diff --git a/Cargo.toml b/Cargo.toml index 9678e8eb..31fbfe3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ serde = { version = "1.0", default-features = false, optional = true } serde_arrays = { version = "0.1.0", optional = true } hex = { version = "0.4", optional = true, default-features = false, features = ["alloc", "serde"] } blake2b_simd = "1" +bls12_381 = { git = "https://github.com/privacy-scaling-explorations/bls12_381", tag = "v2023_10_26", features = ["groups", "basefield"] } rayon = "1.8" [features] diff --git a/src/bls12_381/mod.rs b/src/bls12_381/mod.rs new file mode 100644 index 00000000..d812da7a --- /dev/null +++ b/src/bls12_381/mod.rs @@ -0,0 +1,84 @@ +use crate::arithmetic::mul_512; +use crate::arithmetic::sbb; +use crate::{ + arithmetic::{CurveEndo, EndoParameters}, + endo, +}; +pub use bls12_381::{Fp, G1Projective, Scalar}; +use ff::PrimeField; +use ff::WithSmallOrderMulGroup; +use std::convert::TryInto; + +pub use bls12_381::*; + +// Obtained from https://github.com/ConsenSys/gnark-crypto/blob/master/ecc/utils.go +// See https://github.com/demining/Endomorphism-Secp256k1/blob/main/README.md +// to have more details about the endomorphism. +const ENDO_PARAMS_BLS: EndoParameters = EndoParameters { + // round(b2/n) + gamma2: [0x63f6e522f6cfee30u64, 0x7c6becf1e01faadd, 0x01, 0x0], + // round(-b1/n) + gamma1: [0x02u64, 0x0, 0x0, 0x0], + b1: [0x01u64, 0x0, 0x0, 0x0], + b2: [0x0000000100000000, 0xac45a4010001a402, 0x0, 0x0], +}; + +endo!(G1Projective, Scalar, ENDO_PARAMS_BLS); + +#[test] +fn test_endo() { + use ff::Field; + use rand_core::OsRng; + + for _ in 0..100000 { + let k = Scalar::random(OsRng); + let (k1, k1_neg, k2, k2_neg) = G1Projective::decompose_scalar(&k); + if k1_neg & k2_neg { + assert_eq!( + k, + -Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2) + ) + } else if k1_neg { + assert_eq!( + k, + -Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2) + ) + } else if k2_neg { + assert_eq!( + k, + Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2) + ) + } else { + assert_eq!( + k, + Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2) + ) + } + } + + for _ in 0..100000 { + let k = Scalar::random(OsRng); + let (k1, k1_neg, k2, k2_neg) = G1Projective::decompose_scalar(&k); + if k1_neg & k2_neg { + assert_eq!( + k, + -Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2) + ) + } else if k1_neg { + assert_eq!( + k, + -Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2) + ) + } else if k2_neg { + assert_eq!( + k, + Scalar::from_u128(k1) + Scalar::ZETA * Scalar::from_u128(k2) + ) + } else { + assert_eq!( + k, + Scalar::from_u128(k1) - Scalar::ZETA * Scalar::from_u128(k2) + ) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index b2396d7b..2d582f73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod hash_to_curve; pub mod msm; pub mod serde; +pub mod bls12_381; pub mod bn256; pub mod grumpkin; pub mod pasta;