Skip to content
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

Add Wahby-Boneh hash-to-curve #343

Merged
merged 154 commits into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
154 commits
Select commit Hold shift + click to select a range
377f4a8
ec: Add HashToCurve trait and svw hash
ValarDragon Dec 19, 2020
354fc96
Update traits
ValarDragon Dec 19, 2020
73185bc
Fix lint
ValarDragon Dec 19, 2020
71b17cf
Update HashToField API to match draft
ValarDragon Dec 19, 2020
809b1e1
Update FieldHasher interfaces
ValarDragon Dec 22, 2020
7bcfdf1
Merge branch 'master' into hash_to_curve
ValarDragon Dec 23, 2020
7f7ef6d
Refactor file, progress on hash to field
ValarDragon Dec 28, 2020
a03626d
Update hashing code structure
ValarDragon Dec 28, 2020
6791b65
Fix lint
ValarDragon Dec 28, 2020
68c99ee
Merge branch 'master' into hash_to_curve
ValarDragon Dec 28, 2020
ac387cb
Merge branch 'master' into hash_to_curve
ValarDragon Feb 3, 2021
50d5e33
Add Hash to Field (untested)
ValarDragon Feb 3, 2021
b0aa9d2
First implementation for the simple swu map to curve
drskalman Aug 28, 2021
9f228be
Merge remote-tracking branch 'upstream/master' into hash_to_curve_swu
drskalman Aug 28, 2021
6fc0fa3
fixed some basic error in hash to curve module so it can be compiled.
drskalman Aug 28, 2021
1c61897
removing mistakenly commited editor temps backup.
drskalman Aug 28, 2021
65e45b8
Some syntax and dependancy fixing
drskalman Aug 29, 2021
1c85dcd
Some more error and syntax clean up. Working toward a working test.
drskalman Aug 31, 2021
11dc264
fixes #2
drskalman Aug 31, 2021
095fa75
Fixes #1
drskalman Sep 1, 2021
05cc800
first attempt to add a simple finite field for a simple test.
drskalman Sep 9, 2021
8a9c0f6
fix: trait not object in tests
ashutoshvarma Sep 10, 2021
90c67e8
Merge pull request #4 from ashutoshvarma/hash_to_curve_swu
drskalman Sep 11, 2021
2f20499
First test running but failing because all field elements are equal to
drskalman Sep 11, 2021
480128d
fix the problem with field_new1 macro for F127.
drskalman Sep 11, 2021
d50f8b5
added a test for checking parameters. Still panics at computing square
drskalman Sep 11, 2021
52c9bac
Fixing Field parameters square root works but still it fails: `assert…
drskalman Sep 14, 2021
0075ba3
- use from instead of new to make field elements so we don't deal with
drskalman Sep 15, 2021
5a438c9
copy the structure of wb from sw
drskalman Sep 22, 2021
5136fbe
add curve map structure for of WB19 hash to curve method
drskalman Sep 30, 2021
79badc6
- implement the Isogeny for the test curve for wb
drskalman Oct 7, 2021
0cc72e3
implement wb isogeny as a function in the trait whose coefficents are
drskalman Oct 15, 2021
0aa3569
partially change tests.rs to be compatible with new WBParams
drskalman Oct 19, 2021
55054c5
Correct the size of coefficient array make the the test compile again
drskalman Oct 19, 2021
2817743
Merge remote-tracking branch 'upstream/master' into hash_to_curve_wb
drskalman Oct 19, 2021
e67c744
replace const generic arrays with const static refs
drskalman Oct 21, 2021
3a237ee
Verify that both Xi and Zeta are non-square before making the SWU map…
drskalman Oct 27, 2021
e428957
- fix the inv using Montgomery form anding unit test.
drskalman Oct 29, 2021
c9ae363
Merge remote-tracking branch 'upstream/master' into hash_to_curve_wb
drskalman Oct 29, 2021
59519bf
Add an entery to Pending part of CHANGELOG.md
drskalman Oct 29, 2021
1b57de7
Update ec/src/hashing/curve_maps/shallue_van_de_woestijne/mod.rs
drskalman Nov 1, 2021
9597819
allow user to choose either of square roots for SWU params
drskalman Nov 1, 2021
46ce1a9
replaced two inversions with batch inversion
InaOana Nov 3, 2021
f178498
Update ec/src/hashing/curve_maps/wb/mod.rs
InaOana Nov 3, 2021
c167c02
Update ec/src/hashing/curve_maps/wb/mod.rs
InaOana Nov 3, 2021
9f26f60
Merge pull request #13 from w3f/batch-inversion
drskalman Nov 3, 2021
8cf77c9
Ignore the square root check for swu parameters due to arkwork bug 344
drskalman Nov 3, 2021
d2feca7
Merge branch 'hash_to_curve_wb' of github.com:w3f/arkworks-algebra in…
drskalman Nov 3, 2021
da6ca0e
- check the isogeny actually maps the point from SWU curve to the pai…
drskalman Nov 3, 2021
83e8340
Merge branch 'master' into hash_to_curve_wb
drskalman Nov 29, 2021
aeafe19
make std optional to pass no-std test and resolve some warning.
drskalman Nov 30, 2021
0eeb79f
run cargo fmt on the relevant files.
drskalman Dec 1, 2021
5c9285b
remove unused import of Polynomials in ec/src/hashing/tests.rs
drskalman Dec 1, 2021
5dc1e21
make it compile with --no-default-features so it passes the curve tests
drskalman Dec 1, 2021
7188896
Merge branch 'master' into hash_to_curve_wb
drskalman Dec 1, 2021
ca27f33
adding `hash_to_curve_wb_with_ci_check` to the ci enabled branch.
drskalman Dec 2, 2021
8242efc
Get rid of commas in match as stable fmt mandates
drskalman Dec 3, 2021
b192589
adding back default-features = false to num-traits because no-std test
drskalman Dec 3, 2021
cdc1443
Disabling default features of digest to pass no-std test
drskalman Dec 3, 2021
25ee4d5
removing optional=true from digest in hope to pass no-std test
drskalman Dec 3, 2021
73b2883
Make blake2 dependecy a std feature to pass no-std test
drskalman Dec 3, 2021
ee72de9
- fmt clean up
drskalman Dec 3, 2021
ed90c13
removing the ci check on the branch.
drskalman Dec 3, 2021
c55eae5
Merge branch 'master' into hash_to_curve_wb
drskalman Dec 3, 2021
a612e86
Update CHANGELOG.md
Dec 6, 2021
9945c1a
Clean up dependencies for ec crate
mmagician Dec 6, 2021
af49381
Remove unfinished shallue_van_de_woestijne module
mmagician Dec 6, 2021
192ae6d
Update doc comments
mmagician Dec 6, 2021
be6a07a
Replace the println with panic
mmagician Dec 6, 2021
619bc0f
Remove unused code
mmagician Dec 6, 2021
06dd816
fixup! Update doc comments
mmagician Dec 6, 2021
f527d62
Add correct imports and fix comments in tests
mmagician Dec 6, 2021
1ec2a94
Remove std from ec crate
mmagician Dec 6, 2021
f56b694
Whitespaces fixed in Cargo.toml
mmagician Dec 6, 2021
35d6dfd
Use blake2 without default features
mmagician Dec 6, 2021
454f8d9
Remove double imports from tests
mmagician Dec 6, 2021
763091e
Apply edits from `cargo fmt` and fix README newline
mmagician Dec 6, 2021
a88b3f9
Fix CHANGELOG: move to correct "Features" section
mmagician Dec 6, 2021
75d0b10
Merge branch 'master' into HEAD
mmagician Dec 6, 2021
37482f2
Cleaning up documentation in `ec/src/hashing/tests.rs`
drskalman Dec 7, 2021
250900f
Merge branch 'hash_to_curve_wb' of github.com:w3f/arkworks-algebra in…
drskalman Dec 7, 2021
0c9268d
comment clean up in `ec/src/hashing/curve_maps/swu/mod.rs`
drskalman Dec 7, 2021
3a7b449
no need to have field_hashers module available only under default
mmagician Dec 8, 2021
5aeadc0
Fix formatting after merge
mmagician Dec 8, 2021
493d077
inline computation of sig0
InaOana Dec 9, 2021
3662d26
Merge branch 'hash_to_curve_wb' of https://github.com/w3f/arkworks-al…
InaOana Dec 9, 2021
d50c6bb
Add brackets to citation of the paper
drskalman Dec 15, 2021
7a25216
Bibliography clean up.
drskalman Dec 15, 2021
f79e272
Describing what SWUMap struct is
drskalman Dec 15, 2021
aff134a
Better description for `new_map_to_curve` map
drskalman Dec 15, 2021
ec1fb13
use lower case greek letters for constant explanation
drskalman Dec 15, 2021
b7c118e
resolve typos in panic messages.
drskalman Dec 15, 2021
b6cca9c
Improve the description of `SWUMap::map_to_curve` function
drskalman Dec 16, 2021
60bb96b
Simplify the input type of `SWUMap::map_to_curve`
drskalman Dec 16, 2021
8a6f9d4
tidy up the description of the internal openation of `SWUMap::map_to_…
drskalman Dec 16, 2021
0f98f33
Improve comments and description in `ec/src/hashing/curve_maps/wb/mod…
drskalman Dec 16, 2021
9384963
Make security paramaters an associative constant of `hash_len_in_bytes`
drskalman Dec 16, 2021
837223d
add `explanation` for hashing module in `ec/src/lib.rs`
drskalman Dec 16, 2021
2425e88
Apply suggestions from code review
Dec 22, 2021
61936f7
Add documentation for the MapToCurve & HashToField traits
mmagician Dec 22, 2021
01468cc
fixup! Make security paramaters an associative constant of `hash_len_…
mmagician Dec 22, 2021
52c571b
fixup! Apply suggestions from code review
mmagician Dec 22, 2021
20572cb
Remove unused imports and format code
mmagician Dec 22, 2021
74ffc43
Remove the separate README for hashing mod
mmagician Dec 22, 2021
7c191ad
Format field_hashers/mod.rs
mmagician Dec 22, 2021
e32c91b
Merge branch 'master' into hash_to_curve_wb
mmagician Dec 22, 2021
4479e02
Domain separation tag is only needed for the hash-to-field step
mmagician Dec 23, 2021
a3bfa65
Merge pull request #21 from mmagician/mmagician-review-fixes-2
drskalman Dec 29, 2021
f95531c
Merge pull request #23 from mmagician/remove-domain-from-curve-maps
Dec 29, 2021
76b5f33
Merge branch 'master' into hash_to_curve_wb
Dec 29, 2021
21ffa8f
Move COFACTOR & COFACTOR_INV to ModelParameters
mmagician Dec 30, 2021
2b14323
Merge pull request #24 from mmagician/rebase-after-ec-models-refactor
drskalman Jan 6, 2022
c4f165b
- add `parity` to Field trait using `to_base_prime_field_elements`
drskalman Dec 21, 2021
41bef26
added test for Fq2 extension for bls12-381; to do: correct use of mac…
InaOana Dec 22, 2021
4c6ab9d
added test for Fq6 extension for bls12-381; to do: correct use of mac…
InaOana Dec 22, 2021
63c52ed
correction for cubic extension to_base_prime_field_elements
InaOana Dec 22, 2021
d46a1bd
change field_new to from to make prime field element in parity tests
drskalman Dec 29, 2021
a8a3c9d
use `BasePrimeFieldIter` instead of `BasePrimeFieldArr`
drskalman Dec 29, 2021
eac37bd
Update mod.rs
InaOana Dec 30, 2021
e6e482d
replaced hacky calculation of sig0 with parity function invocation
InaOana Dec 30, 2021
48d2a3c
test without additional import
InaOana Dec 30, 2021
9e18ced
added parity helpr function to swu/mod.rs
InaOana Jan 5, 2022
40d656a
cleanup
InaOana Jan 5, 2022
5e3da54
update
InaOana Jan 5, 2022
8e32acd
dependencies
InaOana Jan 5, 2022
fa40eb4
fixed dependencies and tests
InaOana Jan 5, 2022
7d82e1f
cleanup
InaOana Jan 5, 2022
c7d4cfd
Format and fix iterator
Pratyush Jan 7, 2022
10f848e
moved parity tests from ff to ec/hashing/tests.rs and updated cargo f…
InaOana Jan 7, 2022
0e8838e
Formatting fixes
mmagician Jan 10, 2022
f53a28d
Move the parity helper method to private ElementParity trait
mmagician Jan 10, 2022
5c90d28
Merge pull request #29 from mmagician/parity-trait
drskalman Jan 10, 2022
9a61bbb
Merge pull request #20 from w3f/hash_to_curve_wb_field_element_parity
drskalman Jan 10, 2022
393159c
Merge branch 'master' into hash_to_curve_wb
mmagician Jan 10, 2022
c4b358a
Use BigInt::new instead of the typ BigInteger64
mmagician Jan 10, 2022
6130590
Improve comments related to constants of SWU map parameters.
drskalman Jan 10, 2022
2b20412
clarify choice of ZETA for swu map to curve plus fmt correction
drskalman Jan 10, 2022
3f24f44
Merge pull request #30 from mmagician/fix-bigint
Jan 10, 2022
57bbe10
apply missed comment improvement from @Pratyush
drskalman Jan 10, 2022
e18fd44
Merge pull request #31 from w3f/hash_to_curve_wb_missed_comment_impro…
Jan 10, 2022
5f05861
Apply suggestions from code review
Jan 11, 2022
bfa1986
Adapt the hash-to-curve codebase to digest v0.10
mmagician Jan 11, 2022
712bcd0
Merge pull request #32 from mmagician/adapt-to-digest-v0.10
drskalman Jan 11, 2022
09057e2
- match definition of parity function to sgn0 of ietf draft in swu map
drskalman Jan 12, 2022
dc9210f
non-zero not none-zero
drskalman Jan 12, 2022
6644ce6
Compress `parity` impl
Pratyush Jan 12, 2022
bcc53f5
Merge pull request #33 from w3f/hash_to_curve_wb_with_ietf_parity
Jan 13, 2022
80082c4
Revert f53a28
mmagician Feb 2, 2022
cd6565a
Merge branch 'master' into review-fixes-and-update-to-upstream
mmagician Feb 2, 2022
15677da
Expose the SEC_PARAM on DefaultFieldHasher
mmagician Feb 2, 2022
80bd947
Merge pull request #35 from mmagician/review-fixes-and-update-to-upst…
Feb 3, 2022
4a3eccc
Update CHANGELOG.md
mmagician Feb 3, 2022
df61a89
Merge branch 'master' into hash_to_curve_wb
Pratyush Feb 8, 2022
49598eb
Apply suggestions from code review
Pratyush Feb 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- [\#301](https://github.com/arkworks-rs/algebra/pull/301) (`ark-ec`) Add `GLVParameters` trait definition.
- [\#312](https://github.com/arkworks-rs/algebra/pull/312) (`ark-ec`) Add `is_in_correct_subgroup_assuming_on_curve` for all `SWModelParameters`.
- [\#321](https://github.com/arkworks-rs/algebra/pull/321) (`ark-ff`) Change bigint conversions to impl `From` instead of `Into`.
- [\#343](https://github.com/arkworks-rs/algebra/pull/343) (`ark-ec`) Add WB and SWU hash-to-curve maps.
- [\#348](https://github.com/arkworks-rs/algebra/pull/348) (`ark-ec`) Add `msm:{Fixed,Variable}Base:msm_checked_len`.
- [\#364](https://github.com/arkworks-rs/algebra/pull/364) (`ark-ec`) Add `ChunkedPippenger` to variable-base MSM.
- [\#371](https://github.com/arkworks-rs/algebra/pull/371) (`ark-serialize`) Add serialization impls for arrays
Expand Down
7 changes: 7 additions & 0 deletions ec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ rust-version = "1.57"
ark-std = { version = "^0.3.0", default-features = false }
ark-serialize = { version = "^0.3.0", path = "../serialize", default-features = false }
ark-ff = { version = "^0.3.0", path = "../ff", default-features = false }
ark-poly = { version = "^0.3.0", path = "../poly", default-features = false }
derivative = { version = "2", features = ["use_core"] }
digest = { version = "0.10", default-features = false }
num-traits = { version = "0.2", default-features = false }
rayon = { version = "1", optional = true }
zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] }

[dev-dependencies]
hashbrown = { version = "0.11.1" }
blake2 = { version = "0.10", default-features = false }
ark-test-curves = { version = "^0.3.0", path = "../test-curves", default-features = false, features = ["bls12_381_curve"] }

[features]
default = []
std = [ "ark-std/std", "ark-ff/std", "ark-serialize/std" ]
Expand Down
2 changes: 2 additions & 0 deletions ec/src/hashing/curve_maps/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod swu;
pub mod wb;
175 changes: 175 additions & 0 deletions ec/src/hashing/curve_maps/swu/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
use crate::models::SWModelParameters;
use ark_ff::{BigInteger, Field, One, PrimeField, SquareRootField, Zero};
use ark_std::string::ToString;
use core::marker::PhantomData;

use crate::{
hashing::{map_to_curve_hasher::MapToCurve, HashToCurveError},
models::short_weierstrass_jacobian::GroupAffine,
};

/// Trait defining the necessary parameters for the SWU hash-to-curve method
/// for the curves of Weierstrass form of:
/// y^2 = x^3 + a*x + b where ab != 0. From [\[WB2019\]]
///
/// - [\[WB2019\]] <https://eprint.iacr.org/2019/403>
pub trait SWUParams: SWModelParameters {
/// An element of the base field that is not a square root see \[WB2019, Section 4\].
/// It is also convenient to have $g(b/xi * a)$ to be square. In general
/// we use a `XI` with low absolute value coefficients when they are
/// represented as integers.
const XI: Self::BaseField;
/// An arbitrary nonsquare conveniently chosen to be a primitive element of the base field
const ZETA: Self::BaseField;
/// Square root of `THETA = Self::XI/Self::ZETA`.
const XI_ON_ZETA_SQRT: Self::BaseField;
}

/// Represents the SWU hash-to-curve map defined by `P`.
pub struct SWUMap<P: SWUParams> {
drskalman marked this conversation as resolved.
Show resolved Hide resolved
curve_params: PhantomData<fn() -> P>,
}

/// Trait defining a parity method on the Field elements based on [\[1\]] Section 4.1
///
/// - [\[1\]] <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/>
pub fn parity<F: Field>(element: &F) -> bool {
element
.to_base_prime_field_elements()
.find(|&x| !x.is_zero())
.map_or(false, |x| x.into_bigint().is_odd())
}

impl<P: SWUParams> MapToCurve<GroupAffine<P>> for SWUMap<P> {
/// Constructs a new map if `P` represents a valid map.
fn new_map_to_curve() -> Result<Self, HashToCurveError> {
// Verifying that both XI and ZETA are non-squares
if P::XI.legendre().is_qr() || P::ZETA.legendre().is_qr() {
return Err(HashToCurveError::MapToCurveError(
"both xi and zeta should be quadratic non-residues for the SWU map".to_string(),
));
}

// Verifying precomupted values
let xi_on_zeta = P::XI / P::ZETA;
match xi_on_zeta.sqrt() {
Some(xi_on_zeta_sqrt) => {
if xi_on_zeta_sqrt != P::XI_ON_ZETA_SQRT && xi_on_zeta_sqrt != -P::XI_ON_ZETA_SQRT {
return Err(HashToCurveError::MapToCurveError(
"precomputed P::XI_ON_ZETA_SQRT is not what it is supposed to be"
.to_string(),
));
}
},
None => {
panic!(
"`xi_on_zeta` was expected to have a sqrt, since the numerator and denominator are non-residues and Legendre symbol is multiplicative. Q.E.D"
);
},
}

// Verifying the prerequisite for applicability of SWU map
if P::COEFF_A.is_zero() || P::COEFF_B.is_zero() {
return Err(HashToCurveError::MapToCurveError("Simplified SWU requires a * b != 0 in the short Weierstrass form of y^2 = x^3 + a*x + b ".to_string()));
}

Ok(SWUMap {
curve_params: PhantomData,
})
}

/// Map an arbitrary base field element to a curve point.
/// Based on
/// <https://github.com/zcash/pasta_curves/blob/main/src/hashtocurve.rs>.
fn map_to_curve(&self, point: P::BaseField) -> Result<GroupAffine<P>, HashToCurveError> {
// 1. tv1 = inv0(Z^2 * u^4 + Z * u^2)
// 2. x1 = (-B / A) * (1 + tv1)
// 3. If tv1 == 0, set x1 = B / (Z * A)
// 4. gx1 = x1^3 + A * x1 + B
//
// We use the "Avoiding inversions" optimization in [WB2019, section 4.2]
// (not to be confused with section 4.3):
//
// here [WB2019]
// ------- ---------------------------------
// Z ξ
// u t
// Z * u^2 ξ * t^2 (called u, confusingly)
// x1 X_0(t)
// x2 X_1(t)
// gx1 g(X_0(t))
// gx2 g(X_1(t))
//
// Using the "here" names:
// x1 = num_x1/div = [B*(Z^2 * u^4 + Z * u^2 + 1)] / [-A*(Z^2 * u^4 + Z * u^2]
// gx1 = num_gx1/div_gx1 = [num_x1^3 + A * num_x1 * div^2 + B * div^3] / div^3
let a = P::COEFF_A;
let b = P::COEFF_B;
let xi_t2 = P::XI * point.square();
let ta = xi_t2.square() + xi_t2;
let num_x1 = b * (ta + <P::BaseField as One>::one());
let div = a * if ta.is_zero() { P::XI } else { -ta };
let num2_x1 = num_x1.square();
let div2 = div.square();
let div3 = div2 * div;
let num_gx1 = (num2_x1 + a * div2) * num_x1 + b * div3;

// 5. x2 = Z * u^2 * x1
let num_x2 = xi_t2 * num_x1; // same div

// 6. gx2 = x2^3 + A * x2 + B [optimized out; see below]
// 7. If is_square(gx1), set x = x1 and y = sqrt(gx1)
// 8. Else set x = x2 and y = sqrt(gx2)
let gx1_square;
let gx1;
let zeta_gx1;

assert!(
!div3.is_zero(),
"we have checked that neither a or xi are zero. Q.E.D."
);
let y1: P::BaseField = {
gx1 = num_gx1 / div3;
zeta_gx1 = P::ZETA * gx1;
if gx1.legendre().is_qr() {
gx1_square = true;
gx1.sqrt()
.expect("We have checked that gx1 is a quadratic residue. Q.E.D")
} else {
gx1_square = false;
zeta_gx1.sqrt().expect(
"zeta * gx1 is a quadratic residue because legard is multiplicative. Q.E.D",
)
}
};

// This magic also comes from a generalization of [WB2019, section 4.2].
//
// The Sarkar square root algorithm with input s gives us a square root of
// h * s for free when s is not square, where h is a fixed nonsquare.
// In our implementation, h = ROOT_OF_UNITY.
// We know that Z / h is a square since both Z and h are
// nonsquares. Precompute theta as a square root of Z / ROOT_OF_UNITY.
//
// We have gx2 = g(Z * u^2 * x1) = Z^3 * u^6 * gx1
// = (Z * u^3)^2 * (Z/h * h * gx1)
// = (Z * theta * u^3)^2 * (h * gx1)
//
// When gx1 is not square, y1 is a square root of h * gx1, and so Z * theta *
// u^3 * y1 is a square root of gx2. Note that we don't actually need to
// compute gx2.

let y2 = P::XI_ON_ZETA_SQRT * xi_t2 * point * y1;
let num_x = if gx1_square { num_x1 } else { num_x2 };
let y = if gx1_square { y1 } else { y2 };

let x_affine = num_x / div;
let y_affine = if parity(&y) { -y } else { y };
let point_on_curve = GroupAffine::<P>::new(x_affine, y_affine, false);
assert!(
point_on_curve.is_on_curve(),
"swu mapped to a point off the curve"
);
Ok(point_on_curve)
}
}
95 changes: 95 additions & 0 deletions ec/src/hashing/curve_maps/wb/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use core::marker::PhantomData;

use crate::{models::SWModelParameters, ModelParameters};
use ark_ff::batch_inversion;
use ark_poly::{univariate::DensePolynomial, Polynomial, UVPolynomial};

use crate::{
hashing::{map_to_curve_hasher::MapToCurve, HashToCurveError},
models::short_weierstrass_jacobian::GroupAffine,
AffineCurve,
};

use super::swu::{SWUMap, SWUParams};
type BaseField<MP> = <MP as ModelParameters>::BaseField;

mmagician marked this conversation as resolved.
Show resolved Hide resolved
/// Trait defining the necessary parameters for the WB hash-to-curve method
/// for the curves of Weierstrass form of:
/// of y^2 = x^3 + a*x + b where b != 0 but `a` can be zero like BLS-381 curve.
/// From [\[WB2019\]]
///
/// - [\[WB2019\]] <http://dx.doi.org/10.46586/tches.v2019.i4.154-179>
pub trait WBParams: SWModelParameters + Sized {
// The isogenous curve should be defined over the same base field but it can have
// different scalar field type IsogenousCurveScalarField :
type IsogenousCurve: SWUParams<BaseField = BaseField<Self>>;

const PHI_X_NOM: &'static [BaseField<Self>];
const PHI_X_DEN: &'static [BaseField<Self>];

const PHI_Y_NOM: &'static [BaseField<Self>];
const PHI_Y_DEN: &'static [BaseField<Self>];

fn isogeny_map(
domain_point: GroupAffine<Self::IsogenousCurve>,
) -> Result<GroupAffine<Self>, HashToCurveError> {
let x_num = DensePolynomial::from_coefficients_slice(&Self::PHI_X_NOM[..]);
let x_den = DensePolynomial::from_coefficients_slice(&Self::PHI_X_DEN[..]);

let y_num = DensePolynomial::from_coefficients_slice(&Self::PHI_Y_NOM[..]);
let y_den = DensePolynomial::from_coefficients_slice(&Self::PHI_Y_DEN[..]);

let mut v: [BaseField<Self>; 2] = [
x_den.evaluate(&domain_point.x),
y_den.evaluate(&domain_point.x),
];
batch_inversion(&mut v);
let img_x = x_num.evaluate(&domain_point.x) * v[0];
let img_y = (y_num.evaluate(&domain_point.x) * domain_point.y) * v[1];

Ok(GroupAffine::new(img_x, img_y, false))
}
}

pub struct WBMap<P: WBParams> {
swu_field_curve_hasher: SWUMap<P::IsogenousCurve>,
curve_params: PhantomData<fn() -> P>,
}

impl<P: WBParams> MapToCurve<GroupAffine<P>> for WBMap<P> {
/// Constructs a new map if `P` represents a valid map.
fn new_map_to_curve() -> Result<Self, HashToCurveError> {
// Verifying that the isogeny maps the generator of the SWU curve into us
let isogenous_curve_generator = GroupAffine::<P::IsogenousCurve>::new(
P::IsogenousCurve::AFFINE_GENERATOR_COEFFS.0,
P::IsogenousCurve::AFFINE_GENERATOR_COEFFS.1,
false,
);

match P::isogeny_map(isogenous_curve_generator) {
Ok(point_on_curve) => {
if !point_on_curve.is_on_curve() {
return Err(HashToCurveError::MapToCurveError(format!("the isogeny maps the generator of its domain: {} into {} which does not belong to its codomain.",isogenous_curve_generator, point_on_curve)));
}
},
Err(e) => return Err(e),
}

Ok(WBMap {
swu_field_curve_hasher: SWUMap::<P::IsogenousCurve>::new_map_to_curve().unwrap(),
curve_params: PhantomData,
})
}

/// Map random field point to a random curve point
/// inspired from
/// <https://github.com/zcash/pasta_curves/blob/main/src/hashtocurve.rs>
fn map_to_curve(
&self,
element: <GroupAffine<P> as AffineCurve>::BaseField,
) -> Result<GroupAffine<P>, HashToCurveError> {
// first we need to map the field point to the isogenous curve
let point_on_isogenious_curve = self.swu_field_curve_hasher.map_to_curve(element).unwrap();
P::isogeny_map(point_on_isogenious_curve)
}
}
Loading