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
crypto_sign_edwards25519sha512batch_keypair(unsigned char * pk,unsigned char * sk)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
crypto_sign_edwards25519sha512batch(unsigned char * sm,unsigned long long * smlen_p,const unsigned char * m,unsigned long long mlen,const unsigned char * sk)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
crypto_sign_edwards25519sha512batch_open(unsigned char * m,unsigned long long * mlen_p,const unsigned char * sm,unsigned long long smlen,const unsigned char * pk)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