Skip to content

Commit

Permalink
Elligator2 hash-to-curve for Bandersnatch (#758)
Browse files Browse the repository at this point in the history
* Implement Elligator2 hash-to-curve for Bandersnatch curve

* Add relevant entry to `CHANGELOG.md`

* Remove sha3 unused dependancy

* Include the script to compute an efficient z for elligator2 map.

* move Elligator2 for Bandersnatch from Pending to Features

---------

Co-authored-by: Marcin <marcin.gorny.94@protonmail.com>
  • Loading branch information
drskalman and mmagician authored Jan 27, 2024
1 parent bf96a5b commit 228787b
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

### Features

- [\#758](https://github.com/arkworks-rs/algebra/pull/758) Implement Elligator2 hash-to-curve parameters for Bandersnatch.
- [\#659](https://github.com/arkworks-rs/algebra/pull/659) (`ark-ec`) Add Elligator2 hash-to-curve map.
- [\#689](https://github.com/arkworks-rs/algebra/pull/689) (`ark-serialize`) Add `CanonicalSerialize` and `CanonicalDeserialize` impls for `VecDeque` and `LinkedList`.
- [\#691](https://github.com/arkworks-rs/algebra/pull/691) (`ark-poly`) Implement `Polynomial` for `SparseMultilinearExtension` and `DenseMultilinearExtension`.
Expand Down
1 change: 1 addition & 0 deletions curves/ed_on_bls12_381_bandersnatch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ark-relations = { version = "0.4.0", default-features = false }
ark-serialize = { version = "0.4.0", default-features = false }
ark-algebra-test-templates = { version = "0.4.0", default-features = false }
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }
sha2 = { version = "0.10", default-features = false }

[features]
default = []
Expand Down
53 changes: 53 additions & 0 deletions curves/ed_on_bls12_381_bandersnatch/src/curves/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use ark_ec::{
hashing::curve_maps::elligator2::Elligator2Config,
models::CurveConfig,
short_weierstrass::{self, SWCurveConfig},
twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
Expand Down Expand Up @@ -137,3 +138,55 @@ impl SWCurveConfig for BandersnatchConfig {
/// generators
const GENERATOR: SWAffine = SWAffine::new_unchecked(SW_GENERATOR_X, SW_GENERATOR_Y);
}

// Elligator hash to curve Bandersnatch
// sage: find_z_ell2(GF(52435875175126190479447740508185965837690552500527637822603658699938581184513))
// 5
//
// sage: Fq = GF(52435875175126190479447740508185965837690552500527637822603658699938581184513)
// sage: 1/Fq(25465760566081946422412445027709227188579564747101592991722834452325077642517)^2
// sage: COEFF_A = Fq(29978822694968839326280996386011761570173833766074948509196803838190355340952)
// sage: COEFF_B = Fq(25465760566081946422412445027709227188579564747101592991722834452325077642517)
// sage: 1/COEFF_B^2
// 35484827650731063748396669747216844996598387089274032563585525486049249153249
// sage: COEFF_A/COEFF_B
// 22511181562295907836254750456843438087744031914659733450388350895537307167857
impl Elligator2Config for BandersnatchConfig {
const Z: Fq = MontFp!("5");

/// This must be equal to 1/(MontCurveConfig::COEFF_B)^2;
const ONE_OVER_COEFF_B_SQUARE: Fq =
MontFp!("35484827650731063748396669747216844996598387089274032563585525486049249153249");

/// This must be equal to MontCurveConfig::COEFF_A/MontCurveConfig::COEFF_B;
const COEFF_A_OVER_COEFF_B: Fq =
MontFp!("22511181562295907836254750456843438087744031914659733450388350895537307167857");
}

#[cfg(test)]
mod test {
use super::*;
use ark_ec::hashing::{
curve_maps::elligator2::Elligator2Map, map_to_curve_hasher::MapToCurveBasedHasher,
HashToCurve,
};
use ark_ff::field_hashers::DefaultFieldHasher;
use sha2::Sha512;

#[test]
fn test_elligtor2_hash2curve_hashes_to_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"
);
}
}
39 changes: 39 additions & 0 deletions ec/src/hashing/curve_maps/curve_map_parameter_helper.sage
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Arguments:
# - F, a field object, e.g., F = GF(2^521 - 1)
# - A and B, the coefficients of the curve y^2 = x^3 + A * x + B
def find_z_sswu(F, A, B):
R.<xx> = F[]
# Polynomial ring over F
g = xx^3 + F(A) * xx + F(B)
# y^2 = g(x) = x^3 + A * x + B
ctr = F.gen()
while True:
for Z_cand in (F(ctr), F(-ctr)):
# Criterion 1: Z is non-square in F.
if is_square(Z_cand):
continue
# Criterion 2: Z != -1 in F.
if Z_cand == F(-1):
continue
# Criterion 3: g(x) - Z is irreducible over F.
if not (g - Z_cand).is_irreducible():
continue
# Criterion 4: g(B / (Z * A)) is square in F.
if is_square(g(B / (Z_cand * A))):
return Z_cand
ctr += 1

# Finds the smallest z in term of non-zero bit
# in sage representation for consturcting
# elligator2 map for a curve defined over field F.
# Argument:
# - F, a field object, e.g., F = GF(2^255 - 19)
def find_z_ell2(F):
ctr = F.gen()
while True:
for Z_cand in (F(ctr), F(-ctr)):
# Z must be a non-square in F.
if is_square(Z_cand):
continue
return Z_cand
ctr += 1

1 comment on commit 228787b

@rebenkoy
Copy link

@rebenkoy rebenkoy commented on 228787b May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, I am having following issue with this commit.

❯ cargo test                                                                                 
   Compiling ark-bls12-381 v0.4.0 (https://github.com/arkworks-rs/algebra.git#065cd24f)
   Compiling ark-ed-on-bls12-381-bandersnatch v0.4.0 (https://github.com/arkworks-rs/algebra.git#065cd24f)
error[E0432]: unresolved import `ark_ec::hashing::curve_maps::elligator2`
 --> /.../git/checkouts/algebra-7e23afa68841b66e/065cd24/curves/ed_on_bls12_381_bandersnatch/src/curves/mod.rs:2:26
  |
2 |     hashing::curve_maps::elligator2::Elligator2Config,
  |                          ^^^^^^^^^^ could not find `elligator2` in `curve_maps`

error[E0432]: unresolved import `ark_ff::AdditiveGroup`
 --> /.../git/checkouts/algebra-7e23afa68841b66e/065cd24/curves/ed_on_bls12_381_bandersnatch/src/curves/mod.rs:7:14
  |
7 | use ark_ff::{AdditiveGroup, MontFp};
  |              ^^^^^^^^^^^^^ no `AdditiveGroup` in the root

For more information about this error, try `rustc --explain E0432`.
error: could not compile `ark-ed-on-bls12-381-bandersnatch` (lib) due to 2 previous errors

UPD: it is most probably my fault for using this crate directly with a github link.

Please sign in to comment.