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 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 #ifdef ED25519_COMPAT 27 if (sig[63] & 224) { 28 return -1; 29 } 30 #else 31 if (sc25519_is_canonical(sig + 32) == 0 || 32 ge25519_has_small_order(sig) != 0) { 33 return -1; 34 } 35 if (ge25519_is_canonical(pk) == 0 || 36 ge25519_has_small_order(pk) != 0) { 37 return -1; 38 } 39 #endif 40 if (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 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 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