Home | History | Annotate | Line # | Download | only in ref10
      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 #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
     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