-
Notifications
You must be signed in to change notification settings - Fork 14
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
refactor(fiat-crypto): Inversion #66
Conversation
We should avoid editing the generated code, and only write wrappers around it. Otherwise, if we ever need to regenerate, we won't be able to apply the changes cleanly. This is kind of annoying to work around, considering that the generated code generates C-style APIs, but it's important for long-term maintainability and verifiability. |
agreed, fixed! |
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.
thanks for taking this on!
src/fields/u32/fp/wrapper.rs
Outdated
let mut d = 1; | ||
let mut f: [u32; 13] = [0u32; 13]; | ||
fiat::fp_msat(&mut f); | ||
let mut g = [0u32; 13]; |
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.
I think it might be clearer in these inversion methods to define a constant N_LIMBS
so it's clear that e.g. 13 is N_LIMBS + 1
, 12 is N_LIMBS
, etc.
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.
added global constants NUM_LIMBS
and PRIME_ORDER
src/fields/u32/fp/wrapper.rs
Outdated
let mut i = 0; | ||
let mut j = 0; | ||
|
||
while j < 6 { |
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.
I think this should be 12 instead of 6 (to review I was comparing with the impl_bernstein_yang_invert
macro where j goes up to n_limbs
)
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.
This is a good catch! Fixed by changing limbs to a constant.
src/fields/u32/fp/wrapper.rs
Outdated
use super::*; | ||
|
||
#[test] | ||
fn inversion_test() { |
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.
It would be cool if these were proptests i.e. something like:
fn fp_strategy() -> BoxedStrategy<Fp> {
any::<[u8; 48]>()
.prop_map(|bytes| Fp::from_bytes(&bytes))
.boxed()
}
proptest! {
#[test]
fn inversion_proptest(element in fp_strategy().prop_filter("Non-zero element", |e| e != &Fp::zero())) {
let inverse = element.inverse().unwrap();
assert_eq!(element.mul(inverse), Fp::one());
}
}
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.
Good point. In #67, we implement a proptest for inversion, but I'll include this test as well.
Per the recent indexing changes (packing two @cronokirby let's carry over the inversion proptest to |
References #65.
Referenced BLS12-377 curve construction parameters from ZEXE paper (
p.44
). Retrieved BLS12-377 twisted edwards curve construction parameters from here.Note: I slightly modified the input bounds of the fiat-generated
divstep
to make the output bounds explicitly return. This is merely a semantic change that simplifies the iterations in theinverse
function.Update: This change has been reverted.