跳到主要内容

3.2. Generation of k (k 的生成)

3.2. Generation of k (k 的生成)

给定输入消息 m, 应用以下过程:

a. 通过哈希函数 H 处理 m, 产生:

h1 = H(m)

(h1 是长度为 hlen 的位序列).

b. 设置:

V = 0x01 0x01 0x01 ... 0x01

使得 V 的长度 (以位为单位) 等于 8*ceil(hlen/8).例如, 在基于字节的系统上, 如果 H 是 SHA-256, 则 V 被设置为 32 个值为 1 的字节序列.请注意, 在此步骤和所有后续步骤中, 我们使用与步骤 'a' 中用于处理输入消息的相同 H 函数; 此选择将在第 3.6 节中更详细地讨论.

c. 设置:

K = 0x00 0x00 0x00 ... 0x00

使得 K 的长度 (以位为单位) 等于 8*ceil(hlen/8).

d. 设置:

K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))

其中 '||' 表示连接.换句话说, 我们使用密钥 K 计算 HMAC, 对以下内容按顺序进行连接: V 的当前值,一个值为 0 的八位序列,(EC)DSA 私钥 x 的编码, 以及哈希消息 (可能由 bits2octets 转换截断和扩展).HMAC 结果是 K 的新值.请注意, 私钥 x 在 [1, q-1] 范围内, 因此是 int2octets 的适当输入, 产生 rlen 位的输出, 即整数个字节 (rlen 是 8 的倍数).

e. 设置:

V = HMAC_K(V)

f. 设置:

K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))

请注意, 这次 "内部字节" 是 0x01.

g. 设置:

V = HMAC_K(V)

h. 应用以下算法, 直到找到 k 的适当值:

  1. 将 T 设置为空序列.T 的长度 (以位为单位) 表示为 tlen; 因此, 此时 tlen = 0.

  2. 当 tlen < qlen 时, 执行以下操作:

    V = HMAC_K(V)
    T = T || V
  3. 计算:

    k = bits2int(T)

    如果 k 的值在 [1,q-1] 范围内, 并且适合 DSA 或 ECDSA (即, 它导致的 r 值不为 0; 参见第 3.4 节), 则 k 的生成完成.获得的 k 值用于 DSA 或 ECDSA.否则, 计算:

    K = HMAC_K(V || 0x00)
    V = HMAC_K(V)

    并循环 (尝试生成新的 T, 依此类推).

请注意, 当从 T 生成 k 时, bits2int 的结果与 q 进行比较, 而不是对 q 取模.如果该值不在 1 和 q-1 之间, 则过程循环.执行简单的模归约会引入偏差, 这将对签名安全性造成损害.