Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
elliptic_curve_key_exchange.cpp File Reference

Implementation of Elliptic Curve Diffie Hellman Key Exchange. More...

#include <cassert>
#include <iostream>
#include "uint256_t.hpp"
Include dependency graph for elliptic_curve_key_exchange.cpp:

Classes

struct  ciphers::elliptic_curve_key_exchange::Point
 Definition of struct Point. More...
 

Namespaces

namespace  ciphers
 Algorithms for encryption and decryption.
 
namespace  ciphers::elliptic_curve_key_exchange
 namespace elliptic_curve_key_exchange
 

Typedefs

typedef struct ciphers::elliptic_curve_key_exchange::Point ciphers::elliptic_curve_key_exchange::Point
 Definition of struct Point.
 

Functions

uint256_t ciphers::elliptic_curve_key_exchange::exp (uint256_t number, uint256_t power, const uint256_t &mod)
 This function calculates number raised to exponent power under modulo mod using Modular Exponentiation.
 
Point ciphers::elliptic_curve_key_exchange::addition (Point a, Point b, const uint256_t &curve_a_coeff, uint256_t mod)
 Addition of points.
 
Point ciphers::elliptic_curve_key_exchange::multiply (const Point &a, const uint256_t &curve_a_coeff, uint256_t p, const uint256_t &mod)
 multiply Point and integer
 
static void uint128_t_tests ()
 Function to test the uint128_t header.
 
static void uint256_t_tests ()
 Function to test the uint256_t header.
 
static void test ()
 Function to test the provided algorithm above.
 
int main ()
 Main function.
 

Detailed Description

Implementation of Elliptic Curve Diffie Hellman Key Exchange.

The ECDH (Elliptic Curve Diffie–Hellman Key Exchange) is anonymous key agreement scheme, which allows two parties, each having an elliptic-curve public–private key pair, to establish a shared secret over an insecure channel. ECDH is very similar to the classical DHKE (Diffie–Hellman Key Exchange) algorithm, but it uses ECC point multiplication instead of modular exponentiations. ECDH is based on the following property of EC points: (a * G) * b = (b * G) * a If we have two secret numbers a and b (two private keys, belonging to Alice and Bob) and an ECC elliptic curve with generator point G, we can exchange over an insecure channel the values (a * G) and (b * G) (the public keys of Alice and Bob) and then we can derive a shared secret: secret = (a * G) * b = (b * G) * a. Pretty simple. The above equation takes the following form: alicePubKey * bobPrivKey = bobPubKey * alicePrivKey = secret

Author
Ashish Daulatabad

Function Documentation

◆ main()

int main ( void )

Main function.

Returns
0 on exit
320 {
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}
static void uint256_t_tests()
Function to test the uint256_t header.
Definition elliptic_curve_key_exchange.cpp:230
static void uint128_t_tests()
Function to test the uint128_t header.
Definition elliptic_curve_key_exchange.cpp:197
static void test()
Function to test the provided algorithm above.
Definition elliptic_curve_key_exchange.cpp:267
Here is the call graph for this function:

◆ test()

static void test ( )
static

Function to test the provided algorithm above.

Returns
void
267 {
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
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");
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");
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:
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}
class for 256-bit unsigned integer
Definition uint256_t.hpp:33
T endl(T... args)
int multiply(int x, int res[], int res_size)
Definition power_for_huge_numbers.cpp:25
Definition of struct Point.
Definition elliptic_curve_key_exchange.cpp:46
Here is the call graph for this function:

◆ uint128_t_tests()

static void uint128_t_tests ( )
static

Function to test the uint128_t header.

Returns
void
197 {
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}
class for 128-bit unsigned integer
Definition uint128_t.hpp:59

◆ uint256_t_tests()

static void uint256_t_tests ( )
static

Function to test the uint256_t header.

Returns
void
230 {
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}