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}