1 #include <string.h>
2 #include "crypto_sign.h"
3 #include "crypto_hash_sha512.h"
4 #include "crypto_verify_32.h"
5 #include "ge.h"
6 #include "sc.h"
7 
crypto_sign_open(unsigned char * m,unsigned long long * mlen,const unsigned char * sm,unsigned long long smlen,const unsigned char * pk)8 int crypto_sign_open(
9   unsigned char *m,unsigned long long *mlen,
10   const unsigned char *sm,unsigned long long smlen,
11   const unsigned char *pk
12 )
13 {
14   unsigned char pkcopy[32];
15   unsigned char rcopy[32];
16   unsigned char scopy[32];
17   unsigned char h[64];
18   unsigned char rcheck[32];
19   ge_p3 A;
20   ge_p2 R;
21 
22   if (smlen < 64) goto badsig;
23   if (sm[63] & 224) goto badsig;
24   if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig;
25 
26   memmove(pkcopy,pk,32);
27   memmove(rcopy,sm,32);
28   memmove(scopy,sm + 32,32);
29 
30   memmove(m,sm,smlen);
31   memmove(m + 32,pkcopy,32);
32   crypto_hash_sha512(h,m,smlen);
33   sc_reduce(h);
34 
35   ge_double_scalarmult_vartime(&R,h,&A,scopy);
36   ge_tobytes(rcheck,&R);
37   if (crypto_verify_32(rcheck,rcopy) == 0) {
38     memmove(m,m + 64,smlen - 64);
39     memset(m + smlen - 64,0,64);
40     *mlen = smlen - 64;
41     return 0;
42   }
43 
44 badsig:
45   *mlen = -1;
46   memset(m,0,smlen);
47   return -1;
48 }
49