From b5797ec61f94d6c5ad1482e0310194b54f4f0ff9 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 23 Oct 2017 15:36:04 +0200 Subject: [PATCH] Add scalarmult_ed25519_base, correct is_canonical() test, add clamping helper, check that the result of scalarmult_ed25519() is not the point at infinity --- .../ed25519/ref10/scalarmult_ed25519_ref10.c | 61 ++++++++++++++++--- .../sodium/crypto_scalarmult_ed25519.h | 3 + 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c b/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c index e8bde768..d40ee5bc 100644 --- a/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c +++ b/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c @@ -4,30 +4,75 @@ #include "crypto_scalarmult_ed25519.h" #include "private/curve25519_ref10.h" +static int +_crypto_scalarmult_ed25519_is_inf(const unsigned char s[32]) +{ + unsigned char c; + unsigned int i; + + c = s[0] ^ 0x01; + for (i = 1; i < 31; i++) { + c |= s[i]; + } + c |= s[31] & 0x7f; + + return ((((unsigned int) c) - 1U) >> 8) & 1; +} + +static inline void +_crypto_scalarmult_ed25519_clamp(unsigned char k[32]) +{ + k[0] &= 248; + k[31] &= 63; + k[31] |= 64; +} + int crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, const unsigned char *p) { - unsigned char *t = q; - ge_p3 Q; - ge_p3 P; + unsigned char t[32]; + ge_p3 Q; + ge_p3 P; + unsigned int i; - if (ge_is_canonical(p) != 0 || ge_has_small_order(p) != 0 || + if (ge_is_canonical(p) == 0 || ge_has_small_order(p) != 0 || ge_frombytes_negate_vartime(&P, p) != 0 || ge_is_on_main_subgroup(&P) == 0) { return -1; } - memmove(t, n, 32); - t[0] &= 248; - t[31] &= 63; - t[31] |= 64; + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + _crypto_scalarmult_ed25519_clamp(t); ge_scalarmult(&Q, t, &P); ge_p3_tobytes(q, &Q); + if (_crypto_scalarmult_ed25519_is_inf(q) != 0) { + return -1; + } q[31] ^= 0x80; return 0; } +int +crypto_scalarmult_ed25519_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char t[32]; + ge_p3 Q; + unsigned int i; + + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + _crypto_scalarmult_ed25519_clamp(t); + ge_scalarmult_base(&Q, t); + ge_p3_tobytes(q, &Q); + + return 0; +} + size_t crypto_scalarmult_ed25519_bytes(void) { diff --git a/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h b/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h index dfee8d8b..46b8ef69 100644 --- a/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h +++ b/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h @@ -23,6 +23,9 @@ int crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, const unsigned char *p) __attribute__ ((warn_unused_result)); +SODIUM_EXPORT +int crypto_scalarmult_ed25519_base(unsigned char *q, const unsigned char *n); + #ifdef __cplusplus } #endif