From db0319fb8e9aa25b972e8d01f781179661daf2ed Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sat, 16 Feb 2019 17:27:15 +0100 Subject: [PATCH] Initial support for ristretto255 --- .gitignore | 2 + AUTHORS | 10 + .../msvc/vs2010/libsodium/libsodium.vcxproj | 4 + .../libsodium/libsodium.vcxproj.filters | 18 ++ .../msvc/vs2012/libsodium/libsodium.vcxproj | 4 + .../libsodium/libsodium.vcxproj.filters | 18 ++ .../msvc/vs2013/libsodium/libsodium.vcxproj | 4 + .../libsodium/libsodium.vcxproj.filters | 18 ++ .../msvc/vs2015/libsodium/libsodium.vcxproj | 4 + .../libsodium/libsodium.vcxproj.filters | 18 ++ .../msvc/vs2017/libsodium/libsodium.vcxproj | 4 + .../libsodium/libsodium.vcxproj.filters | 18 ++ libsodium.vcxproj | 4 + libsodium.vcxproj.filters | 12 + src/libsodium/Makefile.am | 2 + .../crypto_core/ed25519/core_ristretto255.c | 140 ++++++++++ .../crypto_core/ed25519/ref10/ed25519_ref10.c | 250 ++++++++++++++++++ .../ed25519/ref10/fe_25_5/constants.h | 20 ++ .../ed25519/ref10/fe_51/constants.h | 20 ++ .../ref10/scalarmult_ristretto255_ref10.c | 62 +++++ src/libsodium/include/Makefile.am | 2 + src/libsodium/include/sodium.h | 2 + .../include/sodium/crypto_core_ristretto255.h | 90 +++++++ .../include/sodium/crypto_scalarmult.h | 2 +- .../sodium/crypto_scalarmult_curve25519.h | 2 +- .../sodium/crypto_scalarmult_ed25519.h | 2 +- .../sodium/crypto_scalarmult_ristretto255.h | 43 +++ .../include/sodium/private/ed25519_ref10.h | 10 + test/default/Makefile.am | 12 + test/default/core_ristretto255.c | 117 ++++++++ test/default/core_ristretto255.exp | 8 + test/default/scalarmult_ristretto255.c | 47 ++++ test/default/scalarmult_ristretto255.exp | 18 ++ 33 files changed, 984 insertions(+), 3 deletions(-) create mode 100644 src/libsodium/crypto_core/ed25519/core_ristretto255.c create mode 100644 src/libsodium/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c create mode 100644 src/libsodium/include/sodium/crypto_core_ristretto255.h create mode 100644 src/libsodium/include/sodium/crypto_scalarmult_ristretto255.h create mode 100644 test/default/core_ristretto255.c create mode 100644 test/default/core_ristretto255.exp create mode 100644 test/default/scalarmult_ristretto255.c create mode 100644 test/default/scalarmult_ristretto255.exp diff --git a/.gitignore b/.gitignore index ab2bf5ab..de7d69ee 100644 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,7 @@ test/default/box_seed test/default/chacha20 test/default/codecs test/default/core_ed25519 +test/default/core_ristretto255 test/default/core1 test/default/core2 test/default/core3 @@ -129,6 +130,7 @@ test/default/pwhash_scrypt_ll test/default/randombytes test/default/scalarmult test/default/scalarmult_ed25519 +test/default/scalarmult_ristretto255 test/default/scalarmult2 test/default/scalarmult5 test/default/scalarmult6 diff --git a/AUTHORS b/AUTHORS index 39e55f62..f4a4b9d8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,6 +28,13 @@ ed25519 Daniel J. Bernstein poly1305 Daniel J. Bernstein +ristretto Mike Hamburg + Henry de Valence + Jack Grigg + George Tankersley + Filippo Valsorda + Isis Lovecruft + salsa20 Daniel J. Bernstein scrypt Colin Percival @@ -56,6 +63,7 @@ crypto_box/curve25519xchacha20poly1305 Frank Denis crypto_core/ed25519 Daniel J. Bernstein Adam Langley + Frank Denis crypto_core/hchacha20 Frank Denis @@ -93,6 +101,8 @@ crypto_scalarmult/curve25519/sandy2x Tung Chou crypto_scalarmult/ed25519 Frank Denis +crypto_scalarmult/ristretto255 Frank Denis + crypto_secretbox/xsalsa20poly1305 Daniel J. Bernstein crypto_secretbox/xchacha20poly1305 Frank Denis diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/builds/msvc/vs2010/libsodium/libsodium.vcxproj index 62fa4f36..031b18af 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj @@ -126,6 +126,7 @@ + @@ -180,6 +181,7 @@ + @@ -209,6 +211,7 @@ + @@ -216,6 +219,7 @@ + diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters index d4d97413..c2e167b3 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters @@ -171,6 +171,9 @@ crypto_scalarmult + + crypto_scalarmult\ristretto255\ref10 + crypto_scalarmult\ed25519\ref10 @@ -333,6 +336,9 @@ crypto_core\ed25519 + + crypto_core\ed25519 + crypto_core\ed25519\ref10 @@ -416,6 +422,9 @@ include\sodium + + include\sodium + include\sodium @@ -437,6 +446,9 @@ include\sodium + + include\sodium + include\sodium @@ -874,6 +886,12 @@ {834d4827-81e4-3de3-baa1-a216763f11d6} + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/builds/msvc/vs2012/libsodium/libsodium.vcxproj index 482284ec..832f0a41 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj @@ -126,6 +126,7 @@ + @@ -180,6 +181,7 @@ + @@ -209,6 +211,7 @@ + @@ -216,6 +219,7 @@ + diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters index d4d97413..c2e167b3 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters @@ -171,6 +171,9 @@ crypto_scalarmult + + crypto_scalarmult\ristretto255\ref10 + crypto_scalarmult\ed25519\ref10 @@ -333,6 +336,9 @@ crypto_core\ed25519 + + crypto_core\ed25519 + crypto_core\ed25519\ref10 @@ -416,6 +422,9 @@ include\sodium + + include\sodium + include\sodium @@ -437,6 +446,9 @@ include\sodium + + include\sodium + include\sodium @@ -874,6 +886,12 @@ {834d4827-81e4-3de3-baa1-a216763f11d6} + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/builds/msvc/vs2013/libsodium/libsodium.vcxproj index f41661f0..b7bb553f 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj @@ -126,6 +126,7 @@ + @@ -180,6 +181,7 @@ + @@ -209,6 +211,7 @@ + @@ -216,6 +219,7 @@ + diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters index d4d97413..c2e167b3 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters @@ -171,6 +171,9 @@ crypto_scalarmult + + crypto_scalarmult\ristretto255\ref10 + crypto_scalarmult\ed25519\ref10 @@ -333,6 +336,9 @@ crypto_core\ed25519 + + crypto_core\ed25519 + crypto_core\ed25519\ref10 @@ -416,6 +422,9 @@ include\sodium + + include\sodium + include\sodium @@ -437,6 +446,9 @@ include\sodium + + include\sodium + include\sodium @@ -874,6 +886,12 @@ {834d4827-81e4-3de3-baa1-a216763f11d6} + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj b/builds/msvc/vs2015/libsodium/libsodium.vcxproj index 13e08b85..a0b94c18 100644 --- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj @@ -126,6 +126,7 @@ + @@ -180,6 +181,7 @@ + @@ -209,6 +211,7 @@ + @@ -216,6 +219,7 @@ + diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters index d4d97413..c2e167b3 100644 --- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters @@ -171,6 +171,9 @@ crypto_scalarmult + + crypto_scalarmult\ristretto255\ref10 + crypto_scalarmult\ed25519\ref10 @@ -333,6 +336,9 @@ crypto_core\ed25519 + + crypto_core\ed25519 + crypto_core\ed25519\ref10 @@ -416,6 +422,9 @@ include\sodium + + include\sodium + include\sodium @@ -437,6 +446,9 @@ include\sodium + + include\sodium + include\sodium @@ -874,6 +886,12 @@ {834d4827-81e4-3de3-baa1-a216763f11d6} + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj b/builds/msvc/vs2017/libsodium/libsodium.vcxproj index 1c7b4a95..1e62541d 100644 --- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj @@ -126,6 +126,7 @@ + @@ -180,6 +181,7 @@ + @@ -209,6 +211,7 @@ + @@ -216,6 +219,7 @@ + diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters index d4d97413..c2e167b3 100644 --- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters @@ -171,6 +171,9 @@ crypto_scalarmult + + crypto_scalarmult\ristretto255\ref10 + crypto_scalarmult\ed25519\ref10 @@ -333,6 +336,9 @@ crypto_core\ed25519 + + crypto_core\ed25519 + crypto_core\ed25519\ref10 @@ -416,6 +422,9 @@ include\sodium + + include\sodium + include\sodium @@ -437,6 +446,9 @@ include\sodium + + include\sodium + include\sodium @@ -874,6 +886,12 @@ {834d4827-81e4-3de3-baa1-a216763f11d6} + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} diff --git a/libsodium.vcxproj b/libsodium.vcxproj index 0828adaf..f438f89b 100644 --- a/libsodium.vcxproj +++ b/libsodium.vcxproj @@ -364,6 +364,7 @@ + @@ -418,6 +419,7 @@ + @@ -447,6 +449,7 @@ + @@ -454,6 +457,7 @@ + diff --git a/libsodium.vcxproj.filters b/libsodium.vcxproj.filters index ecd8d01c..d31c96e3 100644 --- a/libsodium.vcxproj.filters +++ b/libsodium.vcxproj.filters @@ -162,6 +162,9 @@ Source Files + + Source Files + Source Files @@ -324,6 +327,9 @@ Source Files + + Source Files + Source Files @@ -407,6 +413,9 @@ Header Files + + Header Files + Header Files @@ -428,6 +437,9 @@ Header Files + + Header Files + Header Files diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 7649f27d..ad555055 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -152,6 +152,7 @@ libsodium_la_SOURCES += \ crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c \ crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c \ crypto_core/ed25519/core_ed25519.c \ + crypto_core/ed25519/core_ristretto255.c \ crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c \ crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h \ crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c \ @@ -160,6 +161,7 @@ libsodium_la_SOURCES += \ crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c \ crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c \ crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c \ + crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c \ crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c \ crypto_shorthash/siphash24/shorthash_siphashx24.c \ crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c \ diff --git a/src/libsodium/crypto_core/ed25519/core_ristretto255.c b/src/libsodium/crypto_core/ed25519/core_ristretto255.c new file mode 100644 index 00000000..fbd5372c --- /dev/null +++ b/src/libsodium/crypto_core/ed25519/core_ristretto255.c @@ -0,0 +1,140 @@ + +#include + +#include "crypto_core_ed25519.h" +#include "crypto_core_ristretto255.h" +#include "private/common.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_core_ristretto255_is_valid_point(const unsigned char *p) +{ + ge25519_p3 p_p3; + + if (ristretto255_frombytes(&p_p3, p) != 0) { + return 0; + } + return 1; +} + +int +crypto_core_ristretto255_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ristretto255_frombytes(&p_p3, p) != 0 || + ristretto255_frombytes(&q_p3, q) != 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_add(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ristretto255_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ristretto255_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ristretto255_frombytes(&p_p3, p) != 0 || + ristretto255_frombytes(&q_p3, q) != 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_sub(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ristretto255_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ristretto255_from_uniform(unsigned char *p, const unsigned char *r) +{ + ristretto255_from_uniform(p, r); + + return 0; +} + +void +crypto_core_ristretto255_scalar_random(unsigned char *r) +{ + crypto_core_ed25519_scalar_random(r); +} + +int +crypto_core_ristretto255_scalar_invert(unsigned char *recip, + const unsigned char *s) +{ + return crypto_core_ed25519_scalar_invert(recip, s); +} + +void +crypto_core_ristretto255_scalar_negate(unsigned char *neg, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_negate(neg, s); +} + +void +crypto_core_ristretto255_scalar_complement(unsigned char *comp, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_complement(comp, s); +} + +void +crypto_core_ristretto255_scalar_add(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + crypto_core_ed25519_scalar_add(z, x, y); +} + +void +crypto_core_ristretto255_scalar_sub(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + crypto_core_ed25519_scalar_sub(z, x, y); +} + +void +crypto_core_ristretto255_scalar_reduce(unsigned char *r, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_reduce(r, s); +} + +size_t +crypto_core_ristretto255_bytes(void) +{ + return crypto_core_ristretto255_BYTES; +} + +size_t +crypto_core_ristretto255_nonreducedscalarbytes(void) +{ + return crypto_core_ristretto255_NONREDUCEDSCALARBYTES; +} + +size_t +crypto_core_ristretto255_uniformbytes(void) +{ + return crypto_core_ristretto255_UNIFORMBYTES; +} + +size_t +crypto_core_ristretto255_scalarbytes(void) +{ + return crypto_core_ristretto255_SCALARBYTES; +} diff --git a/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c b/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c index 2aba8fa6..10531d48 100644 --- a/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c +++ b/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c @@ -163,6 +163,22 @@ fe25519_pow22523(fe25519 out, const fe25519 z) fe25519_mul(out, t0, z); } +static inline void +fe25519_cneg(fe25519 h, const fe25519 f, unsigned int b) +{ + fe25519 negf; + + fe25519_neg(negf, f); + fe25519_copy(h, f); + fe25519_cmov(h, negf, b); +} + +static inline void +fe25519_abs(fe25519 h, const fe25519 f) +{ + fe25519_cneg(h, f, fe25519_isnegative(f)); +} + /* r = p + q */ @@ -2583,3 +2599,237 @@ ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]) ge25519_p3_tobytes(s, &p3); } + +/* Ristretto group */ + +static int +ristretto255_sqrt_ratio_m1(fe25519 x, const fe25519 u, const fe25519 v) +{ + fe25519 v3; + fe25519 vxx; + fe25519 m_root_check, p_root_check, f_root_check; + fe25519 negx; + fe25519 x_sqrtm1; + int has_m_root, has_p_root, has_f_root; + + fe25519_sq(v3, v); + fe25519_mul(v3, v3, v); /* v3 = v^3 */ + fe25519_sq(x, v3); + fe25519_mul(x, x, v); + fe25519_mul(x, x, u); /* x = uv^7 */ + + fe25519_pow22523(x, x); /* x = (uv^7)^((q-5)/8) */ + fe25519_mul(x, x, v3); + fe25519_mul(x, x, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe25519_sq(vxx, x); + fe25519_mul(vxx, vxx, v); /* vx^2 */ + fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ + fe25519_add(p_root_check, vxx, u); /* vx^2+u */ + fe25519_mul(f_root_check, u, sqrtm1); /* u*sqrt(-1) */ + fe25519_add(f_root_check, vxx, f_root_check); /* vx^2+u*sqrt(-1) */ + has_m_root = fe25519_iszero(m_root_check); + has_p_root = fe25519_iszero(p_root_check); + has_f_root = fe25519_iszero(f_root_check); + fe25519_mul(x_sqrtm1, x, sqrtm1); /* x*sqrt(-1) */ + + fe25519_cmov(x, x_sqrtm1, has_p_root | has_f_root); + fe25519_abs(x, x); + + return has_m_root | has_p_root; +} + +static int +ristretto255_is_canonical(const unsigned char *s) +{ + unsigned char c; + unsigned char d; + unsigned int i; + + c = (s[31] & 0x7f) ^ 0x7f; + for (i = 30; i > 0; i--) { + c |= s[i] ^ 0xff; + } + c = (((unsigned int) c) - 1U) >> 8; + d = (0xed - 1U - (unsigned int) s[0]) >> 8; + + return 1 - (((c & d) | s[0]) & 1); +} + +int +ristretto255_frombytes(ge25519_p3 *h, const unsigned char *s) +{ + fe25519 inv_sqrt; + fe25519 one; + fe25519 s_; + fe25519 ss; + fe25519 u1, u2; + fe25519 u1u1, u2u2; + fe25519 v; + fe25519 v_u2u2; + int was_square; + + if (ristretto255_is_canonical(s) == 0) { + return -1; + } + fe25519_frombytes(s_, s); + fe25519_sq(ss, s_); /* ss = s^2 */ + + fe25519_1(u1); + fe25519_sub(u1, u1, ss); /* u1 = 1-ss */ + fe25519_sq(u1u1, u1); /* u1u1 = u1^2 */ + + fe25519_1(u2); + fe25519_add(u2, u2, ss); /* u2 = 1+ss */ + fe25519_sq(u2u2, u2); /* u2u2 = u2^2 */ + + fe25519_mul(v, d, u1u1); /* v = d*u1^2 */ + fe25519_neg(v, v); /* v = -d*u1^2 */ + fe25519_sub(v, v, u2u2); /* v = -(d*u1^2)-u2^2 */ + + fe25519_1(one); + fe25519_mul(v_u2u2, v, u2u2); /* v_u2u2 = v*u2^2 */ + + was_square = ristretto255_sqrt_ratio_m1(inv_sqrt, one, v_u2u2); + fe25519_mul(h->X, inv_sqrt, u2); + fe25519_mul(h->Y, inv_sqrt, h->X); + fe25519_mul(h->Y, h->Y, v); + + fe25519_mul(h->X, h->X, s_); + fe25519_add(h->X, h->X, h->X); + fe25519_abs(h->X, h->X); + fe25519_mul(h->Y, u1, h->Y); + fe25519_1(h->Z); + fe25519_mul(h->T, h->X, h->Y); + + return - ((1 - was_square) | + fe25519_isnegative(h->T) | fe25519_iszero(h->Y)); +} + +void +ristretto255_p3_tobytes(unsigned char *s, const ge25519_p3 *h) +{ + fe25519 den1, den2; + fe25519 den_inv; + fe25519 eden; + fe25519 inv_sqrt; + fe25519 ix, iy; + fe25519 one; + fe25519 s_; + fe25519 t_z_inv; + fe25519 u1, u2; + fe25519 u1_u2u2; + fe25519 x_, y_; + fe25519 x_z_inv; + fe25519 z_inv; + fe25519 zmy; + int rotate; + + fe25519_add(u1, h->Z, h->Y); /* u1 = Z+Y */ + fe25519_sub(zmy, h->Z, h->Y); /* zmy = Z-Y */ + fe25519_mul(u1, u1, zmy); /* u1 = (Z+Y)*(Z-Y) */ + fe25519_mul(u2, h->X, h->Y); /* u2 = X*Y */ + + fe25519_1(one); + fe25519_sq(u1_u2u2, u2); /* u1_u2u2 = u2^2 */ + fe25519_mul(u1_u2u2, u1, u1_u2u2); /* u1_u2u2 = u1*u2^2 */ + + (void) ristretto255_sqrt_ratio_m1(inv_sqrt, one, u1_u2u2); + fe25519_mul(den1, inv_sqrt, u1); /* den1 = inv_sqrt*u1 */ + fe25519_mul(den2, inv_sqrt, u2); /* den2 = inv_sqrt*u2 */ + fe25519_mul(z_inv, den1, den2); /* z_inv = den1*den2 */ + fe25519_mul(z_inv, z_inv, h->T); /* z_inv = den1*den2*T */ + + fe25519_mul(ix, h->X, sqrtm1); /* ix = X*sqrt(-1) */ + fe25519_mul(iy, h->Y, sqrtm1); /* iy = Y*sqrt(-1) */ + fe25519_mul(eden, den1, invsqrtamd); /* eden = den1*sqrt(a-d) */ + + fe25519_mul(t_z_inv, h->T, z_inv); /* t_z_inv = T*z_inv */ + rotate = fe25519_isnegative(t_z_inv); + + fe25519_copy(x_, h->X); + fe25519_copy(y_, h->Y); + fe25519_copy(den_inv, den2) ; + + fe25519_cmov(x_, iy, rotate); + fe25519_cmov(y_, ix, rotate); + fe25519_cmov(den_inv, eden, rotate); + + fe25519_mul(x_z_inv, x_, z_inv); + fe25519_cneg(y_, y_, fe25519_isnegative(x_z_inv)); + + fe25519_sub(s_, h->Z, y_); + fe25519_mul(s_, den_inv, s_); + fe25519_abs(s_, s_); + fe25519_tobytes(s, s_); +} + +static void +ristretto255_elligator(ge25519_p3 *p, const fe25519 t) +{ + fe25519 c; + fe25519 n; + fe25519 one; + fe25519 r; + fe25519 rpd; + fe25519 s, s_prime; + fe25519 ss; + fe25519 u, v; + fe25519 w0, w1, w2, w3; + int wasnt_square; + + fe25519_1(one); + fe25519_sq(r, t); /* r = t^2 */ + fe25519_mul(r, sqrtm1, r); /* r = sqrt(-1)*t^2 */ + fe25519_add(u, r, one); /* u = r+1 */ + fe25519_mul(u, u, onemsqd); /* u = (r+1)*(1-d^2) */ + fe25519_1(c); + fe25519_neg(c, c); /* c = -1 */ + fe25519_add(rpd, r, d); /* rpd = r*d */ + fe25519_mul(v, r, d); /* v = r*d */ + fe25519_sub(v, c, v); /* v = c-r*d */ + fe25519_mul(v, v, rpd); /* v = (c-r*d)*(r+d) */ + + wasnt_square = 1 - ristretto255_sqrt_ratio_m1(s, u, v); + fe25519_mul(s_prime, s, t); + fe25519_abs(s_prime, s_prime); + fe25519_neg(s_prime, s_prime); /* s_prime = -|s*t| */ + fe25519_cmov(s, s_prime, wasnt_square); + fe25519_cmov(c, r, wasnt_square); + + fe25519_sub(n, r, one); /* n = r-1 */ + fe25519_mul(n, n, c); /* n = c*(r-1) */ + fe25519_mul(n, n, sqdmone); /* n = c*(r-1)*(d-1)^2 */ + fe25519_sub(n, n, v); /* n = c*(r-1)*(d-1)^2-v */ + + fe25519_add(w0, s, s); /* w0 = 2s */ + fe25519_mul(w0, w0, v); /* w0 = 2s*v */ + fe25519_mul(w1, n, sqrtadm1); /* w1 = n*sqrt(ad-1) */ + fe25519_sq(ss, s); /* ss = s^2 */ + fe25519_sub(w2, one, ss); /* w2 = 1-s^2 */ + fe25519_add(w3, one, ss); /* w3 = 1+s^2 */ + + fe25519_mul(p->X, w0, w3); + fe25519_mul(p->Y, w2, w1); + fe25519_mul(p->Z, w1, w3); + fe25519_mul(p->T, w0, w2); +} + +void +ristretto255_from_uniform(unsigned char s[32], const unsigned char r[64]) +{ + fe25519 r0, r1; + ge25519_cached p1_cached; + ge25519_p1p1 p_p1p1; + ge25519_p3 p0, p1; + ge25519_p3 p; + + fe25519_frombytes(r0, r); + fe25519_frombytes(r1, r + 32); + ristretto255_elligator(&p0, r0); + ristretto255_elligator(&p1, r1); + ge25519_p3_to_cached(&p1_cached, &p1); + ge25519_add(&p_p1p1, &p0, &p1_cached); + ge25519_p1p1_to_p3(&p, &p_p1p1); + ristretto255_p3_tobytes(s, &p); +} diff --git a/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h b/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h index 3dc9156a..dd6da1b8 100644 --- a/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h +++ b/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h @@ -18,3 +18,23 @@ static const fe25519 sqrtm1 = { static const fe25519 curve25519_A = { 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +/* sqrt(ad - 1) with a = -1 (mod p) */ +static const fe25519 sqrtadm1 = { + 24849947, -153582, -23613485, 6347715, -21072328, -667138, -25271143, -15367704, -870347, 14525639 +}; + +/* 1 / sqrt(a - d) */ +static const fe25519 invsqrtamd = { + 6111485, 4156064, -27798727, 12243468, -25904040, 120897, 20826367, -7060776, 6093568, -1986012 +}; + +/* 1 - d ^ 2 */ +static const fe25519 onemsqd = { + 6275446, -16617371, -22938544, -3773710, 11667077, 7397348, -27922721, 1766195, -24433858, 672203 +}; + +/* (d - 1) ^ 2 */ +static const fe25519 sqdmone = { + 15551795, -11097455, -13425098, -10125071, -11896535, 10178284, -26634327, 4729244, -5282110, -10116402 +}; diff --git a/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h b/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h index 53b75c6b..24e5cb5e 100644 --- a/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h +++ b/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h @@ -19,3 +19,23 @@ static const fe25519 sqrtm1 = { static const fe25519 curve25519_A = { 486662, 0, 0, 0, 0 }; + +/* sqrt(ad - 1) with a = -1 (mod p) */ +static const fe25519 sqrtadm1 = { + 2241493124984347, 425987919032274, 2207028919301688, 1220490630685848, 974799131293748 +}; + +/* 1 / sqrt(a - d) */ +static const fe25519 invsqrtamd = { + 278908739862762, 821645201101625, 8113234426968, 1777959178193151, 2118520810568447 +}; + +/* 1 - d ^ 2 */ +static const fe25519 onemsqd = { + 1136626929484150, 1998550399581263, 496427632559748, 118527312129759, 45110755273534 +}; + +/* (d - 1) ^ 2 */ +static const fe25519 sqdmone = { + 1507062230895904, 1572317787530805, 683053064812840, 317374165784489, 1572899562415810 +}; diff --git a/src/libsodium/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c b/src/libsodium/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c new file mode 100644 index 00000000..09d87eba --- /dev/null +++ b/src/libsodium/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c @@ -0,0 +1,62 @@ + +#include + +#include "crypto_scalarmult_ed25519.h" +#include "crypto_scalarmult_ristretto255.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +int +crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + ge25519_p3 Q; + ge25519_p3 P; + unsigned int i; + + if (ristretto255_frombytes(&P, p) != 0) { + return -1; + } + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + t[31] &= 127; + ge25519_scalarmult(&Q, t, &P); + ristretto255_p3_tobytes(q, &Q); + if (sodium_is_zero(q, 32)) { + return -1; + } + return 0; +} + +int +crypto_scalarmult_ristretto255_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char *t = q; + ge25519_p3 Q; + unsigned int i; + + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + t[31] &= 127; + ge25519_scalarmult_base(&Q, t); + ristretto255_p3_tobytes(q, &Q); + if (sodium_is_zero(q, 32)) { + return -1; + } + return 0; +} +size_t +crypto_scalarmult_ristretto255_bytes(void) +{ + return crypto_scalarmult_ristretto255_BYTES; +} + +size_t +crypto_scalarmult_ristretto255_scalarbytes(void) +{ + return crypto_scalarmult_ristretto255_SCALARBYTES; +} diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am index c7d5121f..b78df193 100644 --- a/src/libsodium/include/Makefile.am +++ b/src/libsodium/include/Makefile.am @@ -13,6 +13,7 @@ SODIUM_EXPORT = \ sodium/crypto_box_curve25519xchacha20poly1305.h \ sodium/crypto_box_curve25519xsalsa20poly1305.h \ sodium/crypto_core_ed25519.h \ + sodium/crypto_core_ristretto255.h \ sodium/crypto_core_hchacha20.h \ sodium/crypto_core_hsalsa20.h \ sodium/crypto_core_salsa20.h \ @@ -35,6 +36,7 @@ SODIUM_EXPORT = \ sodium/crypto_scalarmult.h \ sodium/crypto_scalarmult_curve25519.h \ sodium/crypto_scalarmult_ed25519.h \ + sodium/crypto_scalarmult_ristretto255.h \ sodium/crypto_secretbox.h \ sodium/crypto_secretbox_xchacha20poly1305.h \ sodium/crypto_secretbox_xsalsa20poly1305.h \ diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h index ecc8f689..0fc1dbe2 100644 --- a/src/libsodium/include/sodium.h +++ b/src/libsodium/include/sodium.h @@ -56,7 +56,9 @@ #ifndef SODIUM_LIBRARY_MINIMAL # include "sodium/crypto_box_curve25519xchacha20poly1305.h" # include "sodium/crypto_core_ed25519.h" +# include "sodium/crypto_core_ristretto255.h" # include "sodium/crypto_scalarmult_ed25519.h" +# include "sodium/crypto_scalarmult_ristretto255.h" # include "sodium/crypto_secretbox_xchacha20poly1305.h" # include "sodium/crypto_pwhash_scryptsalsa208sha256.h" # include "sodium/crypto_stream_salsa2012.h" diff --git a/src/libsodium/include/sodium/crypto_core_ristretto255.h b/src/libsodium/include/sodium/crypto_core_ristretto255.h new file mode 100644 index 00000000..2f2c1f29 --- /dev/null +++ b/src/libsodium/include/sodium/crypto_core_ristretto255.h @@ -0,0 +1,90 @@ +#ifndef crypto_core_ristretto255_H +#define crypto_core_ristretto255_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_ristretto255_BYTES 32 +SODIUM_EXPORT +size_t crypto_core_ristretto255_bytes(void); + +#define crypto_core_ristretto255_UNIFORMBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ristretto255_uniformbytes(void); + +#define crypto_core_ristretto255_SCALARBYTES 32 +SODIUM_EXPORT +size_t crypto_core_ristretto255_scalarbytes(void); + +#define crypto_core_ristretto255_NONREDUCEDSCALARBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ristretto255_nonreducedscalarbytes(void); + +SODIUM_EXPORT +int crypto_core_ristretto255_is_valid_point(const unsigned char *p) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_from_uniform(unsigned char *p, + const unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_random(unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_scalar_invert(unsigned char *recip, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_negate(unsigned char *neg, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_complement(unsigned char *comp, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_add(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_sub(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +/* + * The interval `s` is sampled from should be at least 317 bits to ensure almost + * uniformity of `r` over `L`. + */ +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_reduce(unsigned char *r, + const unsigned char *s) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libsodium/include/sodium/crypto_scalarmult.h b/src/libsodium/include/sodium/crypto_scalarmult.h index 01a8e3ea..1c685853 100644 --- a/src/libsodium/include/sodium/crypto_scalarmult.h +++ b/src/libsodium/include/sodium/crypto_scalarmult.h @@ -27,7 +27,7 @@ int crypto_scalarmult_base(unsigned char *q, const unsigned char *n) __attribute__ ((nonnull)); /* - * NOTE: Do not use the result of this function directly. + * NOTE: Do not use the result of this function directly for key exchange. * * Hash the result with the public keys in order to compute a shared * secret key: H(q || client_pk || server_pk) diff --git a/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h b/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h index e5605cb2..60e9d0c5 100644 --- a/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h +++ b/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h @@ -18,7 +18,7 @@ SODIUM_EXPORT size_t crypto_scalarmult_curve25519_scalarbytes(void); /* - * NOTE: Do not use the result of this function directly. + * NOTE: Do not use the result of this function directly for key exchange. * * Hash the result with the public keys in order to compute a shared * secret key: H(q || client_pk || server_pk) diff --git a/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h b/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h index 1958643c..2dfa4d70 100644 --- a/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h +++ b/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h @@ -19,7 +19,7 @@ SODIUM_EXPORT size_t crypto_scalarmult_ed25519_scalarbytes(void); /* - * NOTE: Do not use the result of this function directly. + * NOTE: Do not use the result of this function directly for key exchange. * * Hash the result with the public keys in order to compute a shared * secret key: H(q || client_pk || server_pk) diff --git a/src/libsodium/include/sodium/crypto_scalarmult_ristretto255.h b/src/libsodium/include/sodium/crypto_scalarmult_ristretto255.h new file mode 100644 index 00000000..40a45cce --- /dev/null +++ b/src/libsodium/include/sodium/crypto_scalarmult_ristretto255.h @@ -0,0 +1,43 @@ + +#ifndef crypto_scalarmult_ristretto255_H +#define crypto_scalarmult_ristretto255_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_ristretto255_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ristretto255_bytes(void); + +#define crypto_scalarmult_ristretto255_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ristretto255_scalarbytes(void); + +/* + * NOTE: Do not use the result of this function directly for key exchange. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_scalarmult_ristretto255_base(unsigned char *q, + const unsigned char *n) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libsodium/include/sodium/private/ed25519_ref10.h b/src/libsodium/include/sodium/private/ed25519_ref10.h index 5af41591..d309e021 100644 --- a/src/libsodium/include/sodium/private/ed25519_ref10.h +++ b/src/libsodium/include/sodium/private/ed25519_ref10.h @@ -110,6 +110,16 @@ int ge25519_has_small_order(const unsigned char s[32]); void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]); +/* + Ristretto group + */ + +int ristretto255_frombytes(ge25519_p3 *h, const unsigned char *s); + +void ristretto255_p3_tobytes(unsigned char *s, const ge25519_p3 *h); + +void ristretto255_from_uniform(unsigned char s[32], const unsigned char r[64]); + /* The set of scalars is \Z/l where l = 2^252 + 27742317777372353535851937790883648493. diff --git a/test/default/Makefile.am b/test/default/Makefile.am index 5a95c123..9ccefe70 100644 --- a/test/default/Makefile.am +++ b/test/default/Makefile.am @@ -25,6 +25,7 @@ EXTRA_DIST = \ chacha20.exp \ codecs.exp \ core_ed25519.exp \ + core_ristretto255.exp \ core1.exp \ core2.exp \ core3.exp \ @@ -53,6 +54,7 @@ EXTRA_DIST = \ randombytes.exp \ scalarmult.exp \ scalarmult_ed25519.exp \ + scalarmult_ristretto255.exp \ scalarmult2.exp \ scalarmult5.exp \ scalarmult6.exp \ @@ -103,6 +105,7 @@ DISTCLEANFILES = \ chacha20.res \ codecs.res \ core_ed25519.res \ + core_ristretto255.res \ core1.res \ core2.res \ core3.res \ @@ -131,6 +134,7 @@ DISTCLEANFILES = \ randombytes.res \ scalarmult.res \ scalarmult_ed25519.res \ + scalarmult_ristretto255.res \ scalarmult2.res \ scalarmult5.res \ scalarmult6.res \ @@ -316,6 +320,9 @@ codecs_LDADD = $(TESTS_LDADD) core_ed25519_SOURCE = cmptest.h core_ed25519.c core_ed25519_LDADD = $(TESTS_LDADD) +core_ristretto255_SOURCE = cmptest.h core_ristretto255.c +core_ristretto255_LDADD = $(TESTS_LDADD) + core1_SOURCE = cmptest.h core1.c core1_LDADD = $(TESTS_LDADD) @@ -397,6 +404,9 @@ scalarmult_LDADD = $(TESTS_LDADD) scalarmult_ed25519_SOURCE = cmptest.h scalarmult_ed25519.c scalarmult_ed25519_LDADD = $(TESTS_LDADD) +scalarmult_ristretto255_SOURCE = cmptest.h scalarmult_ristretto255.c +scalarmult_ristretto255_LDADD = $(TESTS_LDADD) + scalarmult2_SOURCE = cmptest.h scalarmult2.c scalarmult2_LDADD = $(TESTS_LDADD) @@ -478,9 +488,11 @@ xchacha20_LDADD = $(TESTS_LDADD) if !MINIMAL TESTS_TARGETS += \ core_ed25519 \ + core_ristretto255 \ pwhash_scrypt \ pwhash_scrypt_ll \ scalarmult_ed25519 \ + scalarmult_ristretto255 \ siphashx24 \ xchacha20 endif diff --git a/test/default/core_ristretto255.c b/test/default/core_ristretto255.c new file mode 100644 index 00000000..8af208b3 --- /dev/null +++ b/test/default/core_ristretto255.c @@ -0,0 +1,117 @@ +#define TEST_NAME "core_ristretto255" +#include "cmptest.h" + +static void +tv1(void) +{ + static const char *bad_encodings_hex[] = { + /* Non-canonical field encodings */ + "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + + /* Negative field elements */ + "0100000000000000000000000000000000000000000000000000000000000000", + "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20", + "c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562", + "c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78", + "47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24", + "f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72", + "87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309", + + /* Non-square x^2 */ + "26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371", + "4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f", + "de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b", + "bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042", + "2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08", + "f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22", + "8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731", + "2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b", + + /* Negative xy value */ + "3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e", + "a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220", + "d483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e", + "8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32", + "32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b", + "227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165", + "5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e", + "445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b", + + /* s = -1, which causes y = 0 */ + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f" + }; + unsigned char *s; + size_t i; + + s = (unsigned char *) sodium_malloc(crypto_core_ristretto255_BYTES); + for (i = 0; i < sizeof bad_encodings_hex / sizeof bad_encodings_hex[0]; i++) { + sodium_hex2bin(s, crypto_core_ristretto255_BYTES, bad_encodings_hex[i], + crypto_core_ristretto255_BYTES * 2 + 1, + NULL, NULL, NULL); + if (crypto_core_ristretto255_is_valid_point(s)) { + printf("[%s] was not rejected\n", bad_encodings_hex[i]); + } + } + sodium_free(s); +}; + +static void +tv2(void) +{ + static const char *uniform_hex[] = { + "5d1be09e3d0c82fc538112490e35701979d99e06ca3e2b5b54bffe8b4dc772c1" + "4d98b696a1bbfb5ca32c436cc61c16563790306c79eaca7705668b47dffe5bb6", + + "f116b34b8f17ceb56e8732a60d913dd10cce47a6d53bee9204be8b44f6678b27" + "0102a56902e2488c46120e9276cfe54638286b9e4b3cdb470b542d46c2068d38", + + "8422e1bbdaab52938b81fd602effb6f89110e1e57208ad12d9ad767e2e25510c" + "27140775f9337088b982d83d7fcf0b2fa1edffe51952cbe7365e95c86eaf325c", + + "ac22415129b61427bf464e17baee8db65940c233b98afce8d17c57beeb7876c2" + "150d15af1cb1fb824bbd14955f2b57d08d388aab431a391cfc33d5bafb5dbbaf", + + "165d697a1ef3d5cf3c38565beefcf88c0f282b8e7dbd28544c483432f1cec767" + "5debea8ebb4e5fe7d6f6e5db15f15587ac4d4d4a1de7191e0c1ca6664abcc413", + + "a836e6c9a9ca9f1e8d486273ad56a78c70cf18f0ce10abb1c7172ddd605d7fd2" + "979854f47ae1ccf204a33102095b4200e5befc0465accc263175485f0e17ea5c", + + "2cdc11eaeb95daf01189417cdddbf95952993aa9cb9c640eb5058d09702c7462" + "2c9965a697a3b345ec24ee56335b556e677b30e6f90ac77d781064f866a3c982" + }; + unsigned char *s; + unsigned char *u; + char *hex; + size_t i; + + s = (unsigned char *) sodium_malloc(crypto_core_ristretto255_BYTES); + u = (unsigned char *) sodium_malloc(crypto_core_ristretto255_UNIFORMBYTES); + hex = (char *) sodium_malloc(crypto_core_ristretto255_BYTES * 2 + 1); + for (i = 0; i < sizeof uniform_hex / sizeof uniform_hex[0]; i++) { + sodium_hex2bin(u, crypto_core_ristretto255_UNIFORMBYTES, uniform_hex[i], + crypto_core_ristretto255_UNIFORMBYTES * 2 + 1, + NULL, NULL, NULL); + crypto_core_ristretto255_from_uniform(s, u); + sodium_bin2hex(hex, crypto_core_ristretto255_BYTES * 2 + 1, + s, crypto_core_ristretto255_BYTES); + printf("%s\n", hex); + } + sodium_free(hex); + sodium_free(u); + sodium_free(s); +} + +int +main(void) +{ + tv1(); + tv2(); + printf("OK\n"); + + return 0; +} diff --git a/test/default/core_ristretto255.exp b/test/default/core_ristretto255.exp new file mode 100644 index 00000000..8618d892 --- /dev/null +++ b/test/default/core_ristretto255.exp @@ -0,0 +1,8 @@ +3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46 +f26e5b6f7d362d2d2a94c5d0e7602cb4773c95a2e5c31a64f133189fa76ed61b +006ccd2a9e6867e6a2c5cea83d3302cc9de128dd2a9a57dd8ee7b9d7ffe02826 +f8f0c87cf237953c5890aec3998169005dae3eca1fbb04548c635953c817f92a +ae81e7dedf20a497e10c304a765c1767a42d6e06029758d2d7e8ef7cc4c41179 +e2705652ff9f5e44d3e841bf1c251cf7dddb77d140870d1ab2ed64f1a9ce8628 +80bd07262511cdde4863f8a7434cef696750681cb9510eea557088f76d9e5065 +OK diff --git a/test/default/scalarmult_ristretto255.c b/test/default/scalarmult_ristretto255.c new file mode 100644 index 00000000..96a813cb --- /dev/null +++ b/test/default/scalarmult_ristretto255.c @@ -0,0 +1,47 @@ +#define TEST_NAME "scalarmult_ristretto255" +#include "cmptest.h" + +#define B_HEX "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76" + +int +main(void) +{ + unsigned char *b = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_BYTES); + unsigned char *n = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_SCALARBYTES); + unsigned char *p = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_BYTES); + unsigned char *p2 = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_BYTES); + char *hex = + (char *) sodium_malloc(2 * crypto_scalarmult_ristretto255_BYTES + 1); + int i; + + sodium_hex2bin(b, crypto_scalarmult_ristretto255_BYTES, + B_HEX, sizeof B_HEX - (size_t) 1U, NULL, NULL, NULL); + memset(n, 0, crypto_scalarmult_ristretto255_SCALARBYTES); + for (i = 0; i < 16; i++) { + crypto_scalarmult_ristretto255_base(p, n); + if (crypto_scalarmult_ristretto255(p2, n, b) != 0) { + printf("crypto_scalarmult_ristretto255(%d) != 0\n", i); + } + sodium_bin2hex(hex, 2 * crypto_scalarmult_ristretto255_BYTES + 1, + p, crypto_scalarmult_ristretto255_BYTES); + printf("%s\n", hex); + assert(memcmp(p, p2, crypto_scalarmult_ristretto255_BYTES) == 0); + sodium_increment(n, crypto_scalarmult_ristretto255_SCALARBYTES); + } + sodium_free(hex); + sodium_free(p2); + sodium_free(p); + sodium_free(n); + sodium_free(b); + + assert(crypto_scalarmult_ristretto255_BYTES == crypto_scalarmult_ristretto255_bytes()); + assert(crypto_scalarmult_ristretto255_SCALARBYTES == crypto_scalarmult_ristretto255_scalarbytes()); + + printf("OK\n"); + + return 0; +} diff --git a/test/default/scalarmult_ristretto255.exp b/test/default/scalarmult_ristretto255.exp new file mode 100644 index 00000000..919a7621 --- /dev/null +++ b/test/default/scalarmult_ristretto255.exp @@ -0,0 +1,18 @@ +crypto_scalarmult_ristretto255(0) != 0 +0000000000000000000000000000000000000000000000000000000000000000 +e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76 +6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919 +94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259 +da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57 +e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e +f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403 +44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d +903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c +02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031 +20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f +bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42 +e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460 +aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f +46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e +e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e +OK