Bitcoin-Core-Development

如何指定比特幣簽名程式碼中使用的 ECDSA 隨機數?

  • December 11, 2021

以下是CECKey::Sign()程式碼(v0.9.3)。

bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) {
   vchSig.clear();
   ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
   if (sig == NULL)
       return false;
   BN_CTX *ctx = BN_CTX_new();
   BN_CTX_start(ctx);
   const EC_GROUP *group = EC_KEY_get0_group(pkey);
   BIGNUM *order = BN_CTX_get(ctx);
   BIGNUM *halforder = BN_CTX_get(ctx);
   EC_GROUP_get_order(group, order, ctx);
   BN_rshift1(halforder, order);
   if (BN_cmp(sig->s, halforder) > 0) {
       // enforce low S values, by negating the value (modulo the order) if above order/2.
       BN_sub(sig->s, order, sig->s);
   }
   BN_CTX_end(ctx);
   BN_CTX_free(ctx);
   unsigned int nSize = ECDSA_size(pkey);
   vchSig.resize(nSize); // Make sure it is big enough
   unsigned char *pos = &vchSig[0];
   nSize = i2d_ECDSA_SIG(sig, &pos);
   ECDSA_SIG_free(sig);
   vchSig.resize(nSize); // Shrink to fit actual size
   return true;
}

如何指定在 中使用哪個隨機數ECDSA_do_sign()?通過隨機數,我指的是k這裡描述的值:http ://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm 。

ECDSA_do_sign() 不允許指定隨機數。您可以使用 ECDSA_do_sign_ex(),它需要 (k*G).x 和 1/k 的額外參數。

比特幣大師最近切換到libsecp256k1庫進行簽名,它總是需要顯式傳遞的nonce,並且不需要預先計算x座標和逆。請參閱比特幣核心中的程式碼進行簽名:https ://github.com/bitcoin/bitcoin/blob/0a1d03ca5265293e6419b0ffb68d277da6b1d9a0/src/key.cpp#L75-L92

免責聲明:我是 libsecp256k1 的作者。

編輯:這個答案現在已經過時了。libsecp256k1 現在使用隨機數函式自動計算隨機數。預設的 nonce 函式是基於 RFC6979 的。不再可能直接指定 nonce,因為這是危險的做法。

引用自:https://bitcoin.stackexchange.com/questions/32928