'Compute shared secret for ECDSA<ECP, SHA256> keys with Crypto++

I'm trying to do the following:

  1. Receive x and y coordinates of a EC public key
  2. Generate a random EC public key
  3. Compute the shared secret of the two keys

I'm stuck at the last step, from the Documentation is seems like I have to use ECDH<ECP>::Domain but nowhere is it explained how to convert the keys into the required SecByteBlock objects, how can I do this? Pseudocode follows.

std::string x = ...
std::string y = ...

auto make_curve = []{ return ASN1::secp256r1(); };

// Public key
ECDSA<ECP, SHA256>::PublicKey g_a;
g_a.Initialize(make_curve(),
               ECP::Point {
                   Integer { x.data() },
                   Integer { y.data() }
               });

// Private key
ECDSA<ECP, SHA256>::PrivateKey g_b;
g_b.Initialize(RANDOM_POOL, make_curve());

// Compute shared secret
ECDH<ECP>::Domain agreement { make_curve() };

SecByteBlock shared_secret_buf { agreement.AgreedValueLength() };

agreement.Agree(shared_secret_buf, ???, ???);


Solution 1:[1]

The Wikipedia page shows you show to do this:

So first create a new key pair (you never generate just one private key):

ECDH < ECP >::Domain dhB( CURVE );
SecByteBlock privB(dhB.PrivateKeyLength()), pubB(dhB.PublicKeyLength());
dhB.GenerateKeyPair(rng, privB, pubB);

and then you can perform the key agreement like this:

if(!dhB.Agree(shared_secret_buf, privB, pubA))
    throw runtime_error("Failed to reach shared secret (B)");

OK, so now you are left with one issue: encoding the public point. Fortunately that has been explained in the Wiki as well, here, basically you should just be able to use:

void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed)

Where your pubA buffer is put in &bt (I hope the input for &P is clear, use false for compressed).

Basically this returns a byte 04, then the concatenation of X and Y encoded with the size of the field (big endian).

Note that this just requires an ECP::Point and as the key pair generation also doesn't use ECDSA, that part of the code can be stripped out entirely. That's good, because ECDH is a different algorithm and using ECDSA could make the code less portable, e.g. when using the X25519 curve.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1