Skip to content

Enable libsecp256k1 ecdh module, add ECDH function to CKey #14049

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

jonasschnelli
Copy link
Contributor

@jonasschnelli jonasschnelli commented Aug 24, 2018

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.

BOOST_CHECK(key1.ComputeECDHSecret(pubkey2, secret1));
BOOST_CHECK(key2.ComputeECDHSecret(pubkey1, secret2));
BOOST_CHECK(secret1.size() == 32);
BOOST_CHECK(secret1 == secret2);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a test where the pubkey doesn't decode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new pubkeydata[9] = 0xFF; line checks that, right? Maybe add a comment to clarify?

src/key.cpp Outdated
}

secret_out.resize(32);
return secp256k1_ecdh(secp256k1_context_sign, &secret_out[0], &pubkey_internal, &keydata[0]) == 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it better to pass a SECP256K1_CONTEXT_NONE context, given the context is not currently used by these functions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would require creating a dummy context just for this purpose, so I don't think that would be best.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename secp256k1_context_sign to secp256k1_context?

@@ -128,6 +128,9 @@ class CKey
//! Derive BIP32 child key.
bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;

// computes an EC Diffie-Hellman 256bit secret
bool ComputeECDHSecret(const CPubKey& pubkey, CPrivKey& secret_out) const;
Copy link
Contributor

@l2a5b1 l2a5b1 Aug 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense to be a member function (in align with Derive and other member functions of CKey).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"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;
}

jonasschnelli added a commit to jonasschnelli/bitcoin that referenced this pull request Aug 29, 2018
@@ -1432,7 +1432,7 @@ if test x$need_bundled_univalue = xyes; then
AC_CONFIG_SUBDIRS([src/univalue])
fi

ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery --disable-jni"
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery --enable-experimental --enable-module-ecdh --disable-jni"
Copy link
Member

@Sjors Sjors Sep 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this --enable-experimental "permanent"? Perhaps this change should be behind a ./configure --enable-experimental-ecdh, or is overly pedantic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an upstream question. Should be asked at https://github.com/bitcoin-core/secp256k1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

@DrahtBot
Copy link
Contributor

DrahtBot commented May 7, 2019

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.

@DrahtBot DrahtBot reopened this May 7, 2019
@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 9, 2019

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #16573 (build: disable building libsecp256k1 benchmarks by fanquake)

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.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 9, 2019

Needs rebase

@dongcarl
Copy link
Contributor

dongcarl commented Jun 2, 2020

Rebased this PR for you ☺️: master...dongcarl:2020-06-bip151_ecdh-rebased

@fanquake
Copy link
Member

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.

@fanquake fanquake closed this Aug 18, 2021
@bitcoin bitcoin locked and limited conversation to collaborators Oct 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Status: Closed unmerged (Superseded)
Development

Successfully merging this pull request may close these issues.

9 participants