From ceb9c566fbbce051e211c3d94bffdd5370079619 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 10 Nov 2015 07:56:58 +0100 Subject: [PATCH] Implement the old edwards25519sha512batch construction on top of ref10 Only for backward compatibility; not compiled in minimal mode. --- src/libsodium/Makefile.am | 1 + src/libsodium/crypto_sign/ed25519/ref10/ge.h | 2 + .../ed25519/ref10/ge_double_scalarmult.c | 42 +++++++ .../crypto_sign/ed25519/ref10/obsolete.c | 111 ++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 src/libsodium/crypto_sign/ed25519/ref10/obsolete.c diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index e9d58dcd..45fc312d 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -240,6 +240,7 @@ libsodium_la_SOURCES += \ crypto_core/salsa208/ref/core_salsa208.c \ crypto_core/salsa208/core_salsa208_api.c \ crypto_core/salsa208/ref/api.h \ + crypto_sign/ed25519/ref10/obsolete.c \ crypto_stream/aes128ctr/portable/afternm_aes128ctr.c \ crypto_stream/aes128ctr/stream_aes128ctr_api.c \ crypto_stream/aes128ctr/portable/api.h \ diff --git a/src/libsodium/crypto_sign/ed25519/ref10/ge.h b/src/libsodium/crypto_sign/ed25519/ref10/ge.h index 55e95f95..7aaff3d8 100644 --- a/src/libsodium/crypto_sign/ed25519/ref10/ge.h +++ b/src/libsodium/crypto_sign/ed25519/ref10/ge.h @@ -70,6 +70,7 @@ typedef struct { #define ge_sub crypto_sign_ed25519_ref10_ge_sub #define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base #define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime +#define ge_scalarmult_vartime crypto_sign_ed25519_ref10_ge_scalarmult_vartime extern void ge_tobytes(unsigned char *,const ge_p2 *); extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); @@ -91,5 +92,6 @@ extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *); extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *); extern void ge_scalarmult_base(ge_p3 *,const unsigned char *); extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *); +extern void ge_scalarmult_vartime(ge_p3 *,const unsigned char *,const ge_p3 *); #endif diff --git a/src/libsodium/crypto_sign/ed25519/ref10/ge_double_scalarmult.c b/src/libsodium/crypto_sign/ed25519/ref10/ge_double_scalarmult.c index f8bf4bf7..d4f132e8 100644 --- a/src/libsodium/crypto_sign/ed25519/ref10/ge_double_scalarmult.c +++ b/src/libsodium/crypto_sign/ed25519/ref10/ge_double_scalarmult.c @@ -94,3 +94,45 @@ void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A ge_p1p1_to_p2(r,&t); } } + +void ge_scalarmult_vartime(ge_p3 *r,const unsigned char *a,const ge_p3 *A) +{ + signed char aslide[256]; + ge_cached Ai[8]; + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + + slide(aslide,a); + + ge_p3_to_cached(&Ai[0],A); + ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); + ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); + ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); + ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); + ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); + ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); + ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); + ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); + + ge_p3_0(r); + + for (i = 255;i >= 0;--i) { + if (aslide[i]) break; + } + + for (;i >= 0;--i) { + ge_p3_dbl(&t,r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u,&t); + ge_add(&t,&u,&Ai[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u,&t); + ge_sub(&t,&u,&Ai[(-aslide[i])/2]); + } + + ge_p1p1_to_p3(r,&t); + } +} diff --git a/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c b/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c new file mode 100644 index 00000000..ecb0716b --- /dev/null +++ b/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c @@ -0,0 +1,111 @@ + +#include + +#include "crypto_hash_sha512.h" +#include "crypto_sign_edwards25519sha512batch.h" +#include "crypto_verify_32.h" +#include "fe.h" +#include "ge.h" +#include "randombytes.h" +#include "sc.h" +#include "utils.h" + +int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, + unsigned char *sk) +{ + ge_p3 A; + + randombytes_buf(sk, 32); + crypto_hash_sha512(sk, sk, 32); + sk[0] &= 248; + sk[31] &= 63; + sk[31] |= 64; + ge_scalarmult_base(&A, sk); + ge_p3_tobytes(pk, &A); + + return 0; +} + +int crypto_sign_edwards25519sha512batch(unsigned char *sm, + unsigned long long *smlen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) +{ + crypto_hash_sha512_state hs; + unsigned char nonce[64]; + unsigned char hram[64]; + unsigned char sig[64]; + ge_p3 A; + ge_p3 R; + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, sk + 32, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, nonce); + ge_scalarmult_base(&A, sk); + ge_p3_tobytes(sig + 32, &A); + sc_reduce(nonce); + ge_scalarmult_base(&R, nonce); + ge_p3_tobytes(sig, &R); + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, sig, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, hram); + sc_reduce(hram); + sc_muladd(sig + 32, hram, nonce, sk); + sodium_memzero(hram, sizeof hram); + memmove(sm + 32, m, (size_t) mlen); + memcpy(sm, sig, 32); + memcpy(sm + 32 + mlen, sig + 32, 32); + *smlen_p = mlen + 64U; + + return 0; +} + +int crypto_sign_edwards25519sha512batch_open(unsigned char *m, + unsigned long long *mlen_p, + const unsigned char *sm, + unsigned long long smlen, + const unsigned char *pk) +{ + unsigned char h[64]; + unsigned char t1[32], t2[32]; + unsigned long long mlen; + ge_cached Ai; + ge_p1p1 csa; + ge_p2 cs; + ge_p3 A; + ge_p3 R; + ge_p3 cs3; + + *mlen_p = 0; + if (smlen < 64 || smlen > SIZE_MAX) { + return -1; + } + mlen = smlen - 64; + if (sm[smlen - 1] & 224) { + return -1; + } + if (ge_frombytes_negate_vartime(&A, pk) != 0 || + ge_frombytes_negate_vartime(&R, sm) != 0) { + return -1; + } + ge_p3_to_cached(&Ai, &A); + crypto_hash_sha512(h, sm, mlen + 32); + sc_reduce(h); + ge_scalarmult_vartime(&cs3, h, &R); + ge_add(&csa, &cs3, &Ai); + ge_p1p1_to_p2(&cs, &csa); + ge_tobytes(t1, &cs); + t1[31] ^= 1 << 7; + ge_scalarmult_base(&R, sm + 32 + mlen); + ge_p3_tobytes(t2, &R); + if (crypto_verify_32(t1, t2) != 0) { + return -1; + } + *mlen_p = mlen; + memmove(m, sm + 64, mlen); + + return 0; +}