Skip to content

Commit b693f02

Browse files
improve CIOS implementation
1 parent 01eca77 commit b693f02

1 file changed

Lines changed: 36 additions & 15 deletions

File tree

include/evmmax/evmmax.hpp

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,47 @@ 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

8790
constexpr auto S = UintT::num_words; // TODO(C++23): Make it static
8891

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

108129
if (t >= mod)

0 commit comments

Comments
 (0)