Skip to content

Commit 1d3aab1

Browse files
improve CIOS implementation
1 parent 4a3cb41 commit 1d3aab1

1 file changed

Lines changed: 37 additions & 15 deletions

File tree

include/evmmax/evmmax.hpp

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,48 @@ class ModArith
8383
// Based on 2.3.2 from
8484
// High-Speed Algorithms & Architectures For Number-Theoretic Cryptosystems
8585
// https://www.microsoft.com/en-us/research/wp-content/uploads/1998/06/97Acar.pdf
86+
// and on 2.2 from
87+
// EdMSM: Multi-Scalar-Multiplication for SNARKs and Faster Montgomery multiplication
88+
// https://eprint.iacr.org/2022/1400.pdf
8689

90+
constexpr uint64_t most_significant_mod_word_limit {std::numeric_limits<uint64_t>::max() >> 1};
8791
constexpr auto S = UintT::num_words; // TODO(C++23): Make it static
8892

8993
intx::uint<UintT::num_bits + 64> t;
90-
for (size_t i = 0; i != S; ++i)
94+
if (mod[S - 1] < most_significant_mod_word_limit)
9195
{
92-
uint64_t c = 0;
93-
for (size_t j = 0; j != S; ++j)
94-
std::tie(c, t[j]) = addmul(t[j], x[j], y[i], c);
95-
auto tmp = intx::addc(t[S], c);
96-
t[S] = tmp.value;
97-
const auto d = tmp.carry; // TODO: Carry is 0 for sparse modulus.
98-
99-
const auto m = t[0] * m_mod_inv;
100-
std::tie(c, std::ignore) = addmul(t[0], m, mod[0], 0);
101-
for (size_t j = 1; j != S; ++j)
102-
std::tie(c, t[j - 1]) = addmul(t[j], m, mod[j], c);
103-
tmp = intx::addc(t[S], c);
104-
t[S - 1] = tmp.value;
105-
t[S] = d + tmp.carry; // TODO: Carry is 0 for sparse modulus.
96+
for (size_t i = 0; i != S; ++i)
97+
{
98+
uint64_t c = 0;
99+
for (size_t j = 0; j != S; ++j)
100+
std::tie(c, t[j]) = addmul(t[j], x[j], y[i], c);
101+
auto const c_2 = c;
102+
const auto m = t[0] * m_mod_inv;
103+
std::tie(c, std::ignore) = addmul(t[0], m, mod[0], 0);
104+
for (size_t j = 1; j != S; ++j)
105+
std::tie(c, t[j - 1]) = addmul(t[j], m, mod[j], c);
106+
t[S - 1] = c_2 + c;
107+
}
108+
}
109+
else
110+
{
111+
for (size_t i = 0; i != S; ++i)
112+
{
113+
uint64_t c = 0;
114+
for (size_t j = 0; j != S; ++j)
115+
std::tie(c, t[j]) = addmul(t[j], x[j], y[i], c);
116+
auto tmp = intx::addc(t[S], c);
117+
t[S] = tmp.value;
118+
const auto d = tmp.carry; // TODO: Carry is 0 for sparse modulus.
119+
120+
const auto m = t[0] * m_mod_inv;
121+
std::tie(c, std::ignore) = addmul(t[0], m, mod[0], 0);
122+
for (size_t j = 1; j != S; ++j)
123+
std::tie(c, t[j - 1]) = addmul(t[j], m, mod[j], c);
124+
tmp = intx::addc(t[S], c);
125+
t[S - 1] = tmp.value;
126+
t[S] = d + tmp.carry; // TODO: Carry is 0 for sparse modulus.
127+
}
106128
}
107129

108130
if (t >= mod)

0 commit comments

Comments
 (0)