-
Notifications
You must be signed in to change notification settings - Fork 200
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
primeorder: supports only curves with a = -3
#726
Comments
The You're correct that it uses an algorithm specialized to Other values of |
It's actually can be adopted without sacrificing performance. Here I drafted a PoC that makes Let me know if you're interested in contribution, I can cover other functions as well and send a PR. |
That seems like a reasonable enough workaround for now. Anything else I can think of would require unstable Rust features like It's a breaking change, although I think we're about ready to start making breaking changes again. |
My PR draft had support for -3, 0, and general formulas (see the |
Yeah, we can experiment with various APIs prior to the next release. An enum is an option, but also (marker) traits and free functions (used to impl a trait method) are some others. |
Another design option is to have a dedicated pub trait PrimeCurveParams {
// ...
const OPTIMIZATIONS: Optimizations<Self>;
} And optimizations struct itself: pub struct Optimizations<C: PrimeCurveParams> { /* ... */ }
impl<C: PrimeCurveParams> Optimizations<C> {
/// No optimizations are enforsed
pub const fn none() -> Self { /* ... */ }
/// Specifies that coeficient `a` of curve equation equals to `-3`
pub const fn coef_a_equals_3(mut self, v: bool) -> Self {
self.a_eq_minus_3 = v;
self
}
/// Indicates whether coeficient `a` of curve equation equals to `-3`
pub const fn is_coef_a_equals_minus_3(&self) -> bool {
self.a_eq_minus_3
}
} And when implementing impl PrimeCurveParams for MyCurve {
// ...
const OPTIMIZATIONS: Optimizations<MyCurve> = Optimizations::none()
.coef_a_equals_3(true);
} I like this approach because introducing new optimization options is not a breaking change. E.g. at some point you may define optimized arithmetic for |
Generic point addition could benefit from having precomputed Optimizations struct codepub struct Optimizations<C: PrimeCurveParams> {
a_eq_minus_3: bool,
b3: Option<C::FieldElement>,
}
impl<C: PrimeCurveParams> Optimizations<C> {
/// No optimizations are enforsed
pub const fn none() -> Self {
Self{ a_eq_minus_3: false, b3: None }
}
/// Specifies that coeficient `a` of curve equation equals to `-3`
pub const fn coef_a_equals_3(mut self, v: bool) -> Self {
self.a_eq_minus_3 = v;
self
}
/// Indicates whether coeficient `a` of curve equation equals to `-3`
pub const fn is_coef_a_equals_minus_3(&self) -> bool {
self.a_eq_minus_3
}
/// Specifies `b3 = 3 * b`
pub const fn set_b3(mut self, b3: C::FieldElement) -> Self {
self.b3 = Some(b3);
self
}
/// Returns `3*b`
pub fn get_b3(&self) -> C::FieldElement {
self.b3.unwrap_or_else(|| C::EQUATION_B * C::FieldElement::from(3))
}
} I'm not saying it's necessary optimization, just giving an example how the struct could evolve |
I took a shot at implementing the trait-based approach I had in mind: #728 It adds a set of marker traits for properties of Those marker traits can be used as bounds for trait impls on I only did (a newly extracted)
|
@survived having a type or trait which holds a set of precomputed constants for optimizations is an interesting idea. I think it's already possible to do those precomputations at compile time, albeit with a macro that calls a predefined set of As it were, |
I like marker approach! It doesn't require to write those if-statements on constant expression to switch between algorithm implementation. I don't have strong preferences, I can go with any of options. I'd let you, as a code owner, decide which one I should implement in my PR. I'll start by implementing algorithms using |
It is definitely possible, it's just matter of how you retrieve this precomputed data for generic |
Went ahead and landed #728. I also added the |
primeorder
docs say that crate provides generic implementation of elliptic curve arithmetic for curves defined asHowever, I can see that$E/\mathbb{F}_q : y^2 = x^3 + a x + b$ with $a = −3$ .
ProjectivePoint::double
is implementation ofRenes-Costello-Batina 2015 (Algorithm 6)
. Paper says that Algorithm 6 is exception-free point doubling for prime order short Weierstrass curvesDo you consider eventually switching to more generic algorithms, like algorithm 3 from the same paper which doesn't require$a$ to be $-3$ ? In any case, worth mentioning in the docs that atm only $a=-3$ curves are supported to avoid confusion.
The text was updated successfully, but these errors were encountered: