Current section
Files
Jump to
Current section
Files
c_src/srp.hh
// (c) Yura Zhivaga <yzhivaga@gmail.com>
// 2018
#include <iostream>
#include <vector>
#include <random>
#include <climits>
#include <algorithm>
#include <functional>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/random.hpp>
#include "sha/sha512.hh"
using namespace boost::random;
using namespace boost::multiprecision;
using Int = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off>;
class SRP {
private:
Int N;
Int g;
Int k;
public:
SRP(Int N, Int g, Int k) : N(N), g(g), k(k) {};
std::string big_int_to_hex(Int n, bool ignore = false) {
std::stringstream ss;
ss << std::hex << n;
std::string str = ss.str();
if (!ignore && str.length() % 2 == 1) {
str.insert(0, "0");
}
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
}
Int hex_to_big_int(std::string hex) {
if (hex.substr(0, 2) == "0x") {
return Int(hex);
} else {
return Int("0x" + hex);
}
}
bool is_zero_mod_n(std::string number) {
Int n = hex_to_big_int(number);
return int(n % N) == 0;
}
template<typename T, typename... Args>
std::string H(std::initializer_list<T> list) {
std::stringstream data;
int i = 0;
for (auto elem : list)
i++ != 0 ? data << ":" << elem : data << elem;
return sw::sha512::calculate(data.str());
}
Int random_big_number_512bit() {
std::random_device rd;
mt19937 base_gen(rd());
independent_bits_engine<mt11213b, 512, Int> gen(base_gen);
return gen();
}
std::string rnd() {
return big_int_to_hex(random_big_number_512bit());
}
std::string s() {
return rnd();
}
std::string x(std::string s, std::string p) {
return H({s, p});
}
std::string v(std::string x) {
return big_int_to_hex(powm(g, hex_to_big_int(x), N));
}
std::string a() {
return rnd();
}
std::string A(std::string _a) {
Int a = hex_to_big_int(_a);
return big_int_to_hex(powm(g, a, N));
}
std::string b() {
return rnd();
}
std::string B(std::string _v, std::string _b) {
Int v = hex_to_big_int(_v);
Int b = hex_to_big_int(_b);
Int step1 = powm(g, b, N);
return big_int_to_hex(k * v + step1);
}
std::string u(std::string A, std::string B) {
return H({A, B});
}
std::string server_s(std::string _A, std::string _v, std::string _u, std::string _b) {
Int A = hex_to_big_int(_A);
Int v = hex_to_big_int(_v);
Int b = hex_to_big_int(_b);
Int u = hex_to_big_int(_u);
Int step1 = powm(v, u, N);
Int step2 = A * step1;
Int final_result = powm(step2, b, N);
return big_int_to_hex(final_result, true);
}
std::string client_s(std::string _B, std::string _x, std::string _u, std::string _a) {
Int B = hex_to_big_int(_B);
Int x = hex_to_big_int(_x);
Int a = hex_to_big_int(_a);
Int u = hex_to_big_int(_u);
Int step1 = powm(g, x, N);
Int step2 = k * step1;
Int step3 = B - step2;
Int step4 = u * x;
Int step5 = a + step4;
Int final_result = powm(step3, step5, N);
return big_int_to_hex(final_result, true);
}
std::string M(std::string I, std::string s, std::string A, std::string B, std::string K) {
std::string N_hex = big_int_to_hex(N);
std::string g_hex = big_int_to_hex(g);
Int N_hash_int = hex_to_big_int(H({N_hex}));
Int g_hash_int = hex_to_big_int(H({g_hex}));
std::string I_hash = H({I});
std::string xor_step = big_int_to_hex(N_hash_int xor g_hash_int);
return H({xor_step, I_hash, s, A, B, K});
}
std::string R(std::string A, std::string M, std::string K) {
return H({A, M, K});
}
};