¿Cómo generar la clave pública Ed25519 a partir de una clave privada usando libsodium?

No todas las criptomonedas utilizan la tecnología secp256k1 para la generación de pares de claves y firmas digitales. Algunas otras criptomonedas están utilizando la tecnología Curve25519 (utilizada con frecuencia para admitir intercambios de claves ECDH). La criptografía Ed25519 (destinada a admitir la funcionalidad EdDSA) y la criptografía Curve25519 están estrechamente relacionadas a través de transformaciones y la tendencia es comenzar con claves Ed25519 y transformarlas en pares de claves Curve25519.

He estado usando esta referencia como fuente de ocho ED25519_SECRET_KEYS y ED25519_PUBLIC_KEYS correspondientes para usar como vectores de prueba para aplicar implementaciones del paquete Ed25519.

Obtuve floodyberry /ed25519-donna para que funcionara como se esperaba. Sin embargo, no pude calcular ED25519_CURVE25519_PUBLIC_KEYS de la referencia usando ed25519-donna usando su curved25519_scalarmult_basepoint()función para hacer coincidir. Esto me empujó a probar jedisct1/libsodium . Obtuve resultados de función de libsodium crypto_scalarmult_base()para que coincidan con los de ed25519-donna:-)

Sin embargo, it is unclear how jedisct1/libsodium can be applied to generate public Ed25519 keys only from secret Ed25519 keys that are natively in an ASCII hexadecimal format:-( Parece que jedisct1/libsodium requiere que las claves siempre se generen a partir de su proceso nativo de generación de pares de claves, a diferencia de una clave privada proporcionada externamente.

Usó el sodium_hex2bin() para rellenar una clave privada codificada hexadecimal ASCII de la referencia en la variable de 64 caracteres sin firmar ed25519_skpk:

sodio_hex2bin( ed25519_skpk, 32, ED25519_SECRET_KEYS[ii], 64, NULL, NULL, NULL );

Los resultados de la siguiente función de libsodio fueron los esperados:

crypto_scalarmult_base (curva25519_pk, ed25519_skpk)

Estaba un poco frustrado cuando descubrí que crypto_sign_ed25519_sk_to_pk() estaba codificado para extraer la clave pública de ed25519_skpk que nunca se inicializó.

crypto_sign_ed25519_sk_to_pk( ed25519_pk, ed25519_skpk );

Me decepcionó un poco no ubicar una función de libsodium para calcular la clave ed25519_pk cuando ed25519_skpk se carga con una clave privada que funciona desde una fuente externa. Cualquier ayuda será muy apreciada.

Nit pequeño: la curva Ed25519 se usa para implementar EdDSA, no ECDSA.
Fantástico ojo para los detalles! Reflejó el cambio EdDSA.
FYI: existen numerosos sabores de ed25519. tools.ietf.org/html/rfc8032#section-5 documentos ed25519 , ed25519ph y ed25519ctx . Monero e I2P usan red25519 . Consulte geti2p.net/spec/proposals/146-red25519 para obtener una perspectiva de I2P.

Respuestas (2)

No es posible calcular directamente la clave pública ed25519 a partir de la clave privada. En su lugar, use la clave privada determinista para crear una semilla, luego use la semilla para volver a crear la clave privada con su clave pública correspondiente. El siguiente fragmento de código se supone ed25519_skpkque ya está inicializado:

char           hex_ed_pk[65];                                      
unsigned char  seed[crypto_sign_SEEDBYTES];                       
unsigned char  ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES];        
unsigned char  ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES];

// COMPUTE ED25519 PUBLIC KEY, REQUIRES ESTABLISHING A SEED
(void)crypto_sign_ed25519_sk_to_seed( seed,ed25519_skpk);                
(void)crypto_sign_seed_keypair( ed25519_pk, ed25519_skpk, seed );      
(void)sodium_bin2hex( hex_ed_pk, 65, ed25519_pk, 32 );

En libsodium> 1.0.15, crypto_scalarmult_ed25519_base()puede hacer esto.