7#ifndef _MINISKETCH_SKETCH_IMPL_H_
8#define _MINISKETCH_SKETCH_IMPL_H_
18void PolyMod(
const std::vector<typename F::Elem>&
mod, std::vector<typename F::Elem>& val,
const F&
field) {
21 if (val.size() <
modsize)
return;
24 auto term = val.back();
28 for (
size_t x = 0; x <
mod.size() - 1; ++x) {
29 val[val.size() -
modsize + 1 + x] ^= mul(
mod[x]);
33 while (val.size() > 0 && val.back() == 0) val.pop_back();
38void DivMod(
const std::vector<typename F::Elem>&
mod, std::vector<typename F::Elem>& val, std::vector<typename F::Elem>&
div,
const F&
field) {
41 if (val.size() <
mod.size()) {
46 div.resize(val.size() -
mod.size() + 1);
48 auto term = val.back();
53 for (
size_t x = 0; x <
mod.size() - 1; ++x) {
54 val[val.size() -
modsize + 1 + x] ^= mul(
mod[x]);
64 if (
a.back() == 1)
return 0;
65 auto inv =
field.Inv(
a.back());
66 typename F::Multiplier mul(
field, inv);
68 for (
size_t i = 0; i <
a.size() - 1; ++i) {
76void GCD(std::vector<typename F::Elem>&
a, std::vector<typename F::Elem>& b,
const F&
field) {
77 if (
a.size() < b.size()) std::swap(
a, b);
78 while (b.size() > 0) {
93 if (
poly.size() == 0)
return;
95 for (
size_t i = 0; i <
poly.size(); ++i) {
96 auto x =
poly.size() - i - 1;
103void TraceMod(
const std::vector<typename F::Elem>&
mod, std::vector<typename F::Elem>& out,
const typename F::Elem& param,
const F&
field) {
104 out.reserve(
mod.size() * 2);
109 for (
int i = 0; i <
field.Bits() - 1; ++i) {
111 if (out.size() < 2) out.resize(2);
130 auto&
ppoly = stack[pos];
137 if (
ppoly.size() == 2) {
142 if (
ppoly.size() == 3) {
145 auto root =
field.Qrt(input);
146 if ((
field.Sqr(root) ^ root) != input) {
156 if (pos + 3 > stack.size()) {
158 stack.resize((pos + 3) * 2);
160 auto&
poly = stack[pos];
161 auto&
tmp = stack[pos + 1];
162 auto&
trace = stack[pos + 2];
165 for (
int iter = 0;; ++iter) {
206 for (
size_t i = 0; i <
trace.size(); ++i) {
209 while (
tmp.size() &&
tmp.back() == 0)
tmp.pop_back();
216 if (
tmp.size() != 0)
return false;
226 (
poly.size() - 2) >> (
field.Bits() - depth) == 0,
false);
265 std::vector<typename F::Elem>
roots;
270 std::vector<std::vector<typename F::Elem>> stack = {
poly};
283 std::vector<typename F::Multiplier> table;
292 typename F::Elem b = 1,
b_inv = 1;
296 for (
size_t n = 0; n !=
syndromes.size(); ++n) {
301 int x =
static_cast<int>(n + 1 - (
current.size() - 1) - (
prev.size() - 1));
306 bool swap = 2 * (
current.size() - 1) <= n;
313 for (
size_t i = 0; i <
prev.size(); ++i)
current[i + x] ^= mul(
prev[i]);
329 for (
size_t i = 0; i < odd_syndromes.size(); ++i) {
338 auto sqr =
field.Sqr(data);
339 typename F::Multiplier mul(
field, sqr);
350 std::reverse(
poly.begin(),
poly.end());
362 template<
typename... Args>
364 std::random_device rng;
365 std::uniform_int_distribution<uint64_t>
dist;
399 if (
poly.size() == 0)
return -1;
400 if (
poly.size() == 1)
return 0;
401 if ((
int)
poly.size() > 1 + max_count)
return -1;
402 std::reverse(
poly.begin(),
poly.end());
404 if (
roots.size() == 0)
return -1;
406 for (
const auto& root :
roots) {
407 *(out++) =
m_field.ToUint64(root);
409 return static_cast<int>(
roots.size());
Abstract class for internal representation of a minisketch object.
SketchImpl(int implementation, int bits, const Args &... args)
void Serialize(unsigned char *ptr) const override
size_t Merge(const Sketch *other_sketch) override
int Decode(int max_count, uint64_t *out) const override
void Add(uint64_t val) override
void Init(size_t count) override
void Deserialize(const unsigned char *ptr) override
size_t Syndromes() const override
std::vector< typename F::Elem > m_syndromes
void SetSeed(uint64_t seed) override
#define CHECK_RETURN(cond, rvar)
Check a condition and return on failure in non-verify builds, crash in verify builds.
#define CHECK_SAFE(cond)
Check macro that does nothing in normal non-verify builds but crashes in verify builds.
void AddToOddSyndromes(std::vector< typename F::Elem > &osyndromes, typename F::Elem data, const F &field)
bool RecFindRoots(std::vector< std::vector< typename F::Elem > > &stack, size_t pos, std::vector< typename F::Elem > &roots, bool fully_factorizable, int depth, typename F::Elem randv, const F &field)
One step of the root finding algorithm; finds roots of stack[pos] and adds them to roots.
void TraceMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &out, const typename F::Elem ¶m, const F &field)
Compute the trace map of (param*x) modulo mod, putting the result in out.
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
void GCD(std::vector< typename F::Elem > &a, std::vector< typename F::Elem > &b, const F &field)
Compute the GCD of two polynomials, putting the result in a.
std::vector< typename F::Elem > BerlekampMassey(const std::vector< typename F::Elem > &syndromes, size_t max_degree, const F &field)
F::Elem MakeMonic(std::vector< typename F::Elem > &a, const F &field)
Make a polynomial monic.
std::vector< typename F::Elem > FindRoots(const std::vector< typename F::Elem > &poly, typename F::Elem basis, const F &field)
Returns the roots of a fully factorizable polynomial.
void Sqr(std::vector< typename F::Elem > &poly, const F &field)
Square a polynomial.
void DivMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, std::vector< typename F::Elem > &div, const F &field)
Compute the quotient of a polynomial division of val by mod, putting the quotient in div and the rema...
std::vector< typename F::Elem > FullDecode(const std::vector< typename F::Elem > &osyndromes, const F &field)
std::vector< typename F::Elem > ReconstructAllSyndromes(const std::vector< typename F::Elem > &odd_syndromes, const F &field)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.