-
Notifications
You must be signed in to change notification settings - Fork 59
feat: twisted edwards curves #633
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
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for contracts-stylus canceled.
|
Codecov ReportAttention: Patch coverage is
✅ All tests successful. No failed tests found. Additional details and impacted files
|
…wisted-edwards-curves
lib/crypto/src/curve/te/mod.rs
Outdated
/// Checks that the current point is in the prime order subgroup given | ||
/// the point on the curve. | ||
fn is_in_correct_subgroup_assuming_on_curve(item: &Affine<Self>) -> bool { | ||
Self::mul_affine(item, Self::ScalarField::characteristic()).is_zero() | ||
} |
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.
/// Checks that the current point is in the prime order subgroup given | |
/// the point on the curve. | |
fn is_in_correct_subgroup_assuming_on_curve(item: &Affine<Self>) -> bool { | |
Self::mul_affine(item, Self::ScalarField::characteristic()).is_zero() | |
} | |
/// Checks that the current point is in the prime order subgroup given | |
/// the point on the curve. | |
fn is_in_prime_order_subgroup(item: &Affine<Self>) -> bool { | |
Self::mul_affine(item, Self::ScalarField::characteristic()).is_zero() | |
} |
Judging by docs, it seems that this is what it's checking
fn xy(&self) -> Option<(Self::BaseField, Self::BaseField)> { | ||
(!self.is_zero()).then_some((self.x, self.y)) | ||
} |
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.
Why do you think it's better to return None
for zero than to return actual zero tuple ((P::BaseField::ZERO, P::BaseField::ONE)
)?
// See "Twisted Edwards Curves Revisited" | ||
// Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, and Ed Dawson | ||
// 3.3 Doubling in E^e | ||
// Source: https://www.hyperelliptic.org/EFD/g1p/data/twisted/extended/doubling/dbl-2008-hwcd |
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.
Better to put this comment above as fn docs
fn add_assign(&mut self, other: T) { | ||
let other = other.borrow(); | ||
// See "Twisted Edwards Curves Revisited" | ||
// Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, and Ed Dawson | ||
// 3.1 Unified Addition in E^e | ||
// Source: https://www.hyperelliptic.org/EFD/g1p/data/twisted/extended/addition/madd-2008-hwcd | ||
|
||
// A = X1*X2 | ||
let a = self.x * other.x; | ||
// B = Y1*Y2 | ||
let b = self.y * other.y; | ||
// C = T1*d*T2 | ||
let c = P::COEFF_D * self.t * other.x * other.y; | ||
|
||
// D = Z1 | ||
let d = self.z; | ||
// E = (X1+Y1)*(X2+Y2)-A-B | ||
let e = (self.x + self.y) * (other.x + other.y) - a - b; | ||
// F = D-C | ||
let f = d - c; | ||
// G = D+C | ||
let g = d + c; | ||
// H = B-a*A | ||
let h = b - P::mul_by_a(a); | ||
// X3 = E*F | ||
self.x = e * f; | ||
// Y3 = G*H | ||
self.y = g * h; | ||
// T3 = E*H | ||
self.t = e * h; | ||
// Z3 = F*G | ||
self.z = f * g; |
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.
Same question as before for comments
// See "Twisted Edwards Curves Revisited" (https://eprint.iacr.org/2008/522.pdf) | ||
// by Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, and Ed Dawson | ||
// 3.1 Unified Addition in E^e | ||
|
||
// A = x1 * x2 | ||
let a = self.x * other.x; | ||
|
||
// B = y1 * y2 | ||
let b = self.y * other.y; | ||
|
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.
Same question as before for comments
|
||
impl_additive_ops_from_ref!(Projective, TECurveConfig); | ||
|
||
impl<'a, P: TECurveConfig> Add<&'a Self> for Projective<P> { |
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.
Would it make sense to implement ref + ref
?
/// | ||
/// * If point is not on curve. | ||
/// * If point is not in the prime-order subgroup. | ||
pub fn new(x: P::BaseField, y: P::BaseField) -> Self { |
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.
Some general comments:
- could any of the new functions be marked with
inline(always)
ormust_use
? - some flows are not covered with unit tests
- could we implement any proptests for this?
- missing CHANGELOG
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.
Agree with @0xNeshi 💯
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.
Almost looks good, take care of @0xNeshi comments please.
/// | ||
/// * If point is not on curve. | ||
/// * If point is not in the prime-order subgroup. | ||
pub fn new(x: P::BaseField, y: P::BaseField) -> Self { |
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.
Agree with @0xNeshi 💯
lib/crypto/src/curve/te/mod.rs
Outdated
} | ||
|
||
/// Default implementation of group multiplication for projective | ||
/// coordinates |
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.
/// coordinates | |
/// coordinates. |
} | ||
|
||
/// Default implementation of group multiplication for affine | ||
/// coordinates |
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.
/// coordinates | |
/// coordinates. |
|
||
batch_inversion(&mut z_s); | ||
|
||
// Perform affine transformations |
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.
// Perform affine transformations | |
// Perform affine transformations. |
fn normalize_batch(v: &[Self]) -> Vec<Self::Affine> { | ||
// A projective curve element (x, y, t, z) is normalized | ||
// to its affine representation, by the conversion | ||
// (x, y, t, z) -> (x/z, y/z, t/z, 1) |
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.
// (x, y, t, z) -> (x/z, y/z, t/z, 1) | |
// (x, y, t, z) -> (x/z, y/z, t/z, 1). |
// (x, y, t, z) -> (x/z, y/z, t/z, 1) | ||
// Batch normalizing N twisted edwards curve elements costs: | ||
// 1 inversion + 6N field multiplications | ||
// (batch inversion requires 3N multiplications + 1 inversion) |
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.
// (batch inversion requires 3N multiplications + 1 inversion) | |
// (batch inversion requires 3N multiplications + 1 inversion). |
Follows #589
PR Checklist