8#include <botan/fpe_fe1.h>
9#include <botan/internal/loadstor.h>
10#include <botan/numthry.h>
11#include <botan/internal/divide.h>
12#include <botan/internal/fmt.h>
13#include <botan/reducer.h>
21const size_t MAX_N_BYTES = 128/8;
28void factor(BigInt n, BigInt& a, BigInt& b)
35 a <<= (n_low_zero / 2);
36 b <<= n_low_zero - (n_low_zero / 2);
63 std::string_view mac_algo) :
73 if(m_n_bytes.size() > MAX_N_BYTES)
89 mod_a = std::make_unique<Modular_Reducer>(m_a);
101 return fmt(
"FPE_FE1({},{})", m_mac->name(), m_rounds);
106 return m_mac->key_spec();
111 return m_mac->has_keying_material();
114void FPE_FE1::key_schedule(
const uint8_t key[],
size_t length)
116 m_mac->set_key(key, length);
119BigInt FPE_FE1::F(
const BigInt& R,
size_t round,
120 const secure_vector<uint8_t>& tweak_mac,
121 secure_vector<uint8_t>& tmp)
const
125 m_mac->update(tweak_mac);
126 m_mac->update_be(
static_cast<uint32_t
>(round));
128 m_mac->update_be(
static_cast<uint32_t
>(tmp.size()));
129 m_mac->update(tmp.data(), tmp.size());
131 tmp = m_mac->final();
132 return BigInt(tmp.data(), tmp.size());
135secure_vector<uint8_t> FPE_FE1::compute_tweak_mac(
const uint8_t tweak[],
size_t tweak_len)
const
137 m_mac->update_be(
static_cast<uint32_t
>(m_n_bytes.size()));
138 m_mac->update(m_n_bytes.data(), m_n_bytes.size());
140 m_mac->update_be(
static_cast<uint32_t
>(tweak_len));
142 m_mac->update(tweak, tweak_len);
144 return m_mac->final();
156 for(
size_t i = 0; i != m_rounds; ++i)
159 Fi = F(R, i, tweak_mac, tmp);
160 X = m_a * R + mod_a->reduce(L + Fi);
174 for(
size_t i = 0; i != m_rounds; ++i)
178 Fi = F(R, m_rounds-i-1, tweak_mac, tmp);
179 X = m_b * mod_a->reduce(W - Fi) + R;
189 return encrypt(x, tweak8,
sizeof(tweak8));
196 return decrypt(x, tweak8,
sizeof(tweak8));
203 const std::vector<uint8_t>& tweak)
205 FPE_FE1 fpe(n, 3,
true,
"HMAC(SHA-256)");
207 return fpe.
encrypt(
X, tweak.data(), tweak.size());
212 const std::vector<uint8_t>& tweak)
214 FPE_FE1 fpe(n, 3,
true,
"HMAC(SHA-256)");
216 return fpe.
decrypt(
X, tweak.data(), tweak.size());
static secure_vector< uint8_t > encode_locked(const BigInt &n)
static std::vector< uint8_t > encode(const BigInt &n)
static BigInt from_word(word n)
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
constexpr void store_be(uint16_t in, uint8_t out[2])
void ct_divide(const BigInt &x, const BigInt &y, BigInt &q_out, BigInt &r_out)
std::vector< T, secure_allocator< T > > secure_vector