Correct method to generate a Curve25519 keypair
Alexander Lyon
arlyon at me.com
Thu Jun 28 17:25:23 CEST 2018
I use use gcry_mpi_dump during debugging so I can check the hex values in a break point. It just prints a hex to stdout (or err not sure).
As for extracting the q value, I use gcry_sexp_extract_param. the whole process looks something like this:
------------------------------------
gcry_mpi_t mpi_Curve_pub = gcry_mpi_new( 0 );
gcry_mpi_t mpi_Curve_priv;
gcry_sexp_build( &sexp_genkey_params, NULL,
"(genkey"
" (ecc"
" (curve \"Curve25519\")"
" (flags djb-tweak comp)"
" )"
")" );
gcry_sexp_t sexp_Curve25519_pair;
gcry_pk_genkey( &sexp_Curve25519_pair, sexp_genkey_params );
// the public key is a point stored compressed (determined by the 0x40 prefix)
// in an mpi and it will need to be decompressed
gcry_mpi_t mpi_Curve_pub_compressed;
gcry_sexp_extract_param( sexp_Curve25519_pair, NULL, "qd",
&mpi_Curve_pub_compressed, &mpi_Curve_priv, NULL );
// to decompress, we decode it into a point
// then extract the X and discard the rest
gcry_mpi_point_t point_Curve_pub = gcry_mpi_point_new( 0 );
gcry_ctx_t ctx_curve;
gcry_mpi_ec_new( &ctx_curve, NULL, "Curve25519" );
gcry_mpi_ec_decode_point( point_Curve_pub, mpi_Curve_pub_compressed, ctx_curve );
// we extract x, y and z but only need x because
// curve only uses the x coordinate. y and z are discarded.
gcry_mpi_t mpi_Curve_pub_y = gcry_mpi_new( 0 );
gcry_mpi_t mpi_Curve_pub_z = gcry_mpi_new( 0 );
gcry_mpi_point_snatch_get( mpi_Curve_pub, mpi_Curve_pub_y, mpi_Curve_pub_z, point_Curve_pub );
gcry_sexp_release( sexp_genkey_params );
gcry_sexp_release( sexp_Curve25519_pair );
gcry_mpi_release( mpi_Curve_pub_y );
gcry_mpi_release( mpi_Curve_pub_z );
gcry_mpi_release( mpi_Curve_pub_compressed );
uint8_t p_bytes_Curve[32];
error = gcry_mpi_print( GCRYMPI_FMT_USG, p_bytes_Curve, 32, NULL, mpi_Curve_pub );
// Curve25519 is little-endian
reverse_buffer( p_bytes_Curve, 32 );
------------------------------------
At that point you'll have the generated private key stored in binary in the p_bytes_Curve buffer.
Hope that helps
Alex
> On 28 Jun 2018, at 16:11, Stef Bon <stefbon at gmail.com> wrote:
>
> Op do 28 jun. 2018 om 15:57 schreef Alexander Lyon <arlyon at me.com>:
>>
>> A little late, but as a follow up to this, I managed to find the solution. The generated keys are valid but Curve25519 is little-endian and printing it to a buffer is big-endian so the hex dumped by gcry_mpi_dump is in reverse. It was as easy as reversing the buffer when appropriate. This allowed me to extract the public key binary.
>
> Ok, that explains the remark in "curve25519-sha256 at libssh.org.txt 4.3
> Shared secret generation ":
> "This conversion follows the network byte order."
>
> Thanks for sharing this. You're helping me with implementing it in my
> application.
> Some questions: the public key is shared with the other side. This is
> for ecc/ed25519 available in the s-exp created by genkey as "q-value".
> How did you extract
> this "q-value"?
>
> You're using gcry_mpi_dump. Does this the right tool for this?
> Comments in the documentation say that
> "Dump the value of a in a format suitable for debugging to Libgcrypt’s
> logging stream."
>
> Stef
>
> _______________________________________________
> Gcrypt-devel mailing list
> Gcrypt-devel at gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
More information about the Gcrypt-devel
mailing list