TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
elliptic_curve_key_exchange.cpp
Go to the documentation of this file.
1
24
#include <cassert>
25
#include <iostream>
26
27
#include "
uint256_t.hpp
"
28
33
namespace
ciphers
{
40
namespace
elliptic_curve_key_exchange
{
41
46
typedef
struct
Point
{
47
uint256_t
x, y;
48
55
inline
bool
operator==
(
const
Point
&p) {
return
x == p.x && y == p.y; }
56
63
friend
std::ostream &
operator<<
(std::ostream &op,
const
Point
&p) {
64
op << p.x <<
" "
<< p.y;
65
return
op;
66
}
67
}
Point
;
68
78
uint256_t
exp
(
uint256_t
number,
uint256_t
power
,
const
uint256_t
&mod) {
79
if
(!
power
) {
80
return
uint256_t
(1);
81
}
82
uint256_t
ans(1);
83
number = number % mod;
84
while
(
power
) {
85
if
((
power
& 1)) {
86
ans = (ans * number) % mod;
87
}
88
power
>>= 1;
89
if
(
power
) {
90
number = (number * number) % mod;
91
}
92
}
93
return
ans;
94
}
95
110
Point
addition
(
Point
a,
Point
b,
const
uint256_t
&curve_a_coeff,
111
uint256_t
mod) {
112
uint256_t
lambda(0);
113
uint256_t
zero(0);
114
lambda = zero = 0;
115
uint256_t
inf = ~zero;
116
if
(a.x != b.x || a.y != b.y) {
117
// Slope being infinite.
118
if
(b.x == a.x) {
119
return
{inf, inf};
120
}
121
uint256_t
num = (b.y - a.y + mod), den = (b.x - a.x + mod);
122
lambda = (num * (
exp
(den, mod - 2, mod))) % mod;
123
}
else
{
134
if
(!a.y) {
135
return
{inf, inf};
136
}
137
uint256_t
axsq = ((a.x * a.x)) % mod;
138
// Mulitply by 3 adjustment
139
axsq += (axsq << 1);
140
axsq %= mod;
141
// Mulitply by 2 adjustment
142
uint256_t
a_2 = (a.y << 1);
143
lambda =
144
(((axsq + curve_a_coeff) % mod) *
exp
(a_2, mod - 2, mod)) % mod;
145
}
146
Point
c;
147
// new point: x = ((lambda^2) - x1 - x2)
148
// y = (lambda * (x1 - x)) - y1
149
c.x = ((lambda * lambda) % mod + (mod << 1) - a.x - b.x) % mod;
150
c.y = (((lambda * (a.x + mod - c.x)) % mod) + mod - a.y) % mod;
151
return
c;
152
}
153
165
Point
multiply
(
const
Point
&a,
const
uint256_t
&curve_a_coeff,
uint256_t
p,
166
const
uint256_t
&mod) {
167
Point
N = a;
168
N.x %= mod;
169
N.y %= mod;
170
uint256_t
inf{};
171
inf =
~uint256_t
(0);
172
Point
Q = {inf, inf};
173
while
(p) {
174
if
((p & 1)) {
175
if
(Q.x == inf && Q.y == inf) {
176
Q.x = N.x;
177
Q.y = N.y;
178
}
else
{
179
Q =
addition
(Q, N, curve_a_coeff, mod);
180
}
181
}
182
p >>= 1;
183
if
(p) {
184
N =
addition
(N, N, curve_a_coeff, mod);
185
}
186
}
187
return
Q;
188
}
189
}
// namespace elliptic_curve_key_exchange
190
}
// namespace ciphers
191
197
static
void
uint128_t_tests
() {
198
// 1st test: Operations test
199
uint128_t
a(
"122"
), b(
"2312"
);
200
assert(a + b == 2434);
201
assert(b - a == 2190);
202
assert(a * b == 282064);
203
assert(b / a == 18);
204
assert(b % a == 116);
205
assert((a & b) == 8);
206
assert((a | b) == 2426);
207
assert((a ^ b) == 2418);
208
assert((a << 64) ==
uint128_t
(
"2250502776992565297152"
));
209
assert((b >> 7) == 18);
210
211
// 2nd test: Operations test
212
a =
uint128_t
(
"12321421424232142122"
);
213
b =
uint128_t
(
"23123212"
);
214
assert(a + b ==
uint128_t
(
"12321421424255265334"
));
215
assert(a - b ==
uint128_t
(
"12321421424209018910"
));
216
assert(a * b ==
uint128_t
(
"284910839733861759501135864"
));
217
assert(a / b == 532859423865LL);
218
assert(a % b == 3887742);
219
assert((a & b) == 18912520);
220
assert((a | b) ==
uint128_t
(
"12321421424236352814"
));
221
assert((a ^ b) ==
uint128_t
(
"12321421424217440294"
));
222
assert((a << 64) ==
uint128_t
(
"227290107637132170748078080907806769152"
));
223
}
224
230
static
void
uint256_t_tests
() {
231
// 1st test: Operations test
232
uint256_t
a(
"122"
), b(
"2312"
);
233
assert(a + b == 2434);
234
assert(b - a == 2190);
235
assert(a * b == 282064);
236
assert(b / a == 18);
237
assert(b % a == 116);
238
assert((a & b) == 8);
239
assert((a | b) == 2426);
240
assert((a ^ b) == 2418);
241
assert((a << 64) ==
uint256_t
(
"2250502776992565297152"
));
242
assert((b >> 7) == 18);
243
244
// 2nd test: Operations test
245
a =
uint256_t
(
"12321423124513251424232142122"
);
246
b =
uint256_t
(
"23124312431243243215354315132413213212"
);
247
assert(a + b ==
uint256_t
(
"23124312443564666339867566556645355334"
));
248
// Since a < b, the value is greater
249
assert(a - b ==
uint256_t
(
"115792089237316195423570985008687907853246860353"
250
"221642219366742944204948568846"
));
251
assert(a * b ==
uint256_t
(
"284924437928789743312147393953938013677909398222"
252
"169728183872115864"
));
253
assert(b / a ==
uint256_t
(
"1876756621"
));
254
assert(b % a ==
uint256_t
(
"2170491202688962563936723450"
));
255
assert((a & b) ==
uint256_t
(
"3553901085693256462344"
));
256
assert((a | b) ==
uint256_t
(
"23124312443564662785966480863388892990"
));
257
assert((a ^ b) ==
uint256_t
(
"23124312443564659232065395170132430646"
));
258
assert((a << 128) ==
uint256_t
(
"4192763024643754272961909047609369343091683"
259
"376561852756163540549632"
));
260
}
261
267
static
void
test
() {
268
// demonstration of key exchange using curve secp112r1
269
270
// Equation of the form y^2 = (x^3 + ax + b) % P (here p is mod)
271
uint256_t
a(
"4451685225093714772084598273548424"
),
272
b(
"2061118396808653202902996166388514"
),
273
mod(
"4451685225093714772084598273548427"
);
274
275
// Generator value: is pre-defined for the given curve
276
ciphers::elliptic_curve_key_exchange::Point
ptr = {
277
uint256_t
(
"188281465057972534892223778713752"
),
278
uint256_t
(
"3419875491033170827167861896082688"
)};
279
280
// Shared key generation.
281
// For alice
282
std::cout <<
"For alice:\n"
;
283
// Alice's private key (can be generated randomly)
284
uint256_t
alice_private_key(
"164330438812053169644452143505618"
);
285
ciphers::elliptic_curve_key_exchange::Point
alice_public_key =
286
multiply
(ptr, a, alice_private_key, mod);
287
std::cout <<
"\tPrivate key: "
<< alice_private_key <<
"\n"
;
288
std::cout <<
"\tPublic Key: "
<< alice_public_key << std::endl;
289
290
// For Bob
291
std::cout <<
"For Bob:\n"
;
292
// Bob's private key (can be generated randomly)
293
uint256_t
bob_private_key(
"1959473333748537081510525763478373"
);
294
ciphers::elliptic_curve_key_exchange::Point
bob_public_key =
295
multiply
(ptr, a, bob_private_key, mod);
296
std::cout <<
"\tPrivate key: "
<< bob_private_key <<
"\n"
;
297
std::cout <<
"\tPublic Key: "
<< bob_public_key << std::endl;
298
299
// After public key exchange, create a shared key for communication.
300
// create shared key:
301
ciphers::elliptic_curve_key_exchange::Point
alice_shared_key =
multiply
(
302
bob_public_key, a,
303
alice_private_key, mod),
304
bob_shared_key =
multiply
(
305
alice_public_key, a,
306
bob_private_key, mod);
307
308
std::cout <<
"Shared keys:\n"
;
309
std::cout << alice_shared_key << std::endl;
310
std::cout << bob_shared_key << std::endl;
311
312
// Check whether shared keys are equal
313
assert(alice_shared_key == bob_shared_key);
314
}
315
320
int
main
() {
321
uint128_t_tests
();
// running predefined 128-bit unsigned integer tests
322
uint256_t_tests
();
// running predefined 256-bit unsigned integer tests
323
test
();
// running self-test implementations
324
return
0;
325
}
test
void test()
Definition
caesar_cipher.cpp:100
uint128_t
class for 128-bit unsigned integer
Definition
uint128_t.hpp:53
uint256_t
class for 256-bit unsigned integer
Definition
uint256_t.hpp:24
uint256_t_tests
static void uint256_t_tests()
Function to test the uint256_t header.
Definition
elliptic_curve_key_exchange.cpp:230
uint128_t_tests
static void uint128_t_tests()
Function to test the uint128_t header.
Definition
elliptic_curve_key_exchange.cpp:197
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
ciphers::elliptic_curve_key_exchange
namespace elliptic_curve_key_exchange
Definition
elliptic_curve_key_exchange.cpp:40
ciphers::elliptic_curve_key_exchange::multiply
Point multiply(const Point &a, const uint256_t &curve_a_coeff, uint256_t p, const uint256_t &mod)
multiply Point and integer
Definition
elliptic_curve_key_exchange.cpp:165
ciphers::elliptic_curve_key_exchange::exp
uint256_t exp(uint256_t number, uint256_t power, const uint256_t &mod)
This function calculates number raised to exponent power under modulo mod using Modular Exponentiatio...
Definition
elliptic_curve_key_exchange.cpp:78
ciphers::elliptic_curve_key_exchange::addition
Point addition(Point a, Point b, const uint256_t &curve_a_coeff, uint256_t mod)
Addition of points.
Definition
elliptic_curve_key_exchange.cpp:110
ciphers
Algorithms for encryption and decryption.
multiply
int multiply(int x, int res[], int res_size)
Definition
power_for_huge_numbers.cpp:25
power
void power(int x, int n)
Definition
power_for_huge_numbers.cpp:56
Point
Definition
line_segment_intersection.cpp:12
ciphers::elliptic_curve_key_exchange::Point
Definition of struct Point.
Definition
elliptic_curve_key_exchange.cpp:46
ciphers::elliptic_curve_key_exchange::Point::operator==
bool operator==(const Point &p)
x and y co-ordinates
Definition
elliptic_curve_key_exchange.cpp:55
ciphers::elliptic_curve_key_exchange::Point::operator<<
friend std::ostream & operator<<(std::ostream &op, const Point &p)
ostream operator for printing Point
Definition
elliptic_curve_key_exchange.cpp:63
uint256_t.hpp
ciphers
elliptic_curve_key_exchange.cpp
Generated by
1.18.0