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