我目前正在使用libgcrypt,尽管它支持Curve25519原语,但它生成的密钥对却存在问题。也就是说,私钥与预期的位掩码(在此处https://cr.yp.to/ecdh.html中定义的)不匹配,也与手动导出的预期值(在我的情况下,将其插入另一个库中)不匹配。
这是用于生成密钥的S表达式:
(genkey
(ecc
(curve "Curve25519")
(flags djb-tweak comp)
)
)
下面的示例代码。公钥“ q”存储为压缩的mpi,在访问它之前需要先将其转换为一个点(由0x40前缀表示)。
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 );
这时的值如下所示。 Y和Z值分别为0x01
和0x00
。
mpi_curve_priv_key = 6ef90e0c0201256c301484580a59756529285a80537389235d98cb9d0b036e10
point_curve_pub_key->x = 30795e2d73beede300464f26f589e6d171f61a65fc2ab62719941f0b230dc8d9
mpi_curve_priv_key[0] == (mpi_curve_priv_key[0] & 248) = false
mpi_curve_priv_key[31] == ((mpi_curve_priv_key[31] & 127) | 64) = false
私钥无效。夹紧私钥使其有效并手动派生公钥将返回一个完全不同的十六进制:
68f90e0c0201256c301484580a59756529285a80537389235d98cb9d0b036e50
be762d0ff2ed2172a85929eeeadccadd0d19c681d8af8693c88592355c3d46b
这里显然是不正确的。我在做什么错了?