This add ComputeECDHSecret(const CPubKey& pubkey, CPrivKey& secret_out) to CKey (including a test).
This is a subset of #14032 and a pre-requirement for BIP324.
This add ComputeECDHSecret(const CPubKey& pubkey, CPrivKey& secret_out) to CKey (including a test).
This is a subset of #14032 and a pre-requirement for BIP324.
156 | + CPrivKey secret2; 157 | + BOOST_CHECK(key1.ComputeECDHSecret(pubkey2, secret1)); 158 | + BOOST_CHECK(key2.ComputeECDHSecret(pubkey1, secret2)); 159 | + BOOST_CHECK(secret1.size() == 32); 160 | + BOOST_CHECK(secret1 == secret2); 161 | }
Needs a test where the pubkey doesn't decode.
Added
Thanks but please also add one that could actually have come in over the wire for BIP151, -- the first byte isn't sent there. What I'm hoping we check for is that it correctly rejects points that aren't on the curve here, rather than performing operations on the twist.
The new pubkeydata[9] = 0xFF; line checks that, right? Maybe add a comment to clarify?
292 | + if (!secp256k1_ec_pubkey_parse(secp256k1_context_sign, &pubkey_internal, pubkey.data(), pubkey.size())) { 293 | + return false; 294 | + } 295 | + 296 | + secret_out.resize(32); 297 | + return secp256k1_ecdh(secp256k1_context_sign, &secret_out[0], &pubkey_internal, &keydata[0]) == 1;
Is it better to pass a SECP256K1_CONTEXT_NONE context, given the context is not currently used by these functions?
That would require creating a dummy context just for this purpose, so I don't think that would be best.
Maybe replace the &keydata[0] argument with keydata.data()?
Maybe rename secp256k1_context_sign to secp256k1_context?
Fixed.
127 | @@ -128,6 +128,9 @@ class CKey 128 | //! Derive BIP32 child key. 129 | bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; 130 | 131 | + // computes an EC Diffie-Hellman 256bit secret 132 | + bool ComputeECDHSecret(const CPubKey& pubkey, CPrivKey& secret_out) const;
Extract ComputeECDHSecret from CKey to make it a freestanding function?
bool ComputeECDHSecret(const CKey& key, const CPubKey& pubkey, CPrivKey& secret_out);
Although it is convenient to add new BIP responsibilities directly to CKey, I would recommend against adding more responsibilities to CKey than it already has.
I think this makes sense to be a member function (in align with Derive and other member functions of CKey).
"A function that can be simply, elegantly, and efficiently implemented as a freestanding function (that is, as a nonmember function) should be implemented outside the class." (Stroustrup) is a very commonly used and well documented best practice in C++ development.
See C.4. Make a function a member only if it needs direct access to the representation of a class for more info and guidelines.
bool ComputeECDHSecret(const CKey& key, const CPubKey& pubkey, CPrivKey& secret_out)
{
secp256k1_pubkey pubkey_internal;
if (!secp256k1_ec_pubkey_parse(secp256k1_context_sign, &pubkey_internal, pubkey.data(), pubkey.size())) {
return false;
}
secret_out.resize(32);
return secp256k1_ecdh(secp256k1_context_sign, &secret_out[0], &pubkey_internal, key.begin()) == 1;
}
1431 | @@ -1432,7 +1432,7 @@ if test x$need_bundled_univalue = xyes; then 1432 | AC_CONFIG_SUBDIRS([src/univalue]) 1433 | fi 1434 | 1435 | -ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery --disable-jni" 1436 | +ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery --enable-experimental --enable-module-ecdh --disable-jni"
Is this --enable-experimental "permanent"? Perhaps this change should be behind a ./configure --enable-experimental-ecdh, or is overly pedantic?
It's an upstream question. Should be asked at https://github.com/bitcoin-core/secp256k1
It's declared experimental upstream. Asking upstream to no longer declare it experimental is an upstream question. My point is about using it here; as long as it's experimental upstream, shouldn't it be considered experimental here?
I think it's best to not hide it behind a configuration option on our side. I think we should always compile BIP324 features but only activate them when passing a startup argument (can be switched to default later)
<!--5d09a71f8925f3f132321140b44b946d-->The last travis run for this pull request was 252 days ago and is thus outdated. To trigger a fresh travis build, this pull request should be closed and re-opened.
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--174a7506f384e20aa4161008e828411d-->
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
<!--cf906140f33d8803c4a75a2196329ecb-->Needs rebase
Rebased this PR for you :relaxed:: https://github.com/bitcoin/bitcoin/compare/master...dongcarl:2020-06-bip151_ecdh-rebased
My understanding is that someone else is helping with / taking over these changes, and that the BIP is still being overhauled. I think we'll be better off with new PRs, and clean discussion when work on the implementation resumes in this repo. Changes from here are be cherry-picked if / when needed. So I'm going to close this PR for now.