Alice wants to send Bob a message. Both have well known public/private EC keys (PA, b, PB, b). Both have well known public keys tied to an identity.

Alice computes a shared secret with Bob (PBa), and uses the x coordinate to tweak her private key, creating a new public/private keypair (PAx, ax).

Alice computes a shared secret between ax and PB, and encrypts a message for Bob this way (using ECIES, for example).

Bob can then easily read the messages, by computing the same shared secret, obtaining x and using bx and PA to decrypt.

The advantage of this is that Bob can know that the message came from Alice, but cannot prove it came from Alice to anyone else, because he can forge it.

Also there's no need for an interactive exchange of temporary keys (which is not always possible). Alice can encrypt and walk away, knowing that Bob can read her message.

Likewise nobody observing the public key that the message was "encrypted for" can know that Alice is encrypting it for Bob, because the public key used is not Bob's well known key. It's a key only known to Alice and Bob.

Is using the "x coordinate" this way OK? Or am I leaking something dangerous?

  • 2
    $\begingroup$ There's no need for an extra ephemeral key. You can just use the shared secret directly as the key for an AEAD scheme with a random nonce or use it to derive some other symmetric encryption key. As long as Alice isn't signing anything and is just doing Diffie-Hellman, Bob can derive the same shared secrets and therefore forge an AEAD encrypted message. $\endgroup$ Jun 13, 2023 at 23:51
  • 1
    $\begingroup$ As an example, Alice can compute the shared secret PB*a , pick a random 16 byte(128 bit) nonce n and compute the message key as k_m=sha256(PB*a || n) or similar. Then encrypt the message with an AEAD scheme and send the ciphertext to Bob along with the nonce. This is just as deniable as plaintext. $\endgroup$ Jun 13, 2023 at 23:56
  • 1
    $\begingroup$ messing around with raw elliptic curve coordinates is usually a bad idea. Notice that while you're deriving a new public key, if you work through the algebra, the net effect is taking the shared secret point and multiplying it by it's own x coordinate to get a new shared secret. This seems to provide no benefit. $\endgroup$ Jun 14, 2023 at 0:00
  • $\begingroup$ unfortunately, i can't use the shared secret "directly", because i'm using it to SIGN things (forced to by a protocol i have to comply with... even thought the signature is 'either alice or bob' ... which is fine in my application). which means i can't use a point. so i just use the X-coord as the new private key. i can hash it first, but that will slow things down a bit, and im not sure its necessary. $\endgroup$ Jun 16, 2023 at 16:40
  • $\begingroup$ You're using an elliptic curve point to sign things? How? That's kind of important. If the DH shared secret is public in some way then there's nothing to be done. DH relies on the fact EC points are not fully homomorphic which is why the computational Diffie-Hellman problem is hard. (can't compute G*ab from (G*a,G*b) ). G*ab is the secret. Once that's out, extra publicly known scalars can't help you, functions that map one secret to another can't help, you need at least one party to generate and send a new key to have new secret information. $\endgroup$ Jun 17, 2023 at 0:47

1 Answer 1


You bumped this so I'll give it an answer.

Your scheme is not secure.

First, you are using the ECDH shared secret P = ab*G as a known, 2 party signature public key. Alice and Bob do a multiparty computation to compute signatures. Whatever it is you are doing, somebody else knows the P = ab*G point.

Your scheme multiplies a factor of x = get_x_coord_as_scalar(P) into the ECDH key exchange. So bob uses xb rather than b as the secret scalar in the ECDH key exchange. You do end up with a new shared secret P'= x*ab*G.

This is equivalent to multiplying the original shared secret by it's own x coordinate. An attacker can do this without knowing either of the two private keys as long as they know the original ECDH secret P which is public since it's being used to verify signatures.

Effectively all you're doing is running the original ECDH shared secret through a function f(P)=get_x_coord_as_scalar(P)*P.


There are still ways to do deniable authenticated encryption with the ECDH secret between the two keys public.

  • For encryption have the message sender pick an ephemeral key at random.
  • For deniable authentication use a 2 member ring signature the recipient can forge.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.