10#include <botan/assert.h>
11#include <botan/dl_group.h>
12#include <botan/exceptn.h>
13#include <botan/hash.h>
14#include <botan/internal/fmt.h>
21 hash_fn.update(in1.serialize(p_bytes));
22 hash_fn.update(in2.serialize(p_bytes));
28 std::string_view identifier,
29 std::string_view password,
30 const std::vector<uint8_t>& salt) {
31 hash_fn.update(identifier);
33 hash_fn.update(password);
38 hash_fn.update(inner_h);
53 const std::string group_name =
"modp/srp/" + std::to_string(N.
bits());
57 if(group.get_p() == N && group.get_g() == g) {
67 std::string_view password,
68 std::string_view group_id,
69 std::string_view hash_id,
70 const std::vector<uint8_t>& salt,
74 const size_t a_bits = group.exponent_bits();
76 return srp6_client_agree(identifier, password, group, hash_id, salt, B, a_bits, rng);
80 std::string_view password,
82 std::string_view hash_id,
83 const std::vector<uint8_t>& salt,
92 const size_t p_bytes = group.
p_bytes();
94 if(B <= 0 || B >= p) {
99 if(8 * hash_fn->output_length() >= group.
p_bits()) {
100 throw Invalid_Argument(
fmt(
"Hash function {} too large for SRP6 with this group", hash_fn->name()));
103 const BigInt k = hash_seq(*hash_fn, p_bytes, p, g);
105 const BigInt a(rng, a_bits);
109 const BigInt u = hash_seq(*hash_fn, p_bytes, A, B);
111 const BigInt x = compute_x(*hash_fn, identifier, password, salt);
117 const BigInt a_ux = a + u * x;
119 const size_t max_aux_bits = std::max<size_t>(a_bits + 1, 2 * 8 * hash_fn->output_length());
126 return std::make_pair(A, Sk);
130 std::string_view password,
131 const std::vector<uint8_t>& salt,
132 std::string_view group_id,
133 std::string_view hash_id) {
139 std::string_view password,
140 const std::vector<uint8_t>& salt,
142 std::string_view hash_id) {
144 if(8 * hash_fn->output_length() >= group.
p_bits()) {
145 throw Invalid_Argument(
fmt(
"Hash function {} too large for SRP6 with this group", hash_fn->name()));
148 const BigInt x = compute_x(*hash_fn, identifier, password, salt);
149 return group.
power_g_p(x, hash_fn->output_length() * 8);
153 std::string_view group_id,
154 std::string_view hash_id,
157 const size_t b_bits = group.exponent_bits();
158 return this->
step1(v, group, hash_id, b_bits, rng);
166 m_group = std::make_unique<DL_Group>(group);
168 const BigInt& g = m_group->get_g();
169 const BigInt& p = m_group->get_p();
172 m_b =
BigInt(rng, b_bits);
176 if(8 * hash_fn->output_length() >= m_group->p_bits()) {
177 throw Invalid_Argument(
fmt(
"Hash function {} too large for SRP6 with this group", hash_fn->name()));
180 const BigInt k = hash_seq(*hash_fn, m_group->p_bytes(), p, g);
181 m_B = m_group->mod_p(v * k + m_group->power_g_p(m_b, b_bits));
189 if(A <= 0 || A >= m_group->get_p()) {
194 if(8 * hash_fn->output_length() >= m_group->p_bits()) {
195 throw Invalid_Argument(
fmt(
"Hash function {} too large for SRP6 with this group", hash_fn->name()));
198 const BigInt u = hash_seq(*hash_fn, m_group->p_bytes(), A, m_B);
200 const BigInt vup = m_group->power_b_p(m_v, u, m_group->p_bits());
201 const BigInt S = m_group->power_b_p(m_group->multiply_mod_p(A, vup), m_b, m_group->p_bits());
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ARG_CHECK(expr, msg)
static BigInt from_bytes(std::span< const uint8_t > bytes)
T serialize(size_t len) const
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
static DL_Group from_name(std::string_view name)
BigInt power_b_p(const BigInt &b, const BigInt &x, size_t max_x_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)
std::vector< T, secure_allocator< T > > secure_vector