-
Notifications
You must be signed in to change notification settings - Fork 256
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
SW <-> TE map for Bandersnatch #804
base: master
Are you sure you want to change the base?
Changes from all commits
d1e4df8
9bb1d78
cbb9bca
eca7035
aadd4b9
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 | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,12 +1,11 @@ | ||||||||||||||||
use crate::{Fq, Fr}; | ||||||||||||||||
use ark_ec::{ | ||||||||||||||||
hashing::curve_maps::elligator2::Elligator2Config, | ||||||||||||||||
models::CurveConfig, | ||||||||||||||||
short_weierstrass::{self, SWCurveConfig}, | ||||||||||||||||
twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig}, | ||||||||||||||||
}; | ||||||||||||||||
use ark_ff::{AdditiveGroup, MontFp}; | ||||||||||||||||
|
||||||||||||||||
use crate::{Fq, Fr}; | ||||||||||||||||
use ark_ff::{AdditiveGroup, Field, MontFp, One}; | ||||||||||||||||
|
||||||||||||||||
#[cfg(test)] | ||||||||||||||||
mod tests; | ||||||||||||||||
|
@@ -163,6 +162,77 @@ impl Elligator2Config for BandersnatchConfig { | |||||||||||||||
MontFp!("22511181562295907836254750456843438087744031914659733450388350895537307167857"); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
// Constants used in mapping TE form to SW form and vice versa | ||||||||||||||||
// | ||||||||||||||||
// sage: q = 52435875175126190479447740508185965837690552500527637822603658699938581184513 | ||||||||||||||||
// sage: Fq = GF(q) | ||||||||||||||||
// sage: MONT_A = 29978822694968839326280996386011761570173833766074948509196803838190355340952 | ||||||||||||||||
// sage: MONT_B = 25465760566081946422412445027709227188579564747101592991722834452325077642517 | ||||||||||||||||
// sage: MONT_A/Fq(3) | ||||||||||||||||
// 9992940898322946442093665462003920523391277922024982836398934612730118446984 | ||||||||||||||||
// sage: Fq(1)/MONT_B | ||||||||||||||||
// 41180284393978236561320365279764246793818536543197771097409483252169927600582 | ||||||||||||||||
const MONT_A_OVER_THREE: Fq = | ||||||||||||||||
MontFp!("9992940898322946442093665462003920523391277922024982836398934612730118446984"); | ||||||||||||||||
const MONT_B_INV: Fq = | ||||||||||||||||
MontFp!("41180284393978236561320365279764246793818536543197771097409483252169927600582"); | ||||||||||||||||
|
||||||||||||||||
impl BandersnatchConfig { | ||||||||||||||||
/// Map an point in TE form to its corresponding point on SW curve | ||||||||||||||||
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
|
||||||||||||||||
pub fn map_te_to_sw(point: EdwardsAffine) -> Option<SWAffine> { | ||||||||||||||||
//First we map the point from the TE to Montgamory | ||||||||||||||||
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
|
||||||||||||||||
//edward to mont ((1+y)/(1-y), (1+y)/(x(1-y))) | ||||||||||||||||
let v_denom = <<BandersnatchConfig as CurveConfig>::BaseField as One>::one() - point.y; | ||||||||||||||||
let w_denom = point.x - point.x * point.y; | ||||||||||||||||
|
||||||||||||||||
let v_denom_inv = v_denom.inverse()?; | ||||||||||||||||
let w_denom_inv = w_denom.inverse()?; | ||||||||||||||||
|
||||||||||||||||
let v_w_num = <<BandersnatchConfig as CurveConfig>::BaseField as One>::one() + point.y; | ||||||||||||||||
|
||||||||||||||||
let v = v_w_num * v_denom_inv; | ||||||||||||||||
let w = v_w_num * w_denom_inv; | ||||||||||||||||
|
||||||||||||||||
//now we are mappyng the montgamory point to SW. | ||||||||||||||||
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
|
||||||||||||||||
//Mont->SW ((x+A/3)/B,y/B) | ||||||||||||||||
|
||||||||||||||||
let x = MONT_B_INV * (v + MONT_A_OVER_THREE); | ||||||||||||||||
let y = MONT_B_INV * w; | ||||||||||||||||
|
||||||||||||||||
let point_on_sw_curve = SWAffine::new_unchecked(x, y); | ||||||||||||||||
debug_assert!( | ||||||||||||||||
point_on_sw_curve.is_on_curve(), | ||||||||||||||||
"TE point mapped off the SW curve" | ||||||||||||||||
); | ||||||||||||||||
Comment on lines
+203
to
+206
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. I'd probably play it safe here and use |
||||||||||||||||
|
||||||||||||||||
return Some(point_on_sw_curve); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
pub fn map_sw_to_te(point: SWAffine) -> Option<EdwardsAffine> { | ||||||||||||||||
//first we are mappyng the sw point to montgamory 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.
Suggested change
|
||||||||||||||||
//SW->Mont by (Bx−A/3,By) | ||||||||||||||||
let mx = <BandersnatchConfig as MontCurveConfig>::COEFF_B * point.x - MONT_A_OVER_THREE; | ||||||||||||||||
let my = <BandersnatchConfig as MontCurveConfig>::COEFF_B * point.y; | ||||||||||||||||
|
||||||||||||||||
//Then we map the TE point to Montgamory | ||||||||||||||||
// (x,y)↦(x/y,(x−1)/(x+1)) | ||||||||||||||||
let v_denom = my.inverse()?; | ||||||||||||||||
let x_p_1 = mx + <<BandersnatchConfig as CurveConfig>::BaseField as One>::one(); | ||||||||||||||||
let w_denom = x_p_1.inverse()?; | ||||||||||||||||
|
||||||||||||||||
let v = mx * v_denom; | ||||||||||||||||
let w = (mx - <<BandersnatchConfig as CurveConfig>::BaseField as One>::one()) * w_denom; | ||||||||||||||||
|
||||||||||||||||
let point_on_te_curve = EdwardsAffine::new_unchecked(v, w); | ||||||||||||||||
debug_assert!( | ||||||||||||||||
point_on_te_curve.is_on_curve(), | ||||||||||||||||
"TE point mapped off the SW curve" | ||||||||||||||||
); | ||||||||||||||||
Comment on lines
+226
to
+230
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. Same comment as above: consider using |
||||||||||||||||
|
||||||||||||||||
return Some(point_on_te_curve); | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
#[cfg(test)] | ||||||||||||||||
mod test { | ||||||||||||||||
use super::*; | ||||||||||||||||
|
@@ -189,4 +259,64 @@ mod test { | |||||||||||||||
"hash results into a point off the curve" | ||||||||||||||||
); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
#[test] | ||||||||||||||||
fn test_mapping_from_te_to_sw_curve() { | ||||||||||||||||
let test_elligator2_to_curve_hasher = MapToCurveBasedHasher::< | ||||||||||||||||
Projective<BandersnatchConfig>, | ||||||||||||||||
DefaultFieldHasher<Sha512, 128>, | ||||||||||||||||
Elligator2Map<BandersnatchConfig>, | ||||||||||||||||
>::new(&[1]) | ||||||||||||||||
.unwrap(); | ||||||||||||||||
|
||||||||||||||||
let hash_result = test_elligator2_to_curve_hasher.hash(b"if you stick a Babel fish in your ear you can instantly understand anything said to you in any form of language.").expect("fail to hash the string to curve"); | ||||||||||||||||
|
||||||||||||||||
assert!( | ||||||||||||||||
hash_result.is_on_curve(), | ||||||||||||||||
"hash results into a point off the curve" | ||||||||||||||||
); | ||||||||||||||||
|
||||||||||||||||
assert!( | ||||||||||||||||
BandersnatchConfig::map_te_to_sw(hash_result) | ||||||||||||||||
.expect("could not map the te point to sw form") | ||||||||||||||||
.is_on_curve(), | ||||||||||||||||
"hash results into a point off the curve" | ||||||||||||||||
); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
#[test] | ||||||||||||||||
fn test_mapping_from_te_to_sw_to_te_curve() { | ||||||||||||||||
let test_elligator2_to_curve_hasher = MapToCurveBasedHasher::< | ||||||||||||||||
Projective<BandersnatchConfig>, | ||||||||||||||||
DefaultFieldHasher<Sha512, 128>, | ||||||||||||||||
Elligator2Map<BandersnatchConfig>, | ||||||||||||||||
>::new(&[1]) | ||||||||||||||||
.unwrap(); | ||||||||||||||||
|
||||||||||||||||
let hash_result = test_elligator2_to_curve_hasher.hash(b"if you stick a Babel fish in your ear you can instantly understand anything said to you in any form of language.").expect("fail to hash the string to curve"); | ||||||||||||||||
|
||||||||||||||||
assert!( | ||||||||||||||||
hash_result.is_on_curve(), | ||||||||||||||||
"hash results into a point off the curve" | ||||||||||||||||
); | ||||||||||||||||
|
||||||||||||||||
let sw_point = BandersnatchConfig::map_te_to_sw(hash_result) | ||||||||||||||||
.expect("could not map the te point to sw form"); | ||||||||||||||||
assert!( | ||||||||||||||||
sw_point.is_on_curve(), | ||||||||||||||||
"hash results into a point off the curve" | ||||||||||||||||
); | ||||||||||||||||
|
||||||||||||||||
let te_point = BandersnatchConfig::map_sw_to_te(sw_point) | ||||||||||||||||
.expect("could not map the te point to sw form"); | ||||||||||||||||
assert!( | ||||||||||||||||
te_point.is_on_curve(), | ||||||||||||||||
"hash results into a point off the curve" | ||||||||||||||||
); | ||||||||||||||||
|
||||||||||||||||
assert!( | ||||||||||||||||
te_point == hash_result, | ||||||||||||||||
"point mapped to sw form was re-mapped to a different point on te form" | ||||||||||||||||
); | ||||||||||||||||
} | ||||||||||||||||
} |
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.
(since the PR is from an organization, I cannot edit directly)