Correct method to generate a Curve25519 keypair

Alexander Lyon arlyon at me.com
Sat Jun 23 02:39:47 CEST 2018


Hello

To preface, apologies if I am unconventional or naive; I am a little new to this.

I am having issues with generating a Curve25519 key pair using gcry_pk_genkey. Specifically the private key doesn't match the expected bitmask (as defined here https://cr.yp.to/ecdh.html) nor does the generated public key match the expected value (in this case derived by manually applying the bit mask to the private key and calculating it with a different library).

This is the S-expression used to generate the key:

    (genkey
        (ecc
            (curve "Curve25519")
            (flags djb-tweak comp)
        )
    )

And an example snippet of code to extract the public and private keys, generating the sexp, extracting the mpis and then converting the compressed public key mpi into a point before extracting the X coordinate (the Y and Z were 0x01 and 0x00 respectively).

    gcry_sexp_build( &sexp_params, NULL,
                     "(genkey"
                     "    (ecc"
                     "        (curve \"Curve25519\")"
                     "        (flags djb-tweak comp)"
                     "    )"
                     ")" );

    gcry_sexp_t sexp_curve25519_keypair;
    gcry_pk_genkey( &sexp_curve25519_keypair, sexp_params );

    gcry_ctx_t ctx_curve;
    gcry_mpi_ec_new( &ctx_curve, NULL, "Curve25519" );

    gcry_mpi_t mpi_curve_priv_key;
    gcry_mpi_t mpi_curve_pub_compressed;
    gcry_mpi_point_t point_curve_pub_key = gcry_mpi_point_new( 0 );
    gcry_sexp_extract_param( sexp_curve25519_keypair, NULL, "qd", &mpi_curve_pub_compressed, &mpi_curve_priv_key, NULL );
    gcry_mpi_ec_decode_point( point_curve_pub_key, mpi_curve_pub_compressed, ctx_curve );

At this point, when checking the results in the debugger it is clear that the generated keys are incorrect:

    > gcry_mpi_dump(mpi_curve_priv_key)

    6ef90e0c0201256c301484580a59756529285a80537389235d98cb9d0b036e10

    > gcry_mpi_dump(point_curve_pub_key->x)

    30795e2d73beede300464f26f589e6d171f61a65fc2ab62719941f0b230dc8d9

    > bytes_curve_priv_key[0] == (bytes_curve_priv_key[0] & 248)

    false

    > bytes_curve_priv_key[31] == ((bytes_curve_priv_key[31] & 127) | 64)

    false

What could be causing this? What is the correct way to generate a key pair?

Regards,

Alex


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: Message signed with OpenPGP
URL: <https://lists.gnupg.org/pipermail/gcrypt-devel/attachments/20180623/54348dc5/attachment.sig>


More information about the Gcrypt-devel mailing list