Skip to content

Commit

Permalink
Bandersnatch Edwards suite. TE2SW and SW2TE
Browse files Browse the repository at this point in the history
  • Loading branch information
davxy committed May 28, 2024
1 parent 87b37e1 commit da166a8
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 128 deletions.
12 changes: 7 additions & 5 deletions src/ietf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub struct Proof<S: IetfSuite> {
pub s: ScalarField<S>,
}

impl<S: IetfSuite + Sync> CanonicalSerialize for Proof<S> {
impl<S: IetfSuite> CanonicalSerialize for Proof<S> {
fn serialize_with_mode<W: ark_serialize::Write>(
&self,
mut writer: W,
Expand All @@ -41,7 +41,7 @@ impl<S: IetfSuite + Sync> CanonicalSerialize for Proof<S> {
}
}

impl<S: IetfSuite + Sync> CanonicalDeserialize for Proof<S> {
impl<S: IetfSuite> CanonicalDeserialize for Proof<S> {
fn deserialize_with_mode<R: ark_serialize::Read>(
mut reader: R,
_compress_always: ark_serialize::Compress,
Expand All @@ -61,7 +61,7 @@ impl<S: IetfSuite + Sync> CanonicalDeserialize for Proof<S> {
}
}

impl<S: IetfSuite + Sync> ark_serialize::Valid for Proof<S> {
impl<S: IetfSuite> ark_serialize::Valid for Proof<S> {
fn check(&self) -> Result<(), ark_serialize::SerializationError> {
self.c.check()?;
self.s.check()?;
Expand Down Expand Up @@ -184,8 +184,10 @@ pub mod testing {
#[cfg(test)]
mod tests {
use super::*;
use crate::utils::testing::{
random_val, AffinePoint, Input, ScalarField, Secret, TestSuite, TEST_SEED,
use crate::testing::{
random_val,
suite::{AffinePoint, Input, ScalarField, Secret, TestSuite},
TEST_SEED,
};

#[test]
Expand Down
10 changes: 9 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub mod utils;
#[cfg(feature = "ring")]
pub mod ring;

#[cfg(test)]
mod testing;

pub mod prelude {
pub use ark_ec;
pub use ark_ff;
Expand Down Expand Up @@ -60,6 +63,7 @@ pub const CUSTOM_SUITE_ID_FLAG: u8 = 0x80;
/// Can be easily customized to implement more exotic VRF types by overwriting
/// the default methods implementations.
pub trait Suite: Copy + Clone {
// TODO: make this a byte array
/// Suite identifier (aka `suite_string` in RFC-9381)
const SUITE_ID: u8;

Expand Down Expand Up @@ -258,7 +262,11 @@ impl<S: Suite> Output<S> {

#[cfg(test)]
mod tests {
use crate::utils::testing::*;
use crate::testing::{
random_val,
suite::{Input, Public, Secret},
TEST_SEED,
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};

#[test]
Expand Down
6 changes: 4 additions & 2 deletions src/pedersen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ impl<S: PedersenSuite> PedersenVerifier<S> for Public<S> {
#[cfg(test)]
mod tests {
use super::*;
use crate::utils::testing::{
random_val, AffinePoint, BaseField, Input, Secret, TestSuite, TEST_SEED,
use crate::testing::{
random_val,
suite::{AffinePoint, BaseField, Input, Secret, TestSuite},
TEST_SEED,
};
use ark_ff::MontFp;

Expand Down
34 changes: 0 additions & 34 deletions src/ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,37 +273,3 @@ where
self.pcs_params.check()
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::suites::bandersnatch::{ring::RingContext, AffinePoint, Input, Secret};
use crate::utils::testing::{random_val, random_vec, TEST_SEED};

#[test]
fn prove_verify_works() {
let rng = &mut ark_std::test_rng();
let domain_size = 1024;
let ring_ctx = RingContext::new_random(domain_size, rng);

let secret = Secret::from_seed(TEST_SEED);
let public = secret.public();
let input = Input::from(random_val(Some(rng)));
let output = secret.output(input);

let keyset_size = ring_ctx.piop_params.keyset_part_size;

let prover_idx = 3;
let mut pks = random_vec::<AffinePoint>(keyset_size, Some(rng));
pks[prover_idx] = public.0;

let prover_key = ring_ctx.prover_key(pks.clone());
let prover = ring_ctx.prover(prover_key, prover_idx);
let proof = secret.prove(input, output, b"foo", &prover);

let verifier_key = ring_ctx.verifier_key(pks);
let verifier = ring_ctx.verifier(verifier_key);
let result = Public::verify(input, output, b"foo", &proof, &verifier);
assert!(result.is_ok());
}
}
210 changes: 151 additions & 59 deletions src/suites/bandersnatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,86 +51,178 @@
// GENERATOR_X = 18886178867200960497001835917649091219057080094937609519140440539760939937304
// GENERATOR_Y = 19188667384257783945677642223292697773471335439753913231509108946878080696678

use crate::{pedersen::PedersenSuite, utils::arkworks_pending::*, *};
use ark_ff::MontFp;

use crate::pedersen::PedersenSuite;
use crate::*;
pub mod weierstrass {
use super::*;

#[derive(Debug, Copy, Clone)]
pub struct BandersnatchSha512;
#[derive(Debug, Copy, Clone)]
pub struct BandersnatchSha512;

suite_types!(BandersnatchSha512);
suite_types!(BandersnatchSha512);

impl Suite for BandersnatchSha512 {
const SUITE_ID: u8 = CUSTOM_SUITE_ID_FLAG | 0x03;
const CHALLENGE_LEN: usize = 32;
impl Suite for BandersnatchSha512 {
const SUITE_ID: u8 = CUSTOM_SUITE_ID_FLAG | 0x03;
const CHALLENGE_LEN: usize = 32;

type Affine = ark_ed_on_bls12_381_bandersnatch::SWAffine;
type Hasher = sha2::Sha512;
}
type Affine = ark_ed_on_bls12_381_bandersnatch::SWAffine;
type Hasher = sha2::Sha512;
}

impl PedersenSuite for BandersnatchSha512 {
const BLINDING_BASE: AffinePoint = {
const X: BaseField = MontFp!(
"4956610287995045830459834427365747411162584416641336688940534788579455781570"
);
const Y: BaseField = MontFp!(
"52360910621642801549936840538960627498114783432181489929217988668068368626761"
);
AffinePoint::new_unchecked(X, Y)
};
}

impl PedersenSuite for BandersnatchSha512 {
const BLINDING_BASE: AffinePoint = {
const X: BaseField =
MontFp!("4956610287995045830459834427365747411162584416641336688940534788579455781570");
const Y: BaseField = MontFp!(
"52360910621642801549936840538960627498114783432181489929217988668068368626761"
#[cfg(feature = "ring")]
pub mod ring {
use super::*;
use crate::ring;

impl ring::Pairing<BandersnatchSha512> for ark_bls12_381::Bls12_381 {}

impl ring::RingSuite for BandersnatchSha512 {
type Config = ark_ed_on_bls12_381_bandersnatch::SWConfig;
type Pairing = ark_bls12_381::Bls12_381;

/// A point on the curve not belonging to the prime order subgroup.
///
/// Found using `ring_proof::find_complement_point::<Self::Config>()` function.
const COMPLEMENT_POINT: AffinePoint = {
const X: BaseField = MontFp!("0");
const Y: BaseField = MontFp!(
"11982629110561008531870698410380659621661946968466267969586599013782997959645"
);
AffinePoint::new_unchecked(X, Y)
};
}

pub type RingContext = ring::RingContext<BandersnatchSha512>;
pub type VerifierKey = ring::VerifierKey<BandersnatchSha512>;
pub type Prover = ring::Prover<BandersnatchSha512>;
pub type Verifier = ring::Verifier<BandersnatchSha512>;
pub type Proof = ring::Proof<BandersnatchSha512>;
}

// 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
impl MapConfig for ark_ed_on_bls12_381_bandersnatch::BandersnatchConfig {
const MONT_A_OVER_THREE: ark_ed_on_bls12_381_bandersnatch::Fq =
MontFp!("9992940898322946442093665462003920523391277922024982836398934612730118446984");
const MONT_B_INV: ark_ed_on_bls12_381_bandersnatch::Fq = MontFp!(
"41180284393978236561320365279764246793818536543197771097409483252169927600582"
);
AffinePoint::new_unchecked(X, Y)
};
}

#[cfg(test)]
mod test {
use super::*;

// TODO: use macro to build all tests
#[test]
fn ietf_prove_verify() {
testing::ietf_prove_verify::<BandersnatchSha512>();
}

#[test]
fn prove_verify_pedersen() {
testing::pedersen_prove_verify::<BandersnatchSha512>();
}

#[cfg(feature = "ring")]
#[test]
fn ring_prove_verify() {
testing::ring_prove_verify::<BandersnatchSha512>()
}

#[test]
fn sw_to_te_roundtrip() {
use ark_ed_on_bls12_381_bandersnatch::BandersnatchConfig;

let org_point = <BandersnatchSha512 as PedersenSuite>::BLINDING_BASE;

let te_point = map_sw_to_te::<BandersnatchConfig>(&org_point).unwrap();
// assert!(te_point.is_on_curve());

let sw_point = map_te_to_sw::<BandersnatchConfig>(&te_point).unwrap();
// assert!(sw_point.is_on_curve());

println!("{:?}", org_point);
println!("{:?}", te_point);
println!("{:?}", sw_point);
}

#[test]
fn sw_to_te_roundtrip() {
use ark_ed_on_bls12_381_bandersnatch::BandersnatchConfig;

let org_point = <BandersnatchSha512 as PedersenSuite>::BLINDING_BASE;

let te_point = map_sw_to_te::<BandersnatchConfig>(&org_point).unwrap();
// assert!(te_point.is_on_curve());

let sw_point = map_te_to_sw::<BandersnatchConfig>(&te_point).unwrap();
// assert!(sw_point.is_on_curve());

println!("{:?}", org_point);
println!("{:?}", te_point);
println!("{:?}", sw_point);
}
}
}

#[cfg(feature = "ring")]
pub mod ring {
pub mod edwards {
use super::*;
use crate::ring;

impl ring::Pairing<BandersnatchSha512> for ark_bls12_381::Bls12_381 {}
#[derive(Debug, Copy, Clone)]
pub struct BandersnatchSha512Edwards;

impl ring::RingSuite for BandersnatchSha512 {
type Config = ark_ed_on_bls12_381_bandersnatch::SWConfig;
type Pairing = ark_bls12_381::Bls12_381;
suite_types!(BandersnatchSha512Edwards);

/// A point on the curve not belonging to the prime order subgroup.
///
/// Found using `ring_proof::find_complement_point::<Self::Config>()` function.
const COMPLEMENT_POINT: AffinePoint = {
const X: BaseField = MontFp!("0");
impl Suite for BandersnatchSha512Edwards {
const SUITE_ID: u8 = CUSTOM_SUITE_ID_FLAG | 0x04;
const CHALLENGE_LEN: usize = 32;

type Affine = ark_ed_on_bls12_381_bandersnatch::EdwardsAffine;
type Hasher = sha2::Sha512;
}

impl PedersenSuite for BandersnatchSha512Edwards {
const BLINDING_BASE: AffinePoint = {
const X: BaseField = MontFp!(
"14576224270591906826192118712803723445031237947873156025406837473427562701854"
);
const Y: BaseField = MontFp!(
"11982629110561008531870698410380659621661946968466267969586599013782997959645"
"38436873314098705092845609371301773715650206984323659492499960072785679638442"
);
AffinePoint::new_unchecked(X, Y)
};
}

pub type RingContext = ring::RingContext<BandersnatchSha512>;
pub type VerifierKey = ring::VerifierKey<BandersnatchSha512>;
pub type Prover = ring::Prover<BandersnatchSha512>;
pub type Verifier = ring::Verifier<BandersnatchSha512>;
pub type Proof = ring::Proof<BandersnatchSha512>;
}

#[cfg(test)]
mod test {
use super::*;
use utils::testing::{random_val, TEST_SEED};
#[cfg(test)]
mod test {
use super::*;

#[test]
fn prove_verify_works() {
use crate::pedersen::{PedersenProver, PedersenVerifier};
#[test]
fn ietf_prove_verify() {
testing::ietf_prove_verify::<BandersnatchSha512Edwards>();
}

let secret = Secret::from_seed(TEST_SEED);
let input = Input::from(random_val(None));
let output = secret.output(input);

let (proof, blinding) = secret.prove(input, output, b"foo");

let result = Public::verify(input, output, b"foo", &proof);
assert!(result.is_ok());

assert_eq!(
proof.key_commitment(),
secret.public().0 + BandersnatchSha512::BLINDING_BASE * blinding
);
#[test]
fn prove_verify_pedersen() {
testing::pedersen_prove_verify::<BandersnatchSha512Edwards>();
}
}
}
Loading

0 comments on commit da166a8

Please sign in to comment.