]> git.codecow.com Git - Monocypher.git/commitdiff
Added EdDSA to X25519 conversions
authorLoup Vaillant <loup@loup-vaillant.fr>
Tue, 24 Mar 2020 19:40:48 +0000 (20:40 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Tue, 24 Mar 2020 19:40:48 +0000 (20:40 +0100)
src/monocypher.c
src/monocypher.h
src/optional/monocypher-ed25519.c
src/optional/monocypher-ed25519.h
tests/test.c

index 81a4a4f9be08b675bafdd0e159f0699989d0a21e..756be320112f45e0e734a55cf103d9442d8e5dc7 100644 (file)
@@ -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);
index 2269bd6e9c67a279f7ce9c9e9441fa5150a259f6..e014f8d94885ab8b45ab5a16f341f587ae983e0d 100644 (file)
@@ -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
 // -----------
 
index 3b58a12b63897edca553e62ca6ffdcf1385e0be8..36d771b1198975c15865762b4906ffe9d60fcdd6 100644 (file)
 /// 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);
+}
index 110d4d07fe9f2074bb594a892f5f28c276c79f36..6f43c506427dbf14bc97fb6839024e6406dcc32c 100644 (file)
@@ -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
index a24ed318ada5f3884644dc7578b296381a431eaa..d6a5e32f2c98d7d2c01aec5647ab87cf4b137b0b 100644 (file)
@@ -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;
 }