Bitcoin-Core-Development
如何指定比特幣簽名程式碼中使用的 ECDSA 隨機數?
以下是
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,因為這是危險的做法。