#include <string.h> #include "crypto_additions.h" #include "gen_x.h" #include "gen_constants.h" #include "gen_eddsa.h" #include "gen_veddsa.h" #include "gen_crypto_additions.h" #include "zeroize.h" static int convert_25519_pubkey(unsigned char* ed_pubkey_bytes, const unsigned char* x25519_pubkey_bytes) { fe u; fe y; /* Convert the X25519 public key into an Ed25519 public key. y = (u - 1) / (u + 1) NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp */ if (!fe_isreduced(x25519_pubkey_bytes)) return -1; fe_frombytes(u, x25519_pubkey_bytes); fe_montx_to_edy(y, u); fe_tobytes(ed_pubkey_bytes, y); return 0; } static int calculate_25519_keypair(unsigned char* K_bytes, unsigned char* k_scalar, const unsigned char* x25519_privkey_scalar) { unsigned char kneg[SCALARLEN]; ge_p3 ed_pubkey_point; unsigned char sign_bit = 0; if (SCALARLEN != 32) return -1; /* Convert the Curve25519 privkey to an Ed25519 public key */ ge_scalarmult_base(&ed_pubkey_point, x25519_privkey_scalar); ge_p3_tobytes(K_bytes, &ed_pubkey_point); /* Force Edwards sign bit to zero */ sign_bit = (K_bytes[31] & 0x80) >> 7; memcpy(k_scalar, x25519_privkey_scalar, 32); sc_neg(kneg, k_scalar); sc_cmov(k_scalar, kneg, sign_bit); K_bytes[31] &= 0x7F; zeroize(kneg, SCALARLEN); return 0; } int generalized_xeddsa_25519_sign(unsigned char* signature_out, const unsigned char* x25519_privkey_scalar, const unsigned char* msg, const unsigned long msg_len, const unsigned char* random, const unsigned char* customization_label, const unsigned long customization_label_len) { unsigned char K_bytes[POINTLEN]; unsigned char k_scalar[SCALARLEN]; int retval = -1; if (calculate_25519_keypair(K_bytes, k_scalar, x25519_privkey_scalar) != 0) return -1; retval = generalized_eddsa_25519_sign(signature_out, K_bytes, k_scalar, msg, msg_len, random, customization_label, customization_label_len); zeroize(k_scalar, SCALARLEN); return retval; } int generalized_xveddsa_25519_sign( unsigned char* signature_out, const unsigned char* x25519_privkey_scalar, const unsigned char* msg, const unsigned long msg_len, const unsigned char* random, const unsigned char* customization_label, const unsigned long customization_label_len) { unsigned char K_bytes[POINTLEN]; unsigned char k_scalar[SCALARLEN]; int retval = -1; if (calculate_25519_keypair(K_bytes, k_scalar, x25519_privkey_scalar) != 0) return -1; retval = generalized_veddsa_25519_sign(signature_out, K_bytes, k_scalar, msg, msg_len, random, customization_label, customization_label_len); zeroize(k_scalar, SCALARLEN); return retval; } int generalized_xeddsa_25519_verify( const unsigned char* signature, const unsigned char* x25519_pubkey_bytes, const unsigned char* msg, const unsigned long msg_len, const unsigned char* customization_label, const unsigned long customization_label_len) { unsigned char K_bytes[POINTLEN]; if (convert_25519_pubkey(K_bytes, x25519_pubkey_bytes) != 0) return -1; return generalized_eddsa_25519_verify(signature, K_bytes, msg, msg_len, customization_label, customization_label_len); } int generalized_xveddsa_25519_verify( unsigned char* vrf_out, const unsigned char* signature, const unsigned char* x25519_pubkey_bytes, const unsigned char* msg, const unsigned long msg_len, const unsigned char* customization_label, const unsigned long customization_label_len) { unsigned char K_bytes[POINTLEN]; if (convert_25519_pubkey(K_bytes, x25519_pubkey_bytes) != 0) return -1; return generalized_veddsa_25519_verify(vrf_out, signature, K_bytes, msg, msg_len, customization_label, customization_label_len); }