10#include <botan/mceliece.h>
12#include <botan/internal/bit_ops.h>
20double binomial(
size_t n,
size_t k) {
23 for(
size_t i = 0; i != k; ++i) {
31double log_binomial(
size_t n,
size_t k) {
34 for(
size_t i = 0; i != k; ++i) {
39 return x / std::numbers::ln2;
42double nb_iter(
size_t n,
size_t k,
size_t w,
size_t p,
size_t l) {
43 double x = 2 * log_binomial(k / 2, p);
44 x += log_binomial(n - k - l, w - 2 * p);
45 x = log_binomial(n, w) - x;
49double cout_iter(
size_t n,
size_t k,
size_t p,
size_t l) {
50 double x = binomial(k / 2, p);
51 const size_t i =
static_cast<size_t>(std::log(x) / std::numbers::ln2);
52 double res = 2 * p * (n - k - l) * std::ldexp(x * x, -
static_cast<int>(l));
60 res += x + k * ((n - k) / 2.0);
62 return std::log(res) / std::numbers::ln2;
65double cout_total(
size_t n,
size_t k,
size_t w,
size_t p,
size_t l) {
66 return nb_iter(n, k, w, p, l) + cout_iter(n, k, p, l);
69double best_wf(
size_t n,
size_t k,
size_t w,
size_t p) {
74 double min = cout_total(n, k, w, p, 0);
76 for(
size_t l = 1; l < n - k; ++l) {
77 const double lwf = cout_total(n, k, w, p, l);
93 double min = cout_total(n, k, t, 0, 0);
94 for(
size_t p = 0; p != t / 2; ++p) {
95 double lwf = best_wf(n, k + 1, t, p);
100 min = std::min(min, lwf);
103 return static_cast<size_t>(min);
size_t mceliece_work_factor(size_t n, size_t t)
constexpr uint8_t ceil_log2(T x)