24constexpr limb_t MAX_PRIME_DIFF = 1103717;
30inline void extract3(limb_t &c0, limb_t &c1, limb_t &c2, limb_t &n) {
38inline void mul(limb_t &c0, limb_t &c1,
const limb_t &a,
const limb_t &b) {
39 double_limb_t t = (double_limb_t)a * b;
45inline void mulnadd3(limb_t &c0, limb_t &c1, limb_t &c2, limb_t &d0, limb_t &d1,
46 limb_t &d2,
const limb_t &n) {
47 double_limb_t t = (double_limb_t)d0 * n + c0;
50 t += (double_limb_t)d1 * n + c1;
57inline void muln2(limb_t &c0, limb_t &c1,
const limb_t &n) {
58 double_limb_t t = (double_limb_t)c0 * n;
61 t += (double_limb_t)c1 * n;
66inline void muladd3(limb_t &c0, limb_t &c1, limb_t &c2,
const limb_t &a,
68 double_limb_t t = (double_limb_t)a * b;
69 limb_t th = t >> LIMB_SIZE;
73 th += (c0 < tl) ? 1 : 0;
75 c2 += (c1 < th) ? 1 : 0;
79inline void muldbladd3(limb_t &c0, limb_t &c1, limb_t &c2,
const limb_t &a,
81 double_limb_t t = (double_limb_t)a * b;
82 limb_t th = t >> LIMB_SIZE;
86 limb_t tt = th + ((c0 < tl) ? 1 : 0);
88 c2 += (c1 < tt) ? 1 : 0;
90 th += (c0 < tl) ? 1 : 0;
92 c2 += (c1 < th) ? 1 : 0;
99inline void addnextract2(limb_t &c0, limb_t &c1,
const limb_t &a, limb_t &n) {
120inline void square_n_mul(
Num3072 &in_out,
const int sq,
const Num3072 &mul) {
121 for (
int j = 0; j < sq; ++j) {
131 if (this->
limbs[0] <= std::numeric_limits<limb_t>::max() - MAX_PRIME_DIFF) {
134 for (
int i = 1; i <
LIMBS; ++i) {
135 if (this->
limbs[i] != std::numeric_limits<limb_t>::max()) {
143 limb_t c0 = MAX_PRIME_DIFF;
145 for (
int i = 0; i <
LIMBS; ++i) {
146 addnextract2(c0, c1, this->
limbs[i], this->
limbs[i]);
160 for (
int i = 0; i < 11; ++i) {
162 for (
int j = 0; j < (1 << i); ++j) {
172 square_n_mul(out, 512, p[9]);
173 square_n_mul(out, 256, p[8]);
174 square_n_mul(out, 128, p[7]);
175 square_n_mul(out, 64, p[6]);
176 square_n_mul(out, 32, p[5]);
177 square_n_mul(out, 8, p[3]);
178 square_n_mul(out, 2, p[1]);
179 square_n_mul(out, 1, p[0]);
180 square_n_mul(out, 5, p[2]);
181 square_n_mul(out, 3, p[0]);
182 square_n_mul(out, 2, p[0]);
183 square_n_mul(out, 4, p[0]);
184 square_n_mul(out, 4, p[1]);
185 square_n_mul(out, 3, p[0]);
191 limb_t c0 = 0, c1 = 0, c2 = 0;
195 for (
int j = 0; j <
LIMBS - 1; ++j) {
196 limb_t d0 = 0, d1 = 0, d2 = 0;
198 for (
int i = 2 + j; i <
LIMBS; ++i) {
201 mulnadd3(c0, c1, c2, d0, d1, d2, MAX_PRIME_DIFF);
202 for (
int i = 0; i < j + 1; ++i) {
203 muladd3(c0, c1, c2, this->
limbs[i], a.
limbs[j - i]);
205 extract3(c0, c1, c2, tmp.
limbs[j]);
210 for (
int i = 0; i <
LIMBS; ++i) {
216 muln2(c0, c1, MAX_PRIME_DIFF);
217 for (
int j = 0; j <
LIMBS; ++j) {
218 addnextract2(c0, c1, tmp.
limbs[j], this->limbs[j]);
222 assert(c0 == 0 || c0 == 1);
238 limb_t c0 = 0, c1 = 0, c2 = 0;
242 for (
int j = 0; j <
LIMBS - 1; ++j) {
243 limb_t d0 = 0, d1 = 0, d2 = 0;
244 for (
int i = 0; i < (
LIMBS - 1 - j) / 2; ++i) {
245 muldbladd3(d0, d1, d2, this->
limbs[i + j + 1],
246 this->
limbs[LIMBS - 1 - i]);
249 muladd3(d0, d1, d2, this->
limbs[(LIMBS - 1 - j) / 2 + j + 1],
250 this->
limbs[LIMBS - 1 - (
LIMBS - 1 - j) / 2]);
252 mulnadd3(c0, c1, c2, d0, d1, d2, MAX_PRIME_DIFF);
253 for (
int i = 0; i < (j + 1) / 2; ++i) {
254 muldbladd3(c0, c1, c2, this->
limbs[i], this->
limbs[j - i]);
257 muladd3(c0, c1, c2, this->
limbs[(j + 1) / 2],
258 this->
limbs[j - (j + 1) / 2]);
260 extract3(c0, c1, c2, tmp.
limbs[j]);
264 for (
int i = 0; i <
LIMBS / 2; ++i) {
265 muldbladd3(c0, c1, c2, this->
limbs[i], this->
limbs[LIMBS - 1 - i]);
270 muln2(c0, c1, MAX_PRIME_DIFF);
271 for (
int j = 0; j <
LIMBS; ++j) {
272 addnextract2(c0, c1, tmp.
limbs[j], this->limbs[j]);
276 assert(c0 == 0 || c0 == 1);
293 for (
int i = 1; i <
LIMBS; ++i) {
319 for (
int i = 0; i <
LIMBS; ++i) {
320 if (
sizeof(
limb_t) == 4) {
322 }
else if (
sizeof(
limb_t) == 8) {
329 for (
int i = 0; i <
LIMBS; ++i) {
330 if (
sizeof(
limb_t) == 4) {
332 }
else if (
sizeof(
limb_t) == 8) {
342 ChaCha20(hashed_in.data(), hashed_in.size())
350 m_numerator = ToNum3072(in);
354 m_numerator.Divide(m_denominator);
356 m_denominator.SetToOne();
359 m_numerator.ToBytes(data);
365 m_numerator.Multiply(mul.m_numerator);
366 m_denominator.Multiply(mul.m_denominator);
371 m_numerator.Multiply(div.m_denominator);
372 m_denominator.Multiply(div.m_numerator);
377 m_numerator.Multiply(ToNum3072(in));
382 m_denominator.Multiply(ToNum3072(in));
A class for ChaCha20 256-bit stream cipher developed by Daniel J.
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
A writer stream (for serialization) that computes a 256-bit hash.
A class representing MuHash sets.
Num3072 ToNum3072(Span< const uint8_t > in)
MuHash3072 & Remove(Span< const uint8_t > in) noexcept
void Finalize(uint256 &out) noexcept
MuHash3072 & operator/=(const MuHash3072 &div) noexcept
MuHash3072 & Insert(Span< const uint8_t > in) noexcept
MuHash3072 & operator*=(const MuHash3072 &mul) noexcept
Num3072 GetInverse() const
static constexpr int LIMBS
static constexpr size_t BYTE_SIZE
bool IsOverflow() const
Indicates whether d is larger than the modulus.
void ToBytes(uint8_t(&out)[BYTE_SIZE])
static constexpr int LIMB_SIZE
void Divide(const Num3072 &a)
void Multiply(const Num3072 &a)
static void WriteLE32(uint8_t *ptr, uint32_t x)
static uint64_t ReadLE64(const uint8_t *ptr)
static uint32_t ReadLE32(const uint8_t *ptr)
static void WriteLE64(uint8_t *ptr, uint64_t x)