Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
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

 ciphers
 Base64 Encoding and Decoding
 
 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. More...
 

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. More...
 
Point ciphers::elliptic_curve_key_exchange::addition (Point a, Point b, const uint256_t &curve_a_coeff, uint256_t mod)
 Addition of points. More...
 
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 More...
 
static void uint128_t_tests ()
 Function to test the uint128_t header. More...
 
static void uint256_t_tests ()
 Function to test the uint256_t header. More...
 
static void test ()
 Function to test the provided algorithm above. More...
 
int main ()
 Main function. More...
 

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)
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
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 }