1#include "ed25519.h"
2#include "sha512.h"
3#include "ge.h"
4#include "sc.h"
5
6static 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
47int 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(h: &A, s: public_key) != 0) {
59 return 0;
60 }
61
62 sha512_init(md: &hash);
63 sha512_update(md: &hash, in: signature, inlen: 32);
64 sha512_update(md: &hash, in: public_key, inlen: 32);
65 sha512_update(md: &hash, in: message, inlen: message_len);
66 sha512_final(md: &hash, out: h);
67
68 sc_reduce(s: h);
69 ge_double_scalarmult_vartime(r: &R, a: h, A: &A, b: signature + 32);
70 ge_tobytes(s: checker, h: &R);
71
72 if (!consttime_equal(x: checker, y: signature)) {
73 return 0;
74 }
75
76 return 1;
77}
78