Include ed25519 and sha512 C language implementation.
[brdnet.git] / ed25519 / key_exchange.c
blobabd75da2c2152b12d312af1d32ee49d5eadbb816
1 #include "ed25519.h"
2 #include "fe.h"
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;
8 fe x1;
9 fe x2;
10 fe z2;
11 fe x3;
12 fe z3;
13 fe tmp0;
14 fe tmp1;
16 int pos;
17 unsigned int swap;
18 unsigned int b;
20 /* copy the private key and make sure it's valid */
21 for (i = 0; i < 32; ++i) {
22 e[i] = private_key[i];
25 e[0] &= 248;
26 e[31] &= 63;
27 e[31] |= 64;
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);
38 fe_1(x2);
39 fe_0(z2);
40 fe_copy(x3, x1);
41 fe_1(z3);
43 swap = 0;
44 for (pos = 254; pos >= 0; --pos) {
45 b = e[pos / 8] >> (pos & 7);
46 b &= 1;
47 swap ^= b;
48 fe_cswap(x2, x3, swap);
49 fe_cswap(z2, z3, swap);
50 swap = b;
52 /* from montgomery.h */
53 fe_sub(tmp0, x3, z3);
54 fe_sub(tmp1, x2, z2);
55 fe_add(x2, x2, z2);
56 fe_add(z2, x3, z3);
57 fe_mul(z3, tmp0, x2);
58 fe_mul(z2, z2, tmp1);
59 fe_sq(tmp0, tmp1);
60 fe_sq(tmp1, x2);
61 fe_add(x3, z3, z2);
62 fe_sub(z2, z3, z2);
63 fe_mul(x2, tmp1, tmp0);
64 fe_sub(tmp1, tmp1, tmp0);
65 fe_sq(z2, z2);
66 fe_mul121666(z3, tmp1);
67 fe_sq(x3, x3);
68 fe_add(tmp0, tmp0, z3);
69 fe_mul(z3, x1, z2);
70 fe_mul(z2, tmp1, tmp0);
73 fe_cswap(x2, x3, swap);
74 fe_cswap(z2, z3, swap);
76 fe_invert(z2, z2);
77 fe_mul(x2, x2, z2);
78 fe_tobytes(shared_secret, x2);