Skip to content

Commit cf0c103

Browse files
committed
ell circuit, Fq12::mul_by_034
1 parent 4451023 commit cf0c103

File tree

4 files changed

+139
-3
lines changed

4 files changed

+139
-3
lines changed

src/circuits/bn254/fq12.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,31 @@ impl Fq12 {
134134
circuit
135135
}
136136

137+
pub fn mul_by_034(a: Wires, c0: Wires, c3: Wires, c4: Wires)-> Circuit {
138+
assert_eq!(a.len(), Self::N_BITS);
139+
assert_eq!(c0.len(), Fq2::N_BITS);
140+
assert_eq!(c3.len(), Fq2::N_BITS);
141+
assert_eq!(c4.len(), Fq2::N_BITS);
142+
let mut circuit = Circuit::empty();
143+
144+
let a_c0 = a[0..Fq6::N_BITS].to_vec();
145+
let a_c1 = a[Fq6::N_BITS..2*Fq6::N_BITS].to_vec();
146+
147+
let wires_1 = circuit.extend(Fq6::mul_by_01(a_c1.clone(), c3.clone(), c4.clone()));
148+
let wires_2 = circuit.extend(Fq6::mul_by_nonresidue(wires_1.clone()));
149+
let wires_3 = circuit.extend(Fq6::mul_by_fq2(a_c0.clone(), c0.clone()));
150+
let new_c0 = circuit.extend(Fq6::add(wires_2.clone(), wires_3.clone()));
151+
let wires_4 = circuit.extend(Fq6::add(a_c0.clone(), a_c1.clone()));
152+
let wires_5 = circuit.extend(Fq2::add(c3.clone(), c0.clone()));
153+
let wires_6 = circuit.extend(Fq6::mul_by_01(wires_4.clone(), wires_5.clone(), c4.clone()));
154+
let wires_7 = circuit.extend(Fq6::add(wires_1, wires_3));
155+
let new_c1 = circuit.extend(Fq6::sub(wires_6, wires_7));
156+
157+
circuit.add_wires(new_c0);
158+
circuit.add_wires(new_c1);
159+
circuit
160+
}
161+
137162
pub fn square(a: Wires) -> Circuit {
138163
assert_eq!(a.len(), Self::N_BITS);
139164
let mut circuit = Circuit::empty();
@@ -271,6 +296,24 @@ mod tests {
271296
assert_eq!(c, b);
272297
}
273298

299+
#[test]
300+
#[serial]
301+
fn test_fq12_mul_by_034() {
302+
let a = random_fq12();
303+
let c0 = random_fq2();
304+
let c3 = random_fq2();
305+
let c4 = random_fq2();
306+
let circuit = Fq12::mul_by_034(wires_set_from_fq12(a.clone()), wires_set_from_fq2(c0.clone()), wires_set_from_fq2(c3.clone()), wires_set_from_fq2(c4.clone()));
307+
circuit.print_gate_type_counts();
308+
for mut gate in circuit.1 {
309+
gate.evaluate();
310+
}
311+
let c = fq12_from_wires(circuit.0);
312+
let mut b = a;
313+
b.mul_by_034(&c0, &c3, &c4);
314+
assert_eq!(c, b);
315+
}
316+
274317
#[test]
275318
#[serial]
276319
fn test_fq12_square() {

src/circuits/bn254/fq2.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,21 @@ impl Fq2 {
152152
circuit
153153
}
154154

155+
pub fn mul_by_fq(a: Wires, b: Wires) -> Circuit {
156+
assert_eq!(a.len(), Self::N_BITS);
157+
assert_eq!(b.len(), Fq::N_BITS);
158+
let mut circuit = Circuit::empty();
159+
160+
let a_c0 = a[0..Fq::N_BITS].to_vec();
161+
let a_c1 = a[Fq::N_BITS..2*Fq::N_BITS].to_vec();
162+
163+
let wires_1 = circuit.extend(Fq::mul(a_c0.clone(), b.clone()));
164+
let wires_2 = circuit.extend(Fq::mul(a_c1.clone(), b.clone()));
165+
circuit.add_wires(wires_1);
166+
circuit.add_wires(wires_2);
167+
circuit
168+
}
169+
155170
pub fn mul_by_constant_fq(a: Wires, b: ark_bn254::Fq) -> Circuit {
156171
assert_eq!(a.len(), Self::N_BITS);
157172
let mut circuit = Circuit::empty();
@@ -238,7 +253,7 @@ impl Fq2 {
238253
#[cfg(test)]
239254
mod tests {
240255
use ark_ff::{AdditiveGroup, Fp6Config};
241-
use crate::circuits::bn254::utils::{fq2_from_wires, random_fq, random_fq2, wires_set_from_fq2};
256+
use crate::circuits::bn254::utils::{fq2_from_wires, random_fq, random_fq2, wires_set_from_fq, wires_set_from_fq2};
242257
use super::*;
243258

244259
#[test]
@@ -329,6 +344,19 @@ mod tests {
329344
assert_eq!(c, a * b);
330345
}
331346

347+
#[test]
348+
fn test_fq2_mul_by_fq() {
349+
let a = random_fq2();
350+
let b = random_fq();
351+
let circuit = Fq2::mul_by_fq(wires_set_from_fq2(a.clone()), wires_set_from_fq(b.clone()));
352+
circuit.print_gate_type_counts();
353+
for mut gate in circuit.1 {
354+
gate.evaluate();
355+
}
356+
let c = fq2_from_wires(circuit.0);
357+
assert_eq!(c, a * ark_bn254::Fq2::new(b, ark_bn254::Fq::ZERO));
358+
}
359+
332360
#[test]
333361
fn test_fq2_mul_by_constant_fq() {
334362
let a = random_fq2();

src/circuits/bn254/fq6.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,24 @@ impl Fq6 {
238238
circuit
239239
}
240240

241+
pub fn mul_by_fq2(a: Wires, b: Wires) -> Circuit {
242+
assert_eq!(a.len(), Self::N_BITS);
243+
assert_eq!(b.len(), Fq2::N_BITS);
244+
let mut circuit = Circuit::empty();
245+
246+
let a_c0 = a[0..Fq2::N_BITS].to_vec();
247+
let a_c1 = a[Fq2::N_BITS..2*Fq2::N_BITS].to_vec();
248+
let a_c2 = a[2*Fq2::N_BITS..3*Fq2::N_BITS].to_vec();
249+
250+
let c0 = circuit.extend(Fq2::mul(a_c0, b.clone()));
251+
let c1 = circuit.extend(Fq2::mul(a_c1, b.clone()));
252+
let c2 = circuit.extend(Fq2::mul(a_c2, b.clone()));
253+
circuit.add_wires(c0);
254+
circuit.add_wires(c1);
255+
circuit.add_wires(c2);
256+
circuit
257+
}
258+
241259
pub fn mul_by_constant_fq2(a: Wires, b: ark_bn254::Fq2) -> Circuit {
242260
assert_eq!(a.len(), Self::N_BITS);
243261
let mut circuit = Circuit::empty();
@@ -454,6 +472,19 @@ mod tests {
454472
assert_eq!(c, a * b);
455473
}
456474

475+
#[test]
476+
fn test_fq6_mul_by_fq2() {
477+
let a = random_fq6();
478+
let b = random_fq2();
479+
let circuit = Fq6::mul_by_fq2(wires_set_from_fq6(a.clone()), wires_set_from_fq2(b.clone()));
480+
circuit.print_gate_type_counts();
481+
for mut gate in circuit.1 {
482+
gate.evaluate();
483+
}
484+
let c = fq6_from_wires(circuit.0);
485+
assert_eq!(c, a * ark_bn254::Fq6::new(b, ark_bn254::Fq2::ZERO, ark_bn254::Fq2::ZERO));
486+
}
487+
457488
#[test]
458489
fn test_fq6_mul_by_constant_fq2() {
459490
let a = random_fq6();

src/circuits/bn254/pairing.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use ark_ec::{bn::BnConfig, short_weierstrass::SWCurveConfig, CurveGroup};
22
use ark_ff::{AdditiveGroup, Field, Fp2Config};
3-
use crate::{bag::*, circuits::bn254::{fp254impl::Fp254Impl, fq::Fq, fq2::Fq2}};
3+
use crate::{bag::*, circuits::bn254::{fp254impl::Fp254Impl, fq::Fq, fq12::Fq12, fq2::Fq2}};
44

55
pub fn double_in_place(r: &mut ark_bn254::G2Projective) -> (ark_bn254::Fq2, ark_bn254::Fq2, ark_bn254::Fq2) {
66
let half = ark_bn254::Fq::from(Fq::half_modulus());
@@ -222,6 +222,23 @@ pub fn ell(f: &mut ark_bn254::Fq12, coeffs: (ark_bn254::Fq2, ark_bn254::Fq2, ark
222222
f.mul_by_034(&c0, &c1, &c2);
223223
}
224224

225+
pub fn ell_circuit(f: Wires, coeffs: (Wires, Wires, Wires), p: Wires) -> Circuit {
226+
let mut circuit = Circuit::empty();
227+
let c0 = coeffs.0;
228+
let c1 = coeffs.1;
229+
let c2 = coeffs.2;
230+
231+
let px = p[0..Fq::N_BITS].to_vec();
232+
let py = p[Fq::N_BITS..2*Fq::N_BITS].to_vec();
233+
234+
let new_c0 = circuit.extend(Fq2::mul_by_fq(c0, py));
235+
let new_c1 = circuit.extend(Fq2::mul_by_fq(c1, px));
236+
let new_f = circuit.extend(Fq12::mul_by_034(f, new_c0, new_c1, c2));
237+
238+
circuit.add_wires(new_f);
239+
circuit
240+
}
241+
225242
pub fn miller_loop(p: ark_bn254::G1Projective, q: ark_bn254::G2Projective) -> ark_bn254::Fq12 {
226243
let qell = ell_coeffs(q);
227244
let mut q_ell = qell.iter();
@@ -253,7 +270,7 @@ mod tests {
253270
use ark_std::rand::SeedableRng;
254271
use ark_ec::pairing::Pairing;
255272
use rand_chacha::ChaCha20Rng;
256-
use crate::circuits::bn254::utils::{fq2_from_wires, wires_set_from_g2a, wires_set_from_g2p};
273+
use crate::circuits::bn254::utils::{fq12_from_wires, fq2_from_wires, wires_set_from_fq12, wires_set_from_fq2, wires_set_from_g1p, wires_set_from_g2a, wires_set_from_g2p};
257274
use super::*;
258275

259276
#[test]
@@ -324,6 +341,23 @@ mod tests {
324341
assert_eq!(c1, coeffs.y);
325342
}
326343

344+
#[test]
345+
fn test_ell_circuit() {
346+
let mut prng = ChaCha20Rng::seed_from_u64(0);
347+
let mut f = ark_bn254::Fq12::rand(&mut prng);
348+
let coeffs = (ark_bn254::Fq2::rand(&mut prng), ark_bn254::Fq2::rand(&mut prng), ark_bn254::Fq2::rand(&mut prng));
349+
let p = ark_bn254::G1Projective::rand(&mut prng);
350+
351+
let circuit = ell_circuit(wires_set_from_fq12(f), (wires_set_from_fq2(coeffs.0), wires_set_from_fq2(coeffs.1), wires_set_from_fq2(coeffs.2)), wires_set_from_g1p(p));
352+
circuit.print_gate_type_counts();
353+
for mut gate in circuit.1 {
354+
gate.evaluate();
355+
}
356+
let new_f = fq12_from_wires(circuit.0);
357+
ell(&mut f, coeffs, p);
358+
assert_eq!(f, new_f);
359+
}
360+
327361
#[test]
328362
fn test_miller_loop() {
329363
let mut prng = ChaCha20Rng::seed_from_u64(0);

0 commit comments

Comments
 (0)