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) {
98 return fmt(
"FPE_FE1({},{})", m_mac->name(), m_rounds);
102 return m_mac->key_spec();
106 return m_mac->has_keying_material();
109void FPE_FE1::key_schedule(std::span<const uint8_t> key) {
113BigInt FPE_FE1::F(
const BigInt& R,
119 m_mac->update(tweak_mac);
120 m_mac->update_be(
static_cast<uint32_t
>(round));
122 m_mac->update_be(
static_cast<uint32_t
>(tmp.size()));
123 m_mac->update(tmp.data(), tmp.size());
125 tmp = m_mac->final();
130 m_mac->update_be(
static_cast<uint32_t
>(m_n_bytes.size()));
131 m_mac->update(m_n_bytes.data(), m_n_bytes.size());
133 m_mac->update_be(
static_cast<uint32_t
>(tweak_len));
135 m_mac->update(tweak, tweak_len);
138 return m_mac->final();
149 for(
size_t i = 0; i != m_rounds; ++i) {
151 Fi = F(R, i, tweak_mac, tmp);
152 X = m_a * R + mod_a->reduce(L + Fi);
165 for(
size_t i = 0; i != m_rounds; ++i) {
168 Fi = F(R, m_rounds - i - 1, tweak_mac, tmp);
169 X = m_b * mod_a->reduce(W - Fi) + R;
178 return encrypt(x, tweak8,
sizeof(tweak8));
184 return decrypt(x, tweak8,
sizeof(tweak8));
190 FPE_FE1 fpe(n, 3,
true,
"HMAC(SHA-256)");
192 return fpe.
encrypt(
X, tweak.data(), tweak.size());
196 FPE_FE1 fpe(n, 3,
true,
"HMAC(SHA-256)");
198 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="")
static Modular_Reducer for_public_modulus(const BigInt &m)
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)