Skip to content

Commit 4451023

Browse files
committed
mul_by_char circuit
1 parent fdcab15 commit 4451023

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/circuits/bn254/pairing.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ pub fn frobenius_in_place(a: ark_bn254::Fq2, power: usize) -> ark_bn254::Fq2 {
149149
ark_bn254::Fq2::new(c0, c1)
150150
}
151151

152+
pub fn frobenius_in_place_circuit(a: Wires, power: usize) -> Circuit {
153+
let mut circuit = Circuit::empty();
154+
let c0 = a[0..Fq::N_BITS].to_vec();
155+
let c1 = a[Fq::N_BITS..2*Fq::N_BITS].to_vec();
156+
let new_c1 = circuit.extend(Fq::mul_by_constant(c1, ark_bn254::Fq2Config::FROBENIUS_COEFF_FP2_C1[power % 2] ));
157+
circuit.add_wires(c0);
158+
circuit.add_wires(new_c1);
159+
circuit
160+
}
161+
152162
pub fn mul_by_char(r: ark_bn254::G2Affine) -> ark_bn254::G2Affine {
153163
let mut s = r;
154164
s.x = frobenius_in_place(s.x, 1);
@@ -158,6 +168,20 @@ pub fn mul_by_char(r: ark_bn254::G2Affine) -> ark_bn254::G2Affine {
158168
s
159169
}
160170

171+
pub fn mul_by_char_circuit(r: Wires) -> Circuit {
172+
let mut circuit = Circuit::empty();
173+
let r_x = r[0..Fq2::N_BITS].to_vec();
174+
let r_y = r[Fq2::N_BITS..2*Fq2::N_BITS].to_vec();
175+
176+
let mut s_x = circuit.extend(frobenius_in_place_circuit(r_x, 1));
177+
s_x = circuit.extend(Fq2::mul_by_constant(s_x, ark_bn254::Config::TWIST_MUL_BY_Q_X.clone()));
178+
let mut s_y = circuit.extend(frobenius_in_place_circuit(r_y, 1));
179+
s_y = circuit.extend(Fq2::mul_by_constant(s_y, ark_bn254::Config::TWIST_MUL_BY_Q_Y.clone()));
180+
circuit.add_wires(s_x);
181+
circuit.add_wires(s_y);
182+
circuit
183+
}
184+
161185
pub fn ell_coeffs(q: ark_bn254::G2Projective) -> Vec<(ark_bn254::Fq2, ark_bn254::Fq2, ark_bn254::Fq2)> {
162186
let q_affine = q.into_affine();
163187
let mut ellc = Vec::new();
@@ -283,6 +307,23 @@ mod tests {
283307
assert_eq!(r.z, new_r_z);
284308
}
285309

310+
#[test]
311+
fn test_mul_by_char_circuit() {
312+
let mut prng = ChaCha20Rng::seed_from_u64(0);
313+
let q = ark_bn254::G2Affine::rand(&mut prng);
314+
315+
let circuit = mul_by_char_circuit(wires_set_from_g2a(q));
316+
circuit.print_gate_type_counts();
317+
for mut gate in circuit.1 {
318+
gate.evaluate();
319+
}
320+
let c0 = fq2_from_wires(circuit.0[0..Fq2::N_BITS].to_vec());
321+
let c1 = fq2_from_wires(circuit.0[Fq2::N_BITS..2*Fq2::N_BITS].to_vec());
322+
let coeffs = mul_by_char(q);
323+
assert_eq!(c0, coeffs.x);
324+
assert_eq!(c1, coeffs.y);
325+
}
326+
286327
#[test]
287328
fn test_miller_loop() {
288329
let mut prng = ChaCha20Rng::seed_from_u64(0);

0 commit comments

Comments
 (0)