perform cheap checks first
[tinc] / src / ed25519 / key_exchange.c
1 #include "ed25519.h"
2 #include "fe.h"
3
4 void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) {
5         unsigned char e[32];
6         unsigned int i;
7
8         fe x1;
9         fe x2;
10         fe z2;
11         fe x3;
12         fe z3;
13         fe tmp0;
14         fe tmp1;
15
16         int pos;
17         unsigned int swap;
18         unsigned int b;
19
20         /* copy the private key and make sure it's valid */
21         for(i = 0; i < 32; ++i) {
22                 e[i] = private_key[i];
23         }
24
25         e[0] &= 248;
26         e[31] &= 63;
27         e[31] |= 64;
28
29         /* unpack the public key and convert edwards to montgomery */
30         /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
31         fe_frombytes(x1, public_key);
32         fe_1(tmp1);
33         fe_add(tmp0, x1, tmp1);
34         fe_sub(tmp1, tmp1, x1);
35         fe_invert(tmp1, tmp1);
36         fe_mul(x1, tmp0, tmp1);
37
38         fe_1(x2);
39         fe_0(z2);
40         fe_copy(x3, x1);
41         fe_1(z3);
42
43         swap = 0;
44
45         for(pos = 254; pos >= 0; --pos) {
46                 b = e[pos / 8] >> (pos & 7);
47                 b &= 1;
48                 swap ^= b;
49                 fe_cswap(x2, x3, swap);
50                 fe_cswap(z2, z3, swap);
51                 swap = b;
52
53                 /* from montgomery.h */
54                 fe_sub(tmp0, x3, z3);
55                 fe_sub(tmp1, x2, z2);
56                 fe_add(x2, x2, z2);
57                 fe_add(z2, x3, z3);
58                 fe_mul(z3, tmp0, x2);
59                 fe_mul(z2, z2, tmp1);
60                 fe_sq(tmp0, tmp1);
61                 fe_sq(tmp1, x2);
62                 fe_add(x3, z3, z2);
63                 fe_sub(z2, z3, z2);
64                 fe_mul(x2, tmp1, tmp0);
65                 fe_sub(tmp1, tmp1, tmp0);
66                 fe_sq(z2, z2);
67                 fe_mul121666(z3, tmp1);
68                 fe_sq(x3, x3);
69                 fe_add(tmp0, tmp0, z3);
70                 fe_mul(z3, x1, z2);
71                 fe_mul(z2, tmp1, tmp0);
72         }
73
74         fe_cswap(x2, x3, swap);
75         fe_cswap(z2, z3, swap);
76
77         fe_invert(z2, z2);
78         fe_mul(x2, x2, z2);
79         fe_tobytes(shared_secret, x2);
80 }