99 lines
3.6 KiB
C++
99 lines
3.6 KiB
C++
|
|
#include <cstdint>
|
||
|
|
#include <iostream>
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
#include "grotto.hpp"
|
||
|
|
|
||
|
|
/// Binomial jet readouts and an exact ring switch from one public offset.
|
||
|
|
int main()
|
||
|
|
{
|
||
|
|
//! [jet-and-ring]
|
||
|
|
// --- Binomial jet -------------------------------------------------------
|
||
|
|
// After eta opens, the jet is the binomial basis at the wrapped
|
||
|
|
// center+kappa. Degree 3 leaves room for a degree-2 hockey-stick prefix.
|
||
|
|
const std::uint8_t center = 12;
|
||
|
|
const std::uint8_t eta = 3;
|
||
|
|
const std::uint8_t point = static_cast<std::uint8_t>(center + eta); // 15
|
||
|
|
const std::size_t degree = 3;
|
||
|
|
auto jet_keys = grotto::make_offset_jet_keys<std::uint8_t>(center, degree);
|
||
|
|
// f(t) = 4 + 2 C(t,1) + C(t,2) (padded to degree 3).
|
||
|
|
const std::vector<std::uint64_t> poly{4, 2, 1};
|
||
|
|
std::vector<std::uint64_t> coeff = poly;
|
||
|
|
coeff.push_back(0);
|
||
|
|
const std::vector<std::uint8_t> knots{0};
|
||
|
|
|
||
|
|
const auto j0 = grotto::offset_jet_shares<0>(jet_keys, knots, eta);
|
||
|
|
const auto j1 = grotto::offset_jet_shares<1>(jet_keys, knots, eta);
|
||
|
|
std::vector<std::uint64_t> jet(degree + 1);
|
||
|
|
for (std::size_t k = 0; k <= degree; ++k)
|
||
|
|
jet[k] = j0[k] + j1[k];
|
||
|
|
|
||
|
|
const std::uint64_t value = grotto::offset_jet_dot(coeff, jet);
|
||
|
|
const std::uint64_t diff = grotto::offset_jet_dot(
|
||
|
|
grotto::offset_jet_difference_coeff(coeff), jet);
|
||
|
|
const std::uint64_t prefix = grotto::offset_jet_dot(
|
||
|
|
grotto::offset_jet_prefix_coeff(poly), jet);
|
||
|
|
|
||
|
|
// Padé / Newton are public dots against the same jet, then one reciprocal
|
||
|
|
// after the shares are opened. For a seed p(t)/p'(t):
|
||
|
|
// auto num = offset_jet_dot(coeff, jet);
|
||
|
|
// auto den = offset_jet_dot(offset_jet_difference_coeff(coeff), jet);
|
||
|
|
// // open num, den; one masked reciprocal; Newton: t - num/den.
|
||
|
|
|
||
|
|
// --- Exact ring switch --------------------------------------------------
|
||
|
|
// Same public-offset pattern: eta = x - r, then x lands in the residue.
|
||
|
|
const std::uint8_t r = 200;
|
||
|
|
const std::uint8_t x = 44;
|
||
|
|
const std::uint8_t ring_eta = static_cast<std::uint8_t>(x - r); // 100, wraps
|
||
|
|
using Z = grotto::zn64<1009>;
|
||
|
|
auto ring = grotto::make_ring_switch_keys<Z>(r);
|
||
|
|
const Z x_mod = grotto::ring_switch_eval<0>(ring, ring_eta)
|
||
|
|
+ grotto::ring_switch_eval<1>(ring, ring_eta);
|
||
|
|
|
||
|
|
auto field = grotto::make_ring_switch_keys<dpf::field128>(r);
|
||
|
|
const dpf::field128 x_field = grotto::ring_switch_eval<0>(field, ring_eta)
|
||
|
|
+ grotto::ring_switch_eval<1>(field, ring_eta);
|
||
|
|
//! [jet-and-ring]
|
||
|
|
|
||
|
|
auto c = [](std::uint64_t t, unsigned k) {
|
||
|
|
return grotto::offset_jet_binom(t, k);
|
||
|
|
};
|
||
|
|
const std::uint64_t expect_v =
|
||
|
|
4 + 2 * c(point, 1) + c(point, 2);
|
||
|
|
if (value != expect_v)
|
||
|
|
{
|
||
|
|
std::cerr << "jet value\n";
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
const std::uint64_t expect_fx1 =
|
||
|
|
4 + 2 * c(static_cast<std::uint8_t>(point + 1), 1)
|
||
|
|
+ c(static_cast<std::uint8_t>(point + 1), 2);
|
||
|
|
if (diff != expect_fx1 - expect_v)
|
||
|
|
{
|
||
|
|
std::cerr << "jet difference\n";
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
std::uint64_t expect_p = 0;
|
||
|
|
for (std::uint8_t i = 0; i < point; ++i)
|
||
|
|
expect_p += 4 + 2 * c(i, 1) + c(i, 2);
|
||
|
|
if (prefix != expect_p)
|
||
|
|
{
|
||
|
|
std::cerr << "jet prefix\n";
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
if (x_mod.raw() != static_cast<std::uint64_t>(x) % 1009)
|
||
|
|
{
|
||
|
|
std::cerr << "ring zn64\n";
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
if (x_field != dpf::field128{x})
|
||
|
|
{
|
||
|
|
std::cerr << "ring field128\n";
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::cout << value << " " << diff << " " << prefix << " "
|
||
|
|
<< x_mod.raw() << "\n";
|
||
|
|
return 0;
|
||
|
|
}
|