Skip to main content

3.2. Generation of 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))

其中 '||' 表示连接。换句话说, 我们计算 HMAC, 密钥为 K, 消息为 V 的值 (当前是一个全 1 的比特序列), 后面跟着值为 0 的八位字节, 然后是编码的私钥 x, 然后是 h1, 后者本身是哈希消息的结果。HMAC 仍然使用相同的哈希函数 H。得到的输出长度为 hlen, 成为 K 的新值。

e. 设置:

V = HMAC_K(V)

f. 设置:

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

请注意, 这与步骤 'd' 中的计算相同, 除了 0x00 已被替换为 0x01。

g. 设置:

V = HMAC_K(V)

h. 应用以下过程, 直到产生适当范围内的 k 值:

  1. 设置 T 为空序列。T 的长度 (以比特为单位) 在此步骤开始时为 0。

  2. 当 T 的长度 (以比特为单位) 小于 qlen 时, 执行以下操作:

    V = HMAC_K(V)
    T = T || V
  3. 使用 bits2int 转换将 T 转换为整数, 然后对 q 取模, 计算:

    k = bits2int(T) mod q

    如果该值对于 k 是合适的 (即, 它在 [1, q-1] 范围内且与为同一密钥生成的任何以前的签名产生的值不同), 则退出循环。

  4. 否则, 计算:

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

    并循环 (尝试生成新的 T, 以及新的 k 值)。

生成的值 k 应在签名生成过程的步骤 3 中使用 (参见第 2.4 节)。

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