summaryrefslogtreecommitdiffstats
path: root/3rd_party/ed25519/key_exchange.c
diff options
context:
space:
mode:
Diffstat (limited to '3rd_party/ed25519/key_exchange.c')
-rw-r--r--3rd_party/ed25519/key_exchange.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/3rd_party/ed25519/key_exchange.c b/3rd_party/ed25519/key_exchange.c
new file mode 100644
index 0000000..abd75da
--- /dev/null
+++ b/3rd_party/ed25519/key_exchange.c
@@ -0,0 +1,79 @@
1#include "ed25519.h"
2#include "fe.h"
3
4void 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 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;
51
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);
71 }
72
73 fe_cswap(x2, x3, swap);
74 fe_cswap(z2, z3, swap);
75
76 fe_invert(z2, z2);
77 fe_mul(x2, x2, z2);
78 fe_tobytes(shared_secret, x2);
79}