perform cheap checks first
[tinc] / src / ed25519 / verify.c
1 #include "ed25519.h"
2 #include "sha512.h"
3 #include "ge.h"
4 #include "sc.h"
5
6 static int consttime_equal(const unsigned char *x, const unsigned char *y) {
7         unsigned char r = 0;
8
9         r = x[0] ^ y[0];
10 #define F(i) r |= x[i] ^ y[i]
11         F(1);
12         F(2);
13         F(3);
14         F(4);
15         F(5);
16         F(6);
17         F(7);
18         F(8);
19         F(9);
20         F(10);
21         F(11);
22         F(12);
23         F(13);
24         F(14);
25         F(15);
26         F(16);
27         F(17);
28         F(18);
29         F(19);
30         F(20);
31         F(21);
32         F(22);
33         F(23);
34         F(24);
35         F(25);
36         F(26);
37         F(27);
38         F(28);
39         F(29);
40         F(30);
41         F(31);
42 #undef F
43
44         return !r;
45 }
46
47 int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
48         unsigned char h[64];
49         unsigned char checker[32];
50         sha512_context hash;
51         ge_p3 A;
52         ge_p2 R;
53
54         if(signature[63] & 224) {
55                 return 0;
56         }
57
58         if(ge_frombytes_negate_vartime(&A, public_key) != 0) {
59                 return 0;
60         }
61
62         sha512_init(&hash);
63         sha512_update(&hash, signature, 32);
64         sha512_update(&hash, public_key, 32);
65         sha512_update(&hash, message, message_len);
66         sha512_final(&hash, h);
67
68         sc_reduce(h);
69         ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
70         ge_tobytes(checker, &R);
71
72         if(!consttime_equal(checker, signature)) {
73                 return 0;
74         }
75
76         return 1;
77 }