10#include <botan/dl_group.h>
11#include <botan/numthry.h>
12#include <botan/internal/fmt.h>
18BigInt hash_seq(HashFunction& hash_fn,
29BigInt compute_x(HashFunction& hash_fn,
30 std::string_view identifier,
31 std::string_view password,
32 const std::vector<uint8_t>& salt)
34 hash_fn.update(identifier);
36 hash_fn.update(password);
38 secure_vector<uint8_t> inner_h = hash_fn.final();
41 hash_fn.update(inner_h);
43 secure_vector<uint8_t> outer_h = hash_fn.final();
58 std::string group_name =
"modp/srp/" + std::to_string(N.
bits());
73std::pair<BigInt, SymmetricKey>
75 std::string_view password,
76 std::string_view group_id,
77 std::string_view hash_id,
78 const std::vector<uint8_t>& salt,
85 return srp6_client_agree(identifier, password, group, hash_id, salt, B, a_bits, rng);
88std::pair<BigInt, SymmetricKey>
90 std::string_view password,
92 std::string_view hash_id,
93 const std::vector<uint8_t>& salt,
103 const size_t p_bytes = group.
p_bytes();
109 if(8*hash_fn->output_length() >= group.
p_bits())
113 const BigInt k = hash_seq(*hash_fn, p_bytes, p, g);
115 const BigInt a(rng, a_bits);
119 const BigInt u = hash_seq(*hash_fn, p_bytes, A, B);
121 const BigInt x = compute_x(*hash_fn, identifier, password, salt);
127 const BigInt a_ux = a + u*x;
129 const size_t max_aux_bits =
130 std::max<size_t>(a_bits + 1,
131 2*8*hash_fn->output_length());
138 return std::make_pair(A, Sk);
142 std::string_view password,
143 const std::vector<uint8_t>& salt,
144 std::string_view group_id,
145 std::string_view hash_id)
152 std::string_view password,
153 const std::vector<uint8_t>& salt,
155 std::string_view hash_id)
158 if(8*hash_fn->output_length() >= group.
p_bits())
162 const BigInt x = compute_x(*hash_fn, identifier, password, salt);
163 return group.
power_g_p(x, hash_fn->output_length() * 8);
167 std::string_view group_id,
168 std::string_view hash_id,
173 return this->
step1(v, group, hash_id, b_bits, rng);
178 std::string_view hash_id,
190 m_b =
BigInt(rng, b_bits);
194 if(8*hash_fn->output_length() >= group.
p_bits())
198 const BigInt k = hash_seq(*hash_fn, m_group.
p_bytes(), p, g);
206 if(A <= 0 || A >= m_group.
get_p())
210 if(8*hash_fn->output_length() >= m_group.
p_bits())
214 const BigInt u = hash_seq(*hash_fn, m_group.
p_bytes(), A, m_B);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ARG_CHECK(expr, msg)
static BigInt decode(const uint8_t buf[], size_t length)
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
BigInt power_g_p(const BigInt &x) const
BigInt mod_p(const BigInt &x) const
BigInt multiply_mod_p(const BigInt &x, const BigInt &y) const
const BigInt & get_p() const
BigInt power_b_p(const BigInt &b, const BigInt &x, size_t max_x_bits) const
size_t exponent_bits() const
const BigInt & get_g() const
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
BigInt step1(const BigInt &v, std::string_view group_id, std::string_view hash_id, RandomNumberGenerator &rng)
SymmetricKey step2(const BigInt &A)
std::string fmt(std::string_view format, const T &... args)
std::pair< BigInt, SymmetricKey > srp6_client_agree(std::string_view identifier, std::string_view password, std::string_view group_id, std::string_view hash_id, const std::vector< uint8_t > &salt, const BigInt &B, RandomNumberGenerator &rng)
BigInt srp6_generate_verifier(std::string_view identifier, std::string_view password, const std::vector< uint8_t > &salt, std::string_view group_id, std::string_view hash_id)
std::string srp6_group_identifier(const BigInt &N, const BigInt &g)