1
2 #include <limits.h>
3 #include <stdint.h>
4 #include <string.h>
5
6 #include "crypto_hash_sha512.h"
7 #include "crypto_sign_ed25519.h"
8 #include "crypto_verify_32.h"
9 #include "sign_ed25519_ref10.h"
10 #include "private/ed25519_ref10.h"
11 #include "utils.h"
12
13 int
_crypto_sign_ed25519_verify_detached(const unsigned char * sig,const unsigned char * m,unsigned long long mlen,const unsigned char * pk,int prehashed)14 _crypto_sign_ed25519_verify_detached(const unsigned char *sig,
15 const unsigned char *m,
16 unsigned long long mlen,
17 const unsigned char *pk,
18 int prehashed)
19 {
20 crypto_hash_sha512_state hs;
21 unsigned char h[64];
22 unsigned char rcheck[32];
23 ge25519_p3 A;
24 ge25519_p2 R;
25
26 #ifndef ED25519_COMPAT
27 if (sc25519_is_canonical(sig + 32) == 0 ||
28 ge25519_has_small_order(sig) != 0) {
29 return -1;
30 }
31 if (ge25519_is_canonical(pk) == 0) {
32 return -1;
33 }
34 #else
35 if (sig[63] & 224) {
36 return -1;
37 }
38 #endif
39 if (ge25519_has_small_order(pk) != 0 ||
40 ge25519_frombytes_negate_vartime(&A, pk) != 0) {
41 return -1;
42 }
43 _crypto_sign_ed25519_ref10_hinit(&hs, prehashed);
44 crypto_hash_sha512_update(&hs, sig, 32);
45 crypto_hash_sha512_update(&hs, pk, 32);
46 crypto_hash_sha512_update(&hs, m, mlen);
47 crypto_hash_sha512_final(&hs, h);
48 sc25519_reduce(h);
49
50 ge25519_double_scalarmult_vartime(&R, h, &A, sig + 32);
51 ge25519_tobytes(rcheck, &R);
52
53 return crypto_verify_32(rcheck, sig) | (-(rcheck == sig)) |
54 sodium_memcmp(sig, rcheck, 32);
55 }
56
57 int
crypto_sign_ed25519_verify_detached(const unsigned char * sig,const unsigned char * m,unsigned long long mlen,const unsigned char * pk)58 crypto_sign_ed25519_verify_detached(const unsigned char *sig,
59 const unsigned char *m,
60 unsigned long long mlen,
61 const unsigned char *pk)
62 {
63 return _crypto_sign_ed25519_verify_detached(sig, m, mlen, pk, 0);
64 }
65
66 int
crypto_sign_ed25519_open(unsigned char * m,unsigned long long * mlen_p,const unsigned char * sm,unsigned long long smlen,const unsigned char * pk)67 crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p,
68 const unsigned char *sm, unsigned long long smlen,
69 const unsigned char *pk)
70 {
71 unsigned long long mlen;
72
73 if (smlen < 64 || smlen - 64 > crypto_sign_ed25519_MESSAGEBYTES_MAX) {
74 goto badsig;
75 }
76 mlen = smlen - 64;
77 if (crypto_sign_ed25519_verify_detached(sm, sm + 64, mlen, pk) != 0) {
78 memset(m, 0, mlen);
79 goto badsig;
80 }
81 if (mlen_p != NULL) {
82 *mlen_p = mlen;
83 }
84 memmove(m, sm + 64, mlen);
85
86 return 0;
87
88 badsig:
89 if (mlen_p != NULL) {
90 *mlen_p = 0;
91 }
92 return -1;
93 }
94