-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to Montgomery representation #663
base: main
Are you sure you want to change the base?
Changes from 23 commits
0c7df67
5f29239
79cd3de
779babe
6a8793b
df45d69
0f3275e
9cdb4bd
21d97d4
4dbbd72
b2533cd
c979161
87ae5ff
2c8e2ad
c53e3db
4282114
7f5345b
a738a41
7ae18a5
c923e6e
5745d8c
258f0ef
01c5143
9d4394c
1172cec
95e92ff
620a4ae
54abe47
30f93a3
1f1c7c0
1d7e819
208dfb6
bc84c83
61c65a5
09cca99
9cd3506
2b6889e
c4ff934
eefa062
507ee38
3dc6154
58a2cda
2c7c379
2727e07
997145f
d978869
a345010
ceb1f3e
a005854
b2aaff6
68f4326
ed7aef4
2d3075b
820ee9e
a880d5d
613b744
686d3cd
a2a8372
963349d
740c3f4
f757986
1a4e6c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -451,9 +451,13 @@ void Msm<A, P>::phase1_bucket_accumulator(const scalar_t* scalars, const A* base | |||||
bool negate_p_and_s = scalar.get_scalar_digit(scalar_t::NBITS - 1, 1) > 0; | ||||||
if (negate_p_and_s) { scalar = scalar_t::neg(scalar); } | ||||||
for (int j = 0; j < m_precompute_factor; j++) { | ||||||
// Handle required preprocess of base P | ||||||
// Handle required preprocess of base P according to the version of Field/Ec adder (accepting Barret / Montgomery) | ||||||
A base = | ||||||
#ifdef BARRET | ||||||
m_are_points_mont ? A::from_montgomery(bases[m_precompute_factor * i + j]) : bases[m_precompute_factor * i + j]; | ||||||
#else | ||||||
m_are_points_mont ? bases[m_precompute_factor * i + j] : A::to_montgomery(bases[m_precompute_factor * i + j]); | ||||||
#endif | ||||||
if (base == A::zero()) { continue; } | ||||||
if (negate_p_and_s) { base = A::neg(base); } | ||||||
|
||||||
|
@@ -780,12 +784,23 @@ eIcicleError cpu_msm_precompute_bases( | |||||
const unsigned int shift = c * ((num_bms_no_precomp - 1) / precompute_factor + 1); | ||||||
for (int i = 0; i < nof_bases; i++) { | ||||||
output_bases[precompute_factor * i] = input_bases[i]; | ||||||
P point = P::from_affine(is_mont ? A::from_montgomery(input_bases[i]) : input_bases[i]); | ||||||
// Handle required preprocess of base P according to the version of Field/Ec adder (accepting Barret / Montgomery) | ||||||
P point = | ||||||
#ifdef BARRET | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe the degredation in performance comes from the Z=1 when moving from affine to projectve? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Degradation in the precompute? |
||||||
P::from_affine(is_mont ? A::from_montgomery(input_bases[i]) : input_bases[i]); | ||||||
#else | ||||||
P::from_affine(is_mont ? input_bases[i] : A::to_montgomery(input_bases[i])); | ||||||
#endif | ||||||
for (int j = 1; j < precompute_factor; j++) { | ||||||
for (int k = 0; k < shift; k++) { | ||||||
point = P::dbl(point); | ||||||
} | ||||||
output_bases[precompute_factor * i + j] = is_mont ? A::to_montgomery(P::to_affine(point)) : P::to_affine(point); | ||||||
output_bases[precompute_factor * i + j] = | ||||||
#ifdef BARRET | ||||||
is_mont ? A::to_montgomery(P::to_affine(point)) : P::to_affine(point); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
#else | ||||||
is_mont ? P::to_affine(point) : A::from_montgomery(P::to_affine(point)); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
#endif | ||||||
} | ||||||
} | ||||||
return eIcicleError::SUCCESS; | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,14 @@ class Projective | |
return {FF::from_montgomery(point.x), FF::from_montgomery(point.y), FF::from_montgomery(point.z)}; | ||
} | ||
|
||
#ifdef BARRET | ||
static HOST_DEVICE_INLINE Projective generator() { return {Gen::gen_x, Gen::gen_y, FF::one()}; } | ||
#else | ||
static HOST_DEVICE_INLINE Projective generator() | ||
{ | ||
return {FF::to_montgomery(Gen::gen_x), FF::to_montgomery(Gen::gen_y), FF::one()}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't we get gen_x, gen_y from the Field as constants? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can, it just means we need to change all the parameters in all the fields manually. This function is only called for testing so I thought this solution is good enough, but we can do it differently. |
||
} | ||
#endif | ||
|
||
static HOST_DEVICE_INLINE Projective neg(const Projective& point) { return {point.x, FF::neg(point.y), point.z}; } | ||
|
||
|
@@ -179,6 +186,10 @@ class Projective | |
|
||
friend HOST_DEVICE Projective operator*(SCALAR_FF scalar, const Projective& point) | ||
{ | ||
#ifndef BARRET | ||
scalar = SCALAR_FF::from_montgomery(scalar); | ||
#endif | ||
Comment on lines
+199
to
+201
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we want to convert from mont here if BARRET isn't defined? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the double and add algorithm requires barret representation, same for msm |
||
|
||
// Precompute points: P, 2P, ..., (2^window_size - 1)P | ||
constexpr unsigned window_size = | ||
4; // 4 seems fastest. Optimum is minimizing EC add and depends on the field size. for 256b it's 4. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,12 +48,12 @@ class ComplexExtensionField | |
|
||
static constexpr HOST_DEVICE_INLINE ComplexExtensionField to_montgomery(const ComplexExtensionField& xs) | ||
{ | ||
return ComplexExtensionField{xs.real * FF{CONFIG::montgomery_r}, xs.imaginary * FF{CONFIG::montgomery_r}}; | ||
return ComplexExtensionField{FF::to_montgomery(xs.real), FF::to_montgomery(xs.imaginary)}; | ||
} | ||
|
||
static constexpr HOST_DEVICE_INLINE ComplexExtensionField from_montgomery(const ComplexExtensionField& xs) | ||
{ | ||
return ComplexExtensionField{xs.real * FF{CONFIG::montgomery_r_inv}, xs.imaginary * FF{CONFIG::montgomery_r_inv}}; | ||
return ComplexExtensionField{FF::from_montgomery(xs.real), FF::from_montgomery(xs.imaginary)}; | ||
} | ||
|
||
static HOST_INLINE ComplexExtensionField rand_host() | ||
|
@@ -128,17 +128,14 @@ class ComplexExtensionField | |
return ExtensionWide{FF::mul_wide(xs.real, ys), FF::mul_wide(xs.imaginary, ys)}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can remove the template also here |
||
} | ||
|
||
template <unsigned MODULUS_MULTIPLE = 1> | ||
static constexpr HOST_DEVICE_INLINE ExtensionWide mul_wide(const FF& xs, const ComplexExtensionField& ys) | ||
{ | ||
return mul_wide(ys, xs); | ||
} | ||
|
||
template <unsigned MODULUS_MULTIPLE = 1> | ||
static constexpr HOST_DEVICE_INLINE ComplexExtensionField reduce(const ExtensionWide& xs) | ||
{ | ||
return ComplexExtensionField{ | ||
FF::template reduce<MODULUS_MULTIPLE>(xs.real), FF::template reduce<MODULUS_MULTIPLE>(xs.imaginary)}; | ||
return ComplexExtensionField{FF::reduce(xs.real), FF::reduce(xs.imaginary)}; | ||
} | ||
|
||
template <class T1, class T2> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what the address sanitizer got to do with the BARRET?