From: Loup Vaillant Date: Tue, 24 Mar 2020 19:40:48 +0000 (+0100) Subject: Added EdDSA to X25519 conversions X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=b3baf279eec11c6507e35b9286333e24f17e6363;p=Monocypher.git Added EdDSA to X25519 conversions --- diff --git a/src/monocypher.c b/src/monocypher.c index 81a4a4f..756be32 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -2235,6 +2235,32 @@ int crypto_check(const u8 signature[64], return crypto_check_final(actx); } +/////////////////////// +/// EdDSA to X25519 /// +/////////////////////// +void crypto_from_eddsa_private(u8 x25519[32], const u8 eddsa[32]) +{ + u8 a[64]; + crypto_blake2b(a, eddsa, 32); + COPY(x25519, a, 32); + WIPE_BUFFER(a); +} + +static const fe fe_one = {1}; + +void crypto_from_eddsa_public(u8 x25519[32], const u8 eddsa[32]) +{ + fe t1, t2; + fe_frombytes(t2, eddsa); + fe_add(t1, fe_one, t2); + fe_sub(t2, fe_one, t2); + fe_invert(t2, t2); + fe_mul(t1, t1, t2); + fe_tobytes(x25519, t1); + WIPE_BUFFER(t1); + WIPE_BUFFER(t2); +} + ///////////////////////////////////////////// /// Dirty ephemeral public key generation /// ///////////////////////////////////////////// @@ -2479,7 +2505,6 @@ void crypto_hidden_to_curve(uint8_t curve[32], const uint8_t hidden[32]) 544946, -16816446, 4011309, -653372, 10741468, }; static const fe A2 = {12721188, 3529, 0, 0, 0, 0, 0, 0, 0, 0}; - static const fe one = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Representatives are encoded in 254 bits. // The two most significant ones are random padding that must be ignored. @@ -2490,7 +2515,7 @@ void crypto_hidden_to_curve(uint8_t curve[32], const uint8_t hidden[32]) fe r, u, t1, t2, t3; fe_frombytes(r, clamped); fe_sq2(t1, r); - fe_add(u, t1, one); + fe_add(u, t1, fe_one); fe_sq (t2, u); fe_mul(t3, A2, t1); fe_sub(t3, t3, t2); @@ -2500,7 +2525,7 @@ void crypto_hidden_to_curve(uint8_t curve[32], const uint8_t hidden[32]) int is_square = invsqrt(t1, t1); fe_sq(u, r); fe_mul(u, u, ufactor); - fe_ccopy(u, one, is_square); + fe_ccopy(u, fe_one, is_square); fe_sq (t1, t1); fe_mul(u, u, A); fe_mul(u, u, t3); diff --git a/src/monocypher.h b/src/monocypher.h index 2269bd6..e014f8d 100644 --- a/src/monocypher.h +++ b/src/monocypher.h @@ -252,6 +252,11 @@ void crypto_check_init_custom_hash(crypto_check_ctx_abstract *ctx, const uint8_t public_key[32], const crypto_sign_vtable *hash); +// EdDSA to X25519 +// --------------- +void crypto_from_eddsa_private(uint8_t x25519[32], const uint8_t eddsa[32]); +void crypto_from_eddsa_public (uint8_t x25519[32], const uint8_t eddsa[32]); + // Elligator 2 // ----------- diff --git a/src/optional/monocypher-ed25519.c b/src/optional/monocypher-ed25519.c index 3b58a12..36d771b 100644 --- a/src/optional/monocypher-ed25519.c +++ b/src/optional/monocypher-ed25519.c @@ -57,8 +57,10 @@ /// Utilities /// ///////////////// #define FOR(i, min, max) for (size_t i = min; i < max; i++) +#define COPY(dst, src, size) FOR(i, 0, size) (dst)[i] = (src)[i] #define ZERO(buf, size) FOR(i, 0, size) (buf)[i] = 0 #define WIPE_CTX(ctx) crypto_wipe(ctx , sizeof(*(ctx))) +#define WIPE_BUFFER(buffer) crypto_wipe(buffer, sizeof(buffer)) #define MIN(a, b) ((a) <= (b) ? (a) : (b)) #define ALIGN(x, block_size) ((~(x) + 1) & ((block_size) - 1)) typedef uint8_t u8; @@ -391,3 +393,11 @@ int crypto_ed25519_check(const u8 signature [64], crypto_ed25519_check_update(actx, message, message_size); return crypto_ed25519_check_final(actx); } + +void crypto_from_ed25519_private(u8 x25519[32], const u8 eddsa[32]) +{ + u8 a[64]; + crypto_sha512(a, eddsa, 32); + COPY(x25519, a, 32); + WIPE_BUFFER(a); +} diff --git a/src/optional/monocypher-ed25519.h b/src/optional/monocypher-ed25519.h index 110d4d0..6f43c50 100644 --- a/src/optional/monocypher-ed25519.h +++ b/src/optional/monocypher-ed25519.h @@ -135,5 +135,8 @@ void crypto_ed25519_check_init(crypto_check_ctx_abstract *ctx, #define crypto_ed25519_check_update crypto_check_update #define crypto_ed25519_check_final crypto_check_final +void crypto_from_ed25519_private(uint8_t x25519[32], const uint8_t eddsa[32]); +#define crypto_from_ed25519_public crypto_from_eddsa_public + #endif // ED25519_H diff --git a/tests/test.c b/tests/test.c index a24ed31..d6a5e32 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1026,6 +1026,36 @@ static int p_x25519_inverse() return status; } +int p_from_eddsa() +{ + int status = 0; + FOR (i, 0, 32) { + RANDOM_INPUT(ed_private, 32); + u8 ed_public[32]; crypto_sign_public_key (ed_public, ed_private); + u8 x_private[32]; crypto_from_eddsa_private(x_private, ed_private); + u8 x_public1[32]; crypto_from_eddsa_public (x_public1, ed_public); + u8 x_public2[32]; crypto_x25519_public_key (x_public2, x_private); + status |= memcmp(x_public1, x_public2, 32); + } + printf("%s: from_eddsa\n", status != 0 ? "FAILED" : "OK"); + return status; +} + +int p_from_ed25519() +{ + int status = 0; + FOR (i, 0, 32) { + RANDOM_INPUT(ed_private, 32); + u8 ed_public[32]; crypto_ed25519_public_key (ed_public, ed_private); + u8 x_private[32]; crypto_from_ed25519_private(x_private, ed_private); + u8 x_public1[32]; crypto_from_ed25519_public (x_public1, ed_public); + u8 x_public2[32]; crypto_x25519_public_key (x_public2, x_private); + status |= memcmp(x_public1, x_public2, 32); + } + printf("%s: from_ed25519\n", status != 0 ? "FAILED" : "OK"); + return status; +} + #define TEST(name, nb_inputs) vector_test(name, #name, nb_inputs, \ nb_##name##_vectors, \ name##_vectors, \ @@ -1096,6 +1126,8 @@ int main(int argc, char *argv[]) status |= p_elligator_key_pair(); status |= p_elligator_key_pair_overlap(); status |= p_x25519_inverse(); - printf("\n%s\n\n", status != 0 ? "SOME TESTS FAILED" : "All tests OK!"); + status |= p_from_eddsa(); + status |= p_from_ed25519(); + printf("\n%s\n\n", status != 0 ? "SOME TESTS FAILED" : "All tests OK!"); return status; }