1

在从零到门罗的书中,我正在阅读Schnorr 签名。2.3.4 节引用了代码库random32_unbiased()中的函数。我的理解是这个函数会生成一个介于和(包括两者)之间的随机整数,其中是一个大整数。src/crypto/crypto.cpp1l-1l

该功能是:

void random32_unbiased(unsigned char *bytes)
  {
    // l = 2^252 + 27742317777372353535851937790883648493.
    // l fits 15 times in 32 bytes (iow, 15 l is the highest multiple of l that fits in 32 bytes)
    static const unsigned char limit[32] = { 0xe3, 0x6a, 0x67, 0x72, 0x8b, 0xce, 0x13, 0x29, 0x8f, 0x30, 0x82, 0x8c, 0x0b, 0xa4, 0x10, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 };
    while(1)
    {
      generate_random_bytes_thread_safe(32, bytes);
      if (!less32(bytes, limit))
        continue;
      sc_reduce32(bytes);
      if (sc_isnonzero(bytes))
        break;
    }
  }

线有什么用途static const unsigned char limit[32]

我的主要问题是上述问题,但总的来说,我并不深入了解函数的工作原理,因此也将不胜感激。

4

1 回答 1

3

门罗币edwards25519用作其用于生成EdDSA(爱德华兹数字签名)的基础椭圆曲线,以在门罗币区块链上创建交易。

edwards25519是一条复合阶曲线,也就是说,它不是secp256k1比特币使用的质数阶曲线。

由于这一事实,在密码学上下文中,我们必须在曲线的素数阶子群中工作,因此出于安全原因,我们的群是素数。

Monero 的那个子组比实际曲线的阶小约 8 倍!因此子组大小为l,即2^252 + 27742317777372353535851937790883648493

2^252 + 27742317777372353535851937790883648493因此, Monero 或其他任何使用的公钥只能是有效的公钥edwards25519

正如 James K. Polk 所指出的,我们希望确保我们留在循环子群内,但不要在关键材料中引入偏差。

有趣的是,我坚持l使用 sagemath,将它乘以 15,它确实适合 256 位。

255.906890595609准确地说,16 次需要256.000000000000000000000000000000000000005位。数学哟。

于 2021-07-23T16:59:57.940 回答