diff options
author | Pieter Wuille <pieter@wuille.net> | 2021-10-28 13:46:52 -0400 |
---|---|---|
committer | Pieter Wuille <pieter@wuille.net> | 2021-11-12 12:04:20 -0500 |
commit | 2478c6730a81dda3c56cb99087caf6abe49c85f5 (patch) | |
tree | 62daa10ff38014d4c9abd855c01de843248d3b79 | |
parent | c9dd5c8d6e59e27af98e99d2844d6ead8eec3162 (diff) | |
download | bitcoin-2478c6730a81dda3c56cb99087caf6abe49c85f5.tar.xz |
Make signing follow BIP340 exactly w.r.t. aux randomness
libsecp256k1's secp256k1_schnorrsig_sign only follows BIP340 exactly
if an aux_rand32 argument is passed. When no randomness is used
(as is the case in the current codebase here), there is no impact
on security between not providing aux_rand32 at all, or providing
an empty one. Yet, for repeatability/testability it is simpler
to always use an all-zero one.
-rw-r--r-- | src/key.cpp | 4 | ||||
-rw-r--r-- | src/key.h | 4 | ||||
-rw-r--r-- | src/script/sign.cpp | 3 | ||||
-rw-r--r-- | src/test/key_tests.cpp | 4 |
4 files changed, 8 insertions, 7 deletions
diff --git a/src/key.cpp b/src/key.cpp index 7688254515..86081b3464 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -275,7 +275,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) return true; } -bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256* aux) const +bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const { assert(sig.size() == 64); secp256k1_keypair keypair; @@ -288,7 +288,7 @@ bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint2 uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root); if (!secp256k1_keypair_xonly_tweak_add(GetVerifyContext(), &keypair, tweak.data())) return false; } - bool ret = secp256k1_schnorrsig_sign(secp256k1_context_sign, sig.data(), hash.data(), &keypair, aux ? (unsigned char*)aux->data() : nullptr); + bool ret = secp256k1_schnorrsig_sign(secp256k1_context_sign, sig.data(), hash.data(), &keypair, (unsigned char*)aux.data()); if (ret) { // Additional verification step to prevent using a potentially corrupted signature secp256k1_xonly_pubkey pubkey_verify; @@ -130,7 +130,7 @@ public: /** * Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this, - * optionally tweaked by *merkle_root. Additional nonce entropy can be provided through + * optionally tweaked by *merkle_root. Additional nonce entropy is provided through * aux. * * merkle_root is used to optionally perform tweaking of the private key, as specified @@ -143,7 +143,7 @@ public: * (this is used for key path spending, with specific * Merkle root of the script tree). */ - bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root = nullptr, const uint256* aux = nullptr) const; + bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const; //! Derive BIP32 child key. bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 4cb2125747..b282f39e6d 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -81,7 +81,8 @@ bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider& uint256 hash; if (!SignatureHashSchnorr(hash, execdata, *txTo, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false; sig.resize(64); - if (!key.SignSchnorr(hash, sig, merkle_root, nullptr)) return false; + // Use uint256{} as aux_rnd for now. + if (!key.SignSchnorr(hash, sig, merkle_root, {})) return false; if (nHashType) sig.push_back(nHashType); return true; } diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index b915982d98..2769dde367 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(bip340_test_vectors) key.Set(sec.begin(), sec.end(), true); XOnlyPubKey pubkey(key.GetPubKey()); BOOST_CHECK(std::equal(pubkey.begin(), pubkey.end(), pub.begin(), pub.end())); - bool ok = key.SignSchnorr(msg256, sig64, nullptr, &aux256); + bool ok = key.SignSchnorr(msg256, sig64, nullptr, aux256); BOOST_CHECK(ok); BOOST_CHECK(std::vector<unsigned char>(sig64, sig64 + 64) == sig); // Verify those signatures for good measure. @@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(bip340_test_vectors) BOOST_CHECK(tweaked); XOnlyPubKey tweaked_key = tweaked->first; aux256 = InsecureRand256(); - bool ok = key.SignSchnorr(msg256, sig64, &merkle_root, &aux256); + bool ok = key.SignSchnorr(msg256, sig64, &merkle_root, aux256); BOOST_CHECK(ok); BOOST_CHECK(tweaked_key.VerifySchnorr(msg256, sig64)); } |