# Algorithms_in_C++: ciphers/elliptic_curve_key_exchange.cpp File Reference

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. 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

{
uint128_t_tests(); // running predefined 128-bit unsigned integer tests
uint256_t_tests(); // running predefined 256-bit unsigned integer tests
test(); // running self-test implementations
return 0;
}
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
test
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

{
// demonstration of key exchange using curve secp112r1
// Equation of the form y^2 = (x^3 + ax + b) % P (here p is mod)
uint256_t a("4451685225093714772084598273548424"),
b("2061118396808653202902996166388514"),
mod("4451685225093714772084598273548427");
// Generator value: is pre-defined for the given curve
ciphers::elliptic_curve_key_exchange::Point ptr = {
uint256_t("188281465057972534892223778713752"),
uint256_t("3419875491033170827167861896082688")};
// Shared key generation.
// For alice
std::cout << "For alice:\n";
// Alice's private key (can be generated randomly)
uint256_t alice_private_key("164330438812053169644452143505618");
ciphers::elliptic_curve_key_exchange::Point alice_public_key =
multiply(ptr, a, alice_private_key, mod);
std::cout << "\tPrivate key: " << alice_private_key << "\n";
std::cout << "\tPublic Key: " << alice_public_key << std::endl;
// For Bob
std::cout << "For Bob:\n";
// Bob's private key (can be generated randomly)
uint256_t bob_private_key("1959473333748537081510525763478373");
ciphers::elliptic_curve_key_exchange::Point bob_public_key =
multiply(ptr, a, bob_private_key, mod);
std::cout << "\tPrivate key: " << bob_private_key << "\n";
std::cout << "\tPublic Key: " << bob_public_key << std::endl;
// After public key exchange, create a shared key for communication.
// create shared key:
ciphers::elliptic_curve_key_exchange::Point alice_shared_key = multiply(
bob_public_key, a,
alice_private_key, mod),
bob_shared_key = multiply(
alice_public_key, a,
bob_private_key, mod);
std::cout << "Shared keys:\n";
std::cout << alice_shared_key << std::endl;
std::cout << bob_shared_key << std::endl;
// Check whether shared keys are equal
assert(alice_shared_key == bob_shared_key);
}
std::cout
uint256_t
class for 256-bit unsigned integer
Definition: uint256_t.hpp:33
std::endl
T endl(T... args)
multiply
int multiply(int x, int res[], int res_size)
Definition: power_for_huge_numbers.cpp:25
ciphers::elliptic_curve_key_exchange::Point
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

{
// 1st test: Operations test
uint128_t a("122"), b("2312");
assert(a + b == 2434);
assert(b - a == 2190);
assert(a * b == 282064);
assert(b / a == 18);
assert(b % a == 116);
assert((a & b) == 8);
assert((a | b) == 2426);
assert((a ^ b) == 2418);
assert((a << 64) == uint128_t("2250502776992565297152"));
assert((b >> 7) == 18);
// 2nd test: Operations test
a = uint128_t("12321421424232142122");
b = uint128_t("23123212");
assert(a + b == uint128_t("12321421424255265334"));
assert(a - b == uint128_t("12321421424209018910"));
assert(a * b == uint128_t("284910839733861759501135864"));
assert(a / b == 532859423865LL);
assert(a % b == 3887742);
assert((a & b) == 18912520);
assert((a | b) == uint128_t("12321421424236352814"));
assert((a ^ b) == uint128_t("12321421424217440294"));
assert((a << 64) == uint128_t("227290107637132170748078080907806769152"));
}
uint128_t
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

{
// 1st test: Operations test
uint256_t a("122"), b("2312");
assert(a + b == 2434);
assert(b - a == 2190);
assert(a * b == 282064);
assert(b / a == 18);
assert(b % a == 116);
assert((a & b) == 8);
assert((a | b) == 2426);
assert((a ^ b) == 2418);
assert((a << 64) == uint256_t("2250502776992565297152"));
assert((b >> 7) == 18);
// 2nd test: Operations test
a = uint256_t("12321423124513251424232142122");
b = uint256_t("23124312431243243215354315132413213212");
assert(a + b == uint256_t("23124312443564666339867566556645355334"));
// Since a < b, the value is greater
assert(a - b == uint256_t("115792089237316195423570985008687907853246860353"
"221642219366742944204948568846"));
assert(a * b == uint256_t("284924437928789743312147393953938013677909398222"
"169728183872115864"));
assert(b / a == uint256_t("1876756621"));
assert(b % a == uint256_t("2170491202688962563936723450"));
assert((a & b) == uint256_t("3553901085693256462344"));
assert((a | b) == uint256_t("23124312443564662785966480863388892990"));
assert((a ^ b) == uint256_t("23124312443564659232065395170132430646"));
assert((a << 128) == uint256_t("4192763024643754272961909047609369343091683"
"376561852756163540549632"));
}