1 2 #include <limits.h> 3 #include <stdint.h> 4 #include <string.h> 5 6 #include "crypto_hash_sha512.h" 7 #include "crypto_sign_edwards25519sha512batch.h" 8 #include "crypto_verify_32.h" 9 #include "private/ed25519_ref10.h" 10 #include "randombytes.h" 11 #include "utils.h" 12 13 int 14 crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, 15 unsigned char *sk) 16 { 17 ge25519_p3 A; 18 19 randombytes_buf(sk, 32); 20 crypto_hash_sha512(sk, sk, 32); 21 sk[0] &= 248; 22 sk[31] &= 127; 23 sk[31] |= 64; 24 ge25519_scalarmult_base(&A, sk); 25 ge25519_p3_tobytes(pk, &A); 26 27 return 0; 28 } 29 30 int 31 crypto_sign_edwards25519sha512batch(unsigned char *sm, 32 unsigned long long *smlen_p, 33 const unsigned char *m, 34 unsigned long long mlen, 35 const unsigned char *sk) 36 { 37 crypto_hash_sha512_state hs; 38 unsigned char nonce[64]; 39 unsigned char hram[64]; 40 unsigned char sig[64]; 41 ge25519_p3 A; 42 ge25519_p3 R; 43 44 crypto_hash_sha512_init(&hs); 45 crypto_hash_sha512_update(&hs, sk + 32, 32); 46 crypto_hash_sha512_update(&hs, m, mlen); 47 crypto_hash_sha512_final(&hs, nonce); 48 ge25519_scalarmult_base(&A, sk); 49 ge25519_p3_tobytes(sig + 32, &A); 50 sc25519_reduce(nonce); 51 ge25519_scalarmult_base(&R, nonce); 52 ge25519_p3_tobytes(sig, &R); 53 crypto_hash_sha512_init(&hs); 54 crypto_hash_sha512_update(&hs, sig, 32); 55 crypto_hash_sha512_update(&hs, m, mlen); 56 crypto_hash_sha512_final(&hs, hram); 57 sc25519_reduce(hram); 58 sc25519_muladd(sig + 32, hram, nonce, sk); 59 sodium_memzero(hram, sizeof hram); 60 memmove(sm + 32, m, (size_t) mlen); 61 memcpy(sm, sig, 32); 62 memcpy(sm + 32 + mlen, sig + 32, 32); 63 *smlen_p = mlen + 64U; 64 65 return 0; 66 } 67 68 int 69 crypto_sign_edwards25519sha512batch_open(unsigned char *m, 70 unsigned long long *mlen_p, 71 const unsigned char *sm, 72 unsigned long long smlen, 73 const unsigned char *pk) 74 { 75 unsigned char h[64]; 76 unsigned char t1[32], t2[32]; 77 unsigned long long mlen; 78 ge25519_cached Ai; 79 ge25519_p1p1 csa; 80 ge25519_p2 cs; 81 ge25519_p3 A; 82 ge25519_p3 R; 83 ge25519_p3 cs3; 84 85 *mlen_p = 0; 86 if (smlen < 64 || smlen - 64 > crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX) { 87 return -1; 88 } 89 mlen = smlen - 64; 90 if (sm[smlen - 1] & 224) { 91 return -1; 92 } 93 if (ge25519_has_small_order(pk) != 0 || 94 ge25519_frombytes_negate_vartime(&A, pk) != 0 || 95 ge25519_has_small_order(sm) != 0 || 96 ge25519_frombytes_negate_vartime(&R, sm) != 0) { 97 return -1; 98 } 99 ge25519_p3_to_cached(&Ai, &A); 100 crypto_hash_sha512(h, sm, mlen + 32); 101 sc25519_reduce(h); 102 ge25519_scalarmult(&cs3, h, &R); 103 ge25519_add(&csa, &cs3, &Ai); 104 ge25519_p1p1_to_p2(&cs, &csa); 105 ge25519_tobytes(t1, &cs); 106 t1[31] ^= 1 << 7; 107 ge25519_scalarmult_base(&R, sm + 32 + mlen); 108 ge25519_p3_tobytes(t2, &R); 109 if (crypto_verify_32(t1, t2) != 0) { 110 return -1; 111 } 112 *mlen_p = mlen; 113 memmove(m, sm + 32, mlen); 114 115 return 0; 116 } 117