diff --git a/ciphers/elliptic_curve_key_exchange.cpp b/ciphers/elliptic_curve_key_exchange.cpp index a4282a024..10023525d 100644 --- a/ciphers/elliptic_curve_key_exchange.cpp +++ b/ciphers/elliptic_curve_key_exchange.cpp @@ -1,5 +1,5 @@ /** - * @file elliptic_curve_key_exchange.cpp + * @file * @brief Implementation of [Elliptic Curve Diffie Hellman Key * Exchange](https://cryptobook.nakov.com/asymmetric-key-ciphers/ecdh-key-exchange). * @@ -21,13 +21,10 @@ * alicePubKey * bobPrivKey = bobPubKey * alicePrivKey = secret * @author [Ashish Daulatabad](https://github.com/AshishYUO) */ +#include /// for assert +#include /// for IO operation -#include -#include -#include -#include - -#include "uint256_t.hpp" +#include "uint256_t.hpp" /// for 256-bit integer; /** * @namespace ciphers @@ -36,7 +33,9 @@ namespace ciphers { /** * @brief namespace elliptic_curve_key_exchange - * @details Demonstration of ECDH (Elliptic Curve Diffie-Hellman) key exchange. + * @details Demonstration of [Elliptic Curve + * Diffie-Hellman](https://cryptobook.nakov.com/asymmetric-key-ciphers/ecdh-key-exchange) + * key exchange. */ namespace elliptic_curve_key_exchange { @@ -84,10 +83,15 @@ uint256_t exp(uint256_t number, uint256_t power, const uint256_t &mod) { /** * @brief Addition of points - * @details Add given point to generate third point + * @details Add given point to generate third point. More description can be + * found + * [here](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Point_addition), + * and + * [here](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Point_doubling) * @param a First point * @param b Second point - * @param curve_a_coeff Coefficient of given curve (y^2 = x^3 + ax + b) % mod + * @param curve_a_coeff Coefficient `a` of the given curve (y^2 = x^3 + ax + b) + * % mod * @param mod Given field * @return the resultant point */ @@ -105,8 +109,9 @@ Point addition(Point a, Point b, const uint256_t &curve_a_coeff, uint256_t num = (b.y - a.y + mod), den = (b.x - a.x + mod); lambda = (num * (exp(den, mod - 2, mod))) % mod; } else { - // Slope being infinite - // Taking dertivative of y^2 = x^3 + ax + b + // Slope when the line is tangent to curve. + // This operation is performed while doubling. + // Taking derivative of y^2 = x^3 + ax + b // 2y dy = (3 * x^2 + a)dx // (dy/dx) = (3x^2 + a)/(2y) if (!a.y) { @@ -132,7 +137,8 @@ Point addition(Point a, Point b, const uint256_t &curve_a_coeff, /** * @brief multiply Point and integer * @details Multiply Point by a scalar factor (here it is a private key p). The - * multiplication is called as double and add method + * multiplication is called as [double and add + * method](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Double-and-add) * @param a Point to multiply * @param curve_a_coeff Coefficient of given curve (y^2 = x^3 + ax + b) % mod * @param p The scalar value @@ -172,7 +178,7 @@ Point multiply(const Point &a, const uint256_t &curve_a_coeff, uint256_t p, * @returns void */ static void uint128_t_tests() { - // Tests 1: Operations test + // 1st test: Operations test uint128_t a("122"), b("2312"); assert(a + b == uint128_t("2434")); assert(b - a == uint128_t("2190")); @@ -185,7 +191,7 @@ static void uint128_t_tests() { assert((a << 64) == uint128_t("2250502776992565297152")); assert((b >> 7) == 18); - // Tests 2: Operations test + // 2nd test: Operations test a = uint128_t("12321421424232142122"); b = uint128_t("23123212"); assert(a + b == uint128_t("12321421424255265334")); @@ -295,8 +301,8 @@ static void test() { * @returns 0 on exit */ int main() { - uint128_t_tests(); // running predefined 128-bit unsigned integer tests. - uint256_t_tests(); // running predefined 256-bit unsigned integer tests. + uint128_t_tests(); // running predefined 128-bit unsigned integer tests + uint256_t_tests(); // running predefined 256-bit unsigned integer tests test(); // running predefined tests return 0; } diff --git a/ciphers/uint128_t.hpp b/ciphers/uint128_t.hpp index f7cf08e2d..6846d7d4c 100644 --- a/ciphers/uint128_t.hpp +++ b/ciphers/uint128_t.hpp @@ -7,13 +7,13 @@ * @author [Ashish Daulatabad](https://github.com/AshishYUO) */ -#include -#include -#include -#include +#include /// for `std::reverse` and other operations +#include /// for `std::cout` overload +#include /// for `std::string` +#include /// for `std::pair` library #ifdef _MSC_VER -#include +#include /// for _BitScanForward64 and __BitScanReverse64 operation #endif #ifndef CIPHERS_UINT128_T_HPP_ @@ -54,10 +54,10 @@ std::string add(const std::string &first, const std::string &second) { } /** * @class uint128_t - * @details 128-bit numbers. + * @brief class for 128-bit unsigned integer */ class uint128_t { - uint64_t f{}, s{}; /// First and second half of 128 bit number. + uint64_t f{}, s{}; /// First and second half of 128 bit number /** * @brief Get integer from given string. diff --git a/ciphers/uint256_t.hpp b/ciphers/uint256_t.hpp index e470047a6..8ab98867d 100644 --- a/ciphers/uint256_t.hpp +++ b/ciphers/uint256_t.hpp @@ -1,5 +1,5 @@ /** - * @file uint256_t.hpp + * @file * * @details Implementation of 256-bit unsigned integers. * @note The implementation can be flagged as not completed. This header is used @@ -7,10 +7,10 @@ * Diffie-Hellman) Key exchange. * @author [Ashish Daulatabad](https://github.com/AshishYUO) */ -#include -#include +#include /// for `std::string` +#include /// for `std::pair` library -#include "uint128_t.hpp" +#include "uint128_t.hpp" /// for uint128_t integer #ifndef CIPHERS_UINT256_T_HPP_ #define CIPHERS_UINT256_T_HPP_ @@ -28,7 +28,7 @@ struct std::is_unsigned : std::true_type {}; /** * @class uint256_t - * @details 256-bit number class. + * @brief class for 256-bit unsigned integer. */ class uint256_t { uint128_t f{}, s{}; /// First and second half of 256 bit number. @@ -504,94 +504,199 @@ class uint256_t { return *this; } - // Comparison operators + /** + * @brief operator < for uint256_t + * @param other number to be compared with this + * @returns true if this is less than other, else false + */ inline bool operator<(const uint256_t &other) { return f < other.f || (f == other.f && s < other.s); } + /** + * @brief operator <= for uint256_t + * @param other number to be compared with this + * @returns true if this is less than or equal to other, else false + */ inline bool operator<=(const uint256_t &other) { return f < other.f || (f == other.f && s <= other.s); } + /** + * @brief operator > for uint256_t + * @param other number to be compared with this + * @returns true if this is greater than other, else false + */ inline bool operator>(const uint256_t &other) { return f > other.f || (f == other.f && s > other.s); } + /** + * @brief operator >= for uint256_t + * @param other number to be compared with this + * @returns true if this is greater than or equal than other, else false + */ inline bool operator>=(const uint256_t &other) { return (f > other.f) || (f == other.f && s >= other.s); } + /** + * @brief operator == for uint256_t + * @param other number to be compared with this + * @returns true if this is equal than other, else false + */ inline bool operator==(const uint256_t &other) { return f == other.f && s == other.s; } + /** + * @brief operator != for uint256_t + * @param other number to be compared with this + * @returns true if this is not equal than other, else false + */ inline bool operator!=(const uint256_t &other) { return !((*this) == other); } + /** + * @brief operator ! for uint256_t + * @returns true if this has zero value, else false + */ inline bool operator!() { return !f && !s; } + /** + * @brief operator && for uint256_t + * @param b number to be compared with this + * @returns true if both of the values are not zero, else false + */ inline bool operator&&(const uint256_t &b) { return (s || f) && (b.s || b.f); } + /** + * @brief operator || for uint256_t + * @param b number to be compared with this + * @returns true if one of the values are not zero, else false + */ inline bool operator||(const uint256_t &b) { return (s || f) || (b.s || b.f); } + /** + * @brief operator () for uint256_t + * @returns true if this value is non-zero, else false + */ inline bool operator()() { return s || f; } + /** + * @brief operator < for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is less than other, else false + */ template ::value, T>::type> bool operator<(const T &other) { return *this < uint256_t(other); } + /** + * @brief operator <= for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is less than or equal to other, else false + */ template ::value, T>::type> bool operator<=(const T &other) { return *this <= uint256_t(other); } + /** + * @brief operator > for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is greater than other, else false + */ template ::value, T>::type> bool operator>(const T &other) { return *this > uint256_t(other); } + /** + * @brief operator >= for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is greater than or equal other, else false + */ template ::value, T>::type> bool operator>=(const T &other) { return *this >= uint256_t(other); } + /** + * @brief operator == for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is equal to other, else false + */ template ::value, T>::type> bool operator==(const T &other) { return *this == uint256_t(other); } + /** + * @brief operator != for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is not equal to other, else false + */ template ::value, T>::type> bool operator!=(const T &other) { return *this != uint256_t(other); } + /** + * @brief operator && for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is both values are non-zero, else false + */ template ::value, T>::type> inline bool operator&&(const T &b) { return (s || f) && (b); } + /** + * @brief operator || for other types + * @tparam T integral type + * @param other number to be compared with this + * @returns true if this is either one of the values are non-zero, else + * false + */ template ::value, T>::type> inline bool operator||(const T &b) { return (s || f) || (b); } - // Bitwise operators + /** + * @brief operator ~ for uint256_t + * @returns 1's complement of this number + */ inline uint256_t operator~() { return {~f, ~s}; } + /** + * @brief operator << for uint256_t + * @tparam T integral type + * @param p number denoting number of shifts + * @returns value of this shifted by p to left + */ template ::value, T>::type> uint256_t operator<<(const T &p) { @@ -604,6 +709,12 @@ class uint256_t { (this->s << p)); } + /** + * @brief operator <<= for uint256_t + * @tparam T integral type + * @param p number denoting number of shifts + * @returns this shifted by p to left + */ template ::value, T>::type> uint256_t &operator<<=(const T &p) { @@ -619,6 +730,12 @@ class uint256_t { return *this; } + /** + * @brief operator >> for uint256_t + * @tparam T integral type + * @param p number denoting number of shifts + * @returns value of this shifted by p to right + */ template ::value, T>::type> uint256_t operator>>(const T &p) { @@ -631,6 +748,12 @@ class uint256_t { (this->s >> p) + (this->f << (128 - p))); } + /** + * @brief operator >>= for uint256_t + * @tparam T integral type + * @param p number denoting number of shifts + * @returns this shifted by p to right + */ template ::value, T>::type> uint256_t &operator>>=(const T &p) { @@ -646,22 +769,44 @@ class uint256_t { return *this; } + /** + * @brief operator & for other types (bitwise operator) + * @tparam T integral type + * @param p number to be operated + * @returns value of this & p (& is bit-wise operator) + */ template ::value, T>::type> inline uint256_t operator&(const T &p) { return *this & uint256_t(p); } + /** + * @brief operator & for uint256_t (bitwise operator) + * @param p number to be operated + * @returns value of this & p (& is bit-wise operator) + */ inline uint256_t operator&(const uint256_t &p) { return {f & p.f, s & p.s}; } + /** + * @brief operator &= for uint256_t (bitwise operator) + * @param p number to be operated + * @returns this = this & p (& is bit-wise operator) + */ inline uint256_t &operator&=(const uint256_t &p) { f &= p.f; s &= p.s; return *this; } + /** + * @brief operator &= for other types (bitwise operator) + * @tparam T integral type + * @param p number to be operated + * @returns this = this & p (& is bit-wise operator) + */ template ::value, T>::type> inline uint256_t &operator&=(const T p) { @@ -669,16 +814,33 @@ class uint256_t { return *this; } + /** + * @brief operator | for other types (bitwise operator) + * @tparam T integral type + * @param p number to be operated + * @returns value of this | p (| is bit-wise operator) + */ template ::value, T>::type> inline uint256_t operator|(const T &p) { return *this | uint256_t(p); } + /** + * @brief operator | for uint256_t (bitwise operator) + * @param p number to be operated + * @returns value of this | p (| is bit-wise OR operator) + */ inline uint256_t operator|(const uint256_t &p) { return {this->f | p.f, this->s | p.s}; } + /** + * @brief operator |= for other types (bitwise operator) + * @tparam T integral type + * @param p number to be operated + * @returns this = this | p (| is bit-wise OR operator) + */ template ::value, T>::type> inline uint256_t &operator|=(const T &p) { @@ -686,28 +848,55 @@ class uint256_t { return *this; } + /** + * @brief operator |= for uint256_t (bitwise operator) + * @param p number to be operated + * @returns this = this | p (| is bit-wise OR operator) + */ inline uint256_t &operator|=(const uint256_t &p) { f |= p.f; s |= p.s; return *this; } + /** + * @brief operator ^ for other types (bitwise operator) + * @tparam T integral type + * @param p number to be operated + * @returns value of this ^ p (^ is bit-wise XOR operator) + */ template ::value, T>::type> inline uint256_t operator^(const T &p) { return uint256_t(f, s ^ p); } + /** + * @brief operator ^ for uint256_t (bitwise operator) + * @param p number to be operated + * @returns value of this ^ p (^ is bit-wise XOR operator) + */ inline uint256_t operator^(const uint256_t &p) { return {this->f ^ p.f, this->s ^ p.s}; } + /** + * @brief operator ^= for uint256_t (bitwise operator) + * @param p number to be operated + * @returns this = this ^ p (^ is bit-wise XOR operator) + */ inline uint256_t &operator^=(const uint256_t &p) { f ^= p.f; s ^= p.s; return *this; } + /** + * @brief operator ^= for other types (bitwise operator) + * @tparam T integral type + * @param p number to be operated + * @returns this = this ^ p (^ is bit-wise XOR operator) + */ template ::value, T>::type> inline uint256_t &operator^=(const T &p) {