8#include <botan/fpe_fe1.h>
11#include <botan/numthry.h>
12#include <botan/reducer.h>
13#include <botan/internal/divide.h>
14#include <botan/internal/fmt.h>
15#include <botan/internal/loadstor.h>
22const size_t MAX_N_BYTES = 128 / 8;
29void factor(BigInt n, BigInt& a, BigInt&
b) {
35 a <<= (n_low_zero / 2);
36 b <<= n_low_zero - (n_low_zero / 2);
40 while(n %
PRIMES[i] == 0) {
54 if(a <= 1 ||
b <= 1) {
70 if(m_n_bytes.size() > MAX_N_BYTES) {
86 mod_a = std::make_unique<Modular_Reducer>(m_a);
96 return fmt(
"FPE_FE1({},{})", m_mac->name(), m_rounds);
100 return m_mac->key_spec();
104 return m_mac->has_keying_material();
107void FPE_FE1::key_schedule(std::span<const uint8_t> key) {
111BigInt FPE_FE1::F(
const BigInt& R,
117 m_mac->update(tweak_mac);
118 m_mac->update_be(
static_cast<uint32_t
>(round));
120 m_mac->update_be(
static_cast<uint32_t
>(tmp.size()));
121 m_mac->update(tmp.data(), tmp.size());
123 tmp = m_mac->final();
128 m_mac->update_be(
static_cast<uint32_t
>(m_n_bytes.size()));
129 m_mac->update(m_n_bytes.data(), m_n_bytes.size());
131 m_mac->update_be(
static_cast<uint32_t
>(tweak_len));
133 m_mac->update(tweak, tweak_len);
136 return m_mac->final();
147 for(
size_t i = 0; i != m_rounds; ++i) {
149 Fi = F(R, i, tweak_mac, tmp);
150 X = m_a * R + mod_a->reduce(L + Fi);
163 for(
size_t i = 0; i != m_rounds; ++i) {
166 Fi = F(R, m_rounds - i - 1, tweak_mac, tmp);
167 X = m_b * mod_a->reduce(W - Fi) + R;
176 return encrypt(x, tweak8,
sizeof(tweak8));
182 return decrypt(x, tweak8,
sizeof(tweak8));
188 FPE_FE1 fpe(n, 3,
true,
"HMAC(SHA-256)");
190 return fpe.
encrypt(
X, tweak.data(), tweak.size());
194 FPE_FE1 fpe(n, 3,
true,
"HMAC(SHA-256)");
196 return fpe.
decrypt(
X, tweak.data(), tweak.size());
static BigInt from_bytes(std::span< const uint8_t > bytes)
static BigInt from_word(word n)
T serialize(size_t len) const
BigInt encrypt(const BigInt &x, const uint8_t tweak[], size_t tweak_len) const
std::string name() const override
FPE_FE1(const BigInt &n, size_t rounds=5, bool compat_mode=false, std::string_view mac_algo="HMAC(SHA-256)")
bool has_keying_material() const override
Key_Length_Specification key_spec() const override
BigInt decrypt(const BigInt &x, const uint8_t tweak[], size_t tweak_len) const
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
void set_key(const SymmetricKey &key)
BigInt fe1_decrypt(const BigInt &n, const BigInt &X, const SymmetricKey &key, const std::vector< uint8_t > &tweak)
BigInt fe1_encrypt(const BigInt &n, const BigInt &X, const SymmetricKey &key, const std::vector< uint8_t > &tweak)
std::string fmt(std::string_view format, const T &... args)
size_t low_zero_bits(const BigInt &n)
const size_t PRIME_TABLE_SIZE
void ct_divide(const BigInt &x, const BigInt &y, BigInt &q_out, BigInt &r_out)
std::vector< T, secure_allocator< T > > secure_vector
constexpr auto store_be(ParamTs &&... params)