ECDH私钥大小

ECDH private key size

我知道 ECDH 中的密钥大小取决于椭圆曲线的大小。

如果它是 256 位曲线 (secp256k1),密钥将是:

Public: 32 bytes * 2 + 1 = 65 (uncompressed)
Private: 32 bytes

384位曲线(secp384r1):

Public: 48 bytes * 2 + 1= 97 (uncompressed)
Private: 48 bytes

但是用521位曲线(secp521r1)情况很奇怪:

Public: 66 bytes * 2 + 1 = 133 (uncompressed)
Private: 66 bytes or 65 bytes.

我使用 node.js 加密模块生成此密钥。

为什么521位曲线的私钥值是可变的?

其他曲线的私钥也是可变的,但在编码为字节时它们不太可能表现出这种差异。

public 密钥被编码为两个 静态大小 整数,前缀为未压缩点指示符 04。大小与密钥大小相同(以字节为单位)。

私钥实际上并没有预先建立的编码。它是 1..N-1 范围内的单个随机值(或向量),其中 N 是曲线的阶数。现在,如果您将此值编码为 可变大小 无符号数,那么 通常 它将与密钥的大小相同(以字节为单位)。然而,它可能偶然小一个字节,或两个,或三个或更多。当然,它小很多的可能性很小。

现在 521 位密钥有点奇怪,第一个最重要的字节不是以设置为 1 的位开始的;它只有 least 有效位设置为 1。这意味着私有值的最高有效字节(通常称为 s)更有可能是字节更短。

当然,确切的机会取决于订单的全部价值:

01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
     FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFA
     51868783 BF2F966B 7FCC0148 F709A5D0
     3BB5C9B8 899C47AE BB6FB71E 91386409

但您可能猜到它非常接近二分之一,因为之后有许多位设置为 1。丢失两个字节的机会当然是 512 中的 1,三个字节的机会是 131072 中的 1(等等)。


请注意,ECDSA 签名大小也可能会波动。 X9.42 签名方案使用两个 DER 编码的 signed 整数。如果最高有效字节的最高有效位设置为 1,则它们已签名的事实可能会引入一个全部设置为零的字节,否则该值将被解释为负数。它由两个数字 r 和 s 组成,并且 DER 编码的大小也取决于编码整数的大小,这一事实使得整个编码的大小很难预测。

ECDSA 签名的另一种不太常见的(平面)编码使用与 public 密钥相同的静态大小的整数,在这种情况下,它只是 N 阶字节大小的两倍。


ECDH 没有这个问题。通常,共享秘密是 ECDH 计算结果点的静态编码 X 坐标,或者至少是使用密钥派生函数 (KDF) 从中派生的值。