随机数发生器设计(四)

概述

本示例DRNG设计参考了GM/T 0105 ,基于SM3算法实现,内部功能接口包括初始化函数、重播种函数、输出函数和已知答案自测试函数,同时还具备DRNG内部状态和错误状态两种内部工作状态。整体框图如下图所示。
DRNG结构

1 内部状态

内部状态包括{V, C, reseed_counter, last_reseed_time, reseed_counter_interval, reseed_time_interval },定义如下:
——比特串V,长度为440比特,每次随机数生成时会进行更新;
——比特串C,长度为440,每次重播种时会进行更新;
——reseed_counter, 在初始化或重播种之后,请求随机数的次数,每次执行随机数生成操作时会加1;
——last_reseed_time,上次重播种的时间值,Unix 时间戳,单位为秒;
——reseed_counter_interval,重播种计数器阈值,该值为常量值1024;
——reseed_time_interval,重播种时间阈值,单位为秒,该值为常量值60s。

2 初始化函数

初始化函数中利用熵源数据对初始状态进行赋值,包含变量初始化和初始化种子函数:
SM3_RNG_Instantiate(nonce)
输入:
——entropy_input:从熵池获取熵压缩函数处理后的结果,长度为440比特。
——nonce: 系统启动时间、当前时间戳、递增计数器信息和固定的随机比特串。
输出:
——初始化内部状态,即V, C, reseed_counter, last_reseed_time, reseed_counter_interval, reseed_time_interval的初始值。
Nonce包括系统启动时间、当前时间戳、递增计数器信息和固定的随机比特串。如下表所示。

熵源说明长度(字节)
CPU信息系统时间(精确到微妙)4
时间信息UTC时间信息(精确到纳秒)4
递增计数器每次调用增14
固定随机值产生自真随机数发生器的随机数128

初始化流程如下:
a) 获取440比特的熵输入entropy_input;
b) 生成种子seed = SM3_df(entropy_input || nonce, seedlen)。Seedlen为440比特;
c) 初始化内部状态变量,包括V、C、reseed_counter。其中V = seed,C = SM3_df (0x00||V, seedlen),reseed_counter = 1;
d) 返回内部状态变量。

#generate nonce
def RNG_Gen_Nonce():
    global nonce_counter
    boottime = (int(psutil.boot_time()) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    timestamp = (int(time_ns()) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    counterbytes = nonce_counter.to_bytes(4, byteorder = 'big', signed=False)
    fixrandom = bytes.fromhex("331051e42be3c2139b4077728785ff2553d1d7ffc7c98377875581837ee6a99501bd28a12c491ea656e5666286fdabc56bb05d811596e9667b165367c7d2e4c8")
    nonce_counter += 1
    return boottime + timestamp + counterbytes + fixrandom
def SM3_RNG_Instantiate(nonce):
    global min_length
    global max_length
    # min_entropy = min_length

    while True:
        (status, entropy_input) = Get_entropy (256, min_length, max_length)
        if status == -2:#need time to generate entropy
            continue
        if status != 0:
            print('entropy source error! please check system source.')
            return -1
        break
    seed = SM3_df(entropy_input + nonce, seedlen)
    reseed_counter = 1
    return Working_state(seed, SM3_df ((bytes([0x00])+ seed), seedlen), reseed_counter)
def Get_entropy (min_entropy, min_length, max_length):
    global drngentropy
    global drngentropylock
    #compress functiong output is about 340*8bits
    if min_entropy > 340*8:#min entropy is too big
        return (-1, bytes()) 
    drngentropylock.acquire()
    #drngentropy is 440 bits fixed, min_length is not expected bigger than 440
    if min_length > (len(drngentropy)*8):#need time to generate entropy
        drngentropylock.release()
        return (-2, bytes()) 
    #retdrngentropy is the var to return
    retdrngentropy = drngentropy
    #clear drngentropy
    drngentropy = bytes()
    drngentropylock.release()
    # print('main thread get entropy OK----')
    return (0,retdrngentropy)
    

3 SM3派生函数

SM3_df在软件随机数发生器的初始化和重播种阶段使用,对输入字符串进行杂凑运算,并返回请求的随机比特串。定义如下:
函数定义: SM3_df(input_string, no_of_bits_to_return)
输入:
——input_ string:输入字符串
——number_of_bits_to_return:SM3_df函数返回的比特长度
输出:
requested_bits:SM3_df函数返回的结果。
SM3_df函数作为扩展函数,实现流程如下。
1) 根据输入的返回数据长度(实际为440比特)和输出数据长度256比特计算循环次数。计算循环次数时使用向上取整方式。
2) 对计数器赋初值1,对临时数据赋初值空。
3) 计算SM3(计数器值||返回数据长度||输入熵源数据)。
4) 临时数据更新为临时数据||SM3结果。
5) 计数器增1。
6) 判断循环是否结果,若结束则跳转至第7步,否则跳转至第3步。
7) 取临时数据左侧指定长度数据,返回。

def sm3Hash(hashbytes:bytes):
    temp = sm3_hash([i for i in hashbytes])
    return bytes.fromhex(temp)

def SM3_df(input_string, no_of_bits_to_return):
    temp = bytes([])
    len = math.ceil(no_of_bits_to_return/outlen)
    counter = 0x01
    for i in range(len):
        temp = temp + sm3Hash(bytes([counter]) + no_of_bits_to_return.to_bytes(4, 'big') + input_string)
        counter = counter + 1
    return temp[0:int(no_of_bits_to_return/8)]

4 其他部分

随机数发生器中的重播种函数函数、输出函数、自测试函数放在下篇文章介绍。

如果商用密码产品认证中遇到问题,欢迎加微信symmrz沟通。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值