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 的适当值:
-
将 T 设置为空序列.T 的长度 (以位为单位) 表示为 tlen; 因此, 此时 tlen = 0.
-
当 tlen < qlen 时, 执行以下操作:
V = HMAC_K(V)
T = T || V -
计算:
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 之间, 则过程循环.执行简单的模归约会引入偏差, 这将对签名安全性造成损害.