arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/r1cs-std/src/pairing/mod.rs
r1cs-std/src/pairing/mod.rsRaw
  1use crate::prelude::*;
  2use algebra::{Field, PairingEngine};
  3use r1cs_core::{ConstraintSystem, SynthesisError};
  4use std::fmt::Debug;
  5
  6pub mod bls12;
  7pub use self::bls12::bls12_377;
  8
  9pub trait PairingGadget<PairingE: PairingEngine, ConstraintF: Field> {
 10    type G1Gadget: GroupGadget<PairingE::G1Projective, ConstraintF>;
 11    type G2Gadget: GroupGadget<PairingE::G2Projective, ConstraintF>;
 12    type G1PreparedGadget: ToBytesGadget<ConstraintF> + Clone + Debug;
 13    type G2PreparedGadget: ToBytesGadget<ConstraintF> + Clone + Debug;
 14    type GTGadget: FieldGadget<PairingE::Fqk, ConstraintF> + Clone;
 15
 16    fn miller_loop<CS: ConstraintSystem<ConstraintF>>(
 17        cs: CS,
 18        p: &[Self::G1PreparedGadget],
 19        q: &[Self::G2PreparedGadget],
 20    ) -> Result<Self::GTGadget, SynthesisError>;
 21
 22    fn final_exponentiation<CS: ConstraintSystem<ConstraintF>>(
 23        cs: CS,
 24        p: &Self::GTGadget,
 25    ) -> Result<Self::GTGadget, SynthesisError>;
 26
 27    fn pairing<CS: ConstraintSystem<ConstraintF>>(
 28        mut cs: CS,
 29        p: Self::G1PreparedGadget,
 30        q: Self::G2PreparedGadget,
 31    ) -> Result<Self::GTGadget, SynthesisError> {
 32        let tmp = Self::miller_loop(cs.ns(|| "miller loop"), &[p], &[q])?;
 33        Self::final_exponentiation(cs.ns(|| "final_exp"), &tmp)
 34    }
 35
 36    /// Computes a product of pairings.
 37    #[must_use]
 38    fn product_of_pairings<CS: ConstraintSystem<ConstraintF>>(
 39        mut cs: CS,
 40        p: &[Self::G1PreparedGadget],
 41        q: &[Self::G2PreparedGadget],
 42    ) -> Result<Self::GTGadget, SynthesisError> {
 43        let miller_result = Self::miller_loop(&mut cs.ns(|| "Miller loop"), p, q)?;
 44        Self::final_exponentiation(&mut cs.ns(|| "Final Exp"), &miller_result)
 45    }
 46
 47    fn prepare_g1<CS: ConstraintSystem<ConstraintF>>(
 48        cs: CS,
 49        q: &Self::G1Gadget,
 50    ) -> Result<Self::G1PreparedGadget, SynthesisError>;
 51
 52    fn prepare_g2<CS: ConstraintSystem<ConstraintF>>(
 53        cs: CS,
 54        q: &Self::G2Gadget,
 55    ) -> Result<Self::G2PreparedGadget, SynthesisError>;
 56}
 57
 58#[cfg(test)]
 59mod test {
 60    // use rand;
 61    use crate::{boolean::Boolean, test_constraint_system::TestConstraintSystem};
 62    use algebra::{BitIterator, Field};
 63    use r1cs_core::ConstraintSystem;
 64
 65    #[test]
 66    fn bls12_377_gadget_bilinearity_test() {
 67        use algebra::{
 68            fields::{bls12_377::{fr::Fr, fq::Fq}, PrimeField},
 69            PairingEngine, ProjectiveCurve,
 70        };
 71
 72        use super::bls12_377::PairingGadget;
 73        use crate::{
 74            fields::FieldGadget,
 75            groups::bls12::bls12_377::{G1Gadget, G1PreparedGadget, G2Gadget, G2PreparedGadget},
 76            pairing::PairingGadget as _,
 77            utils::{AllocGadget, EqGadget},
 78        };
 79        use algebra::curves::bls12_377::{Bls12_377, G1Projective, G2Projective};
 80        use std::ops::Mul;
 81
 82        let mut cs = TestConstraintSystem::<Fq>::new();
 83
 84        // let a: G1Projective = rand::random();
 85        // let b: G2Projective = rand::random();
 86        // let s: Fr = rand::random();
 87
 88        let a: G1Projective = G1Projective::prime_subgroup_generator();
 89        let b: G2Projective = G2Projective::prime_subgroup_generator();
 90        let s: Fr = Fr::one() + &Fr::one();
 91
 92        let sa = a.mul(&s);
 93        let sb = b.mul(&s);
 94
 95        let a_g = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap();
 96        let b_g = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap();
 97        let sa_g = G1Gadget::alloc(&mut cs.ns(|| "sa"), || Ok(sa)).unwrap();
 98        let sb_g = G2Gadget::alloc(&mut cs.ns(|| "sb"), || Ok(sb)).unwrap();
 99
100        let a_prep_g = G1PreparedGadget::from_affine(&mut cs.ns(|| "a_prep"), &a_g).unwrap();
101        let b_prep_g = G2PreparedGadget::from_affine(&mut cs.ns(|| "b_prep"), &b_g).unwrap();
102
103        let sa_prep_g = G1PreparedGadget::from_affine(&mut cs.ns(|| "sa_prep"), &sa_g).unwrap();
104        let sb_prep_g = G2PreparedGadget::from_affine(&mut cs.ns(|| "sb_prep"), &sb_g).unwrap();
105
106        let (ans1_g, ans1_n) = {
107            let ans_g = PairingGadget::pairing(
108                cs.ns(|| "pair(sa, b)"),
109                sa_prep_g.clone(),
110                b_prep_g.clone(),
111            )
112            .unwrap();
113            let ans_n = Bls12_377::pairing(sa, b);
114            (ans_g, ans_n)
115        };
116
117        let (ans2_g, ans2_n) = {
118            let ans_g = PairingGadget::pairing(
119                cs.ns(|| "pair(a, sb)"),
120                a_prep_g.clone(),
121                sb_prep_g.clone(),
122            )
123            .unwrap();
124            let ans_n = Bls12_377::pairing(a, sb);
125            (ans_g, ans_n)
126        };
127
128        let (ans3_g, ans3_n) = {
129            let s_iter = BitIterator::new(s.into_repr())
130                .map(|bit| Boolean::constant(bit))
131                .collect::<Vec<_>>();
132
133            let mut ans_g =
134                PairingGadget::pairing(cs.ns(|| "pair(a, b)"), a_prep_g.clone(), b_prep_g.clone())
135                    .unwrap();
136            let mut ans_n = Bls12_377::pairing(a, b);
137            ans_n = ans_n.pow(s.into_repr());
138            ans_g = ans_g.pow(cs.ns(|| "pow"), &s_iter).unwrap();
139
140            (ans_g, ans_n)
141        };
142
143        assert_eq!(ans1_n, ans2_n, "Failed ans1_native == ans2_native");
144        assert_eq!(ans2_n, ans3_n, "Failed ans2_native == ans3_native");
145        assert_eq!(
146            ans1_g.get_value(),
147            ans3_g.get_value(),
148            "Failed ans1 == ans3"
149        );
150        assert_eq!(
151            ans1_g.get_value(),
152            ans2_g.get_value(),
153            "Failed ans1 == ans2"
154        );
155        assert_eq!(
156            ans2_g.get_value(),
157            ans3_g.get_value(),
158            "Failed ans2 == ans3"
159        );
160
161        ans1_g
162            .enforce_equal(&mut cs.ns(|| "ans1 == ans2?"), &ans2_g)
163            .unwrap();
164        ans2_g
165            .enforce_equal(&mut cs.ns(|| "ans2 == ans3?"), &ans3_g)
166            .unwrap();
167
168        assert_eq!(ans1_g.get_value().unwrap(), ans1_n, "Failed native test 1");
169        assert_eq!(ans2_g.get_value().unwrap(), ans2_n, "Failed native test 2");
170        assert_eq!(ans3_g.get_value().unwrap(), ans3_n, "Failed native test 3");
171
172        if !cs.is_satisfied() {
173            println!("Unsatisfied: {:?}", cs.which_is_unsatisfied());
174        }
175
176        assert!(cs.is_satisfied(), "cs is not satisfied");
177    }
178}