Skip to content

Commit

Permalink
Implements pairing via garaga_rs
Browse files Browse the repository at this point in the history
  • Loading branch information
raugfer committed Aug 8, 2024
1 parent abafb14 commit eef53f0
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 7 deletions.
78 changes: 77 additions & 1 deletion tools/garaga_rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod bn254_final_exp_witness;
pub mod bls12_381_final_exp_witness;

use ark_ec::AffineRepr;
use ark_ec::{AffineRepr, pairing::Pairing};
use ark_ff::PrimeField;
use num_bigint::BigUint;
use lambdaworks_crypto::hash::poseidon::{starknet::PoseidonCairoStark252, Poseidon};
Expand All @@ -20,6 +20,7 @@ use pyo3::{
fn garaga_rs(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(g2_add, m)?)?;
m.add_function(wrap_pyfunction!(g2_scalar_mul, m)?)?;
m.add_function(wrap_pyfunction!(multi_pairing, m)?)?;
m.add_function(wrap_pyfunction!(get_final_exp_witness, m)?)?;
m.add_function(wrap_pyfunction!(hades_permutation, m)?)?;
Ok(())
Expand Down Expand Up @@ -117,6 +118,81 @@ fn g2_scalar_mul(py: Python, curve_id: usize, py_tuple_1: &PyTuple, py_int_2: &P
panic!("Curve ID {} not supported", curve_id);
}

#[pyfunction]
fn multi_pairing(py: Python, curve_id: usize, py_list_1: &PyList) -> PyResult<PyObject> {
assert!(py_list_1.len() % 6 == 0, "invalid length");

if curve_id == CURVE_BN254 {
use ark_bn254::{Bn254, Fq, Fq2, Fq12, G1Affine, G2Affine};
let mut a_list = Vec::new();
let mut b_list = Vec::new();
for i in (0..py_list_1.len()).step_by(6) {
let a_0: BigUint = py_list_1[i + 0].extract()?;
let a_1: BigUint = py_list_1[i + 1].extract()?;
let b_0: BigUint = py_list_1[i + 2].extract()?;
let b_1: BigUint = py_list_1[i + 3].extract()?;
let b_2: BigUint = py_list_1[i + 4].extract()?;
let b_3: BigUint = py_list_1[i + 5].extract()?;
let a = G1Affine::new(Fq::from(a_0), Fq::from(a_1));
let b = G2Affine::new(
Fq2::new(Fq::from(b_0), Fq::from(b_1)),
Fq2::new(Fq::from(b_2), Fq::from(b_3)),
);
a_list.push(a);
b_list.push(b);
}
let c = Bn254::multi_pairing(a_list, b_list);
fn to(v: Fq12) -> [BigUint; 12] {
[
BigUint::from(v.c0.c0.c0.into_bigint()), BigUint::from(v.c0.c0.c1.into_bigint()),
BigUint::from(v.c0.c1.c0.into_bigint()), BigUint::from(v.c0.c1.c1.into_bigint()),
BigUint::from(v.c0.c2.c0.into_bigint()), BigUint::from(v.c0.c2.c1.into_bigint()),
BigUint::from(v.c1.c0.c0.into_bigint()), BigUint::from(v.c1.c0.c1.into_bigint()),
BigUint::from(v.c1.c1.c0.into_bigint()), BigUint::from(v.c1.c1.c1.into_bigint()),
BigUint::from(v.c1.c2.c0.into_bigint()), BigUint::from(v.c1.c2.c1.into_bigint()),
]
}
let py_list = PyList::new(py, to(c.0));
return Ok(py_list.into());
}

if curve_id == CURVE_BLS12_381 {
use ark_bls12_381::{Bls12_381, Fq, Fq2, Fq12, G1Affine, G2Affine};
let mut a_list = Vec::new();
let mut b_list = Vec::new();
for i in (0..py_list_1.len()).step_by(6) {
let a_0: BigUint = py_list_1[i + 0].extract()?;
let a_1: BigUint = py_list_1[i + 1].extract()?;
let b_0: BigUint = py_list_1[i + 2].extract()?;
let b_1: BigUint = py_list_1[i + 3].extract()?;
let b_2: BigUint = py_list_1[i + 4].extract()?;
let b_3: BigUint = py_list_1[i + 5].extract()?;
let a = G1Affine::new(Fq::from(a_0), Fq::from(a_1));
let b = G2Affine::new(
Fq2::new(Fq::from(b_0), Fq::from(b_1)),
Fq2::new(Fq::from(b_2), Fq::from(b_3)),
);
a_list.push(a);
b_list.push(b);
}
let c = Bls12_381::multi_pairing(a_list, b_list);
fn to(v: Fq12) -> [BigUint; 12] {
[
BigUint::from(v.c0.c0.c0.into_bigint()), BigUint::from(v.c0.c0.c1.into_bigint()),
BigUint::from(v.c0.c1.c0.into_bigint()), BigUint::from(v.c0.c1.c1.into_bigint()),
BigUint::from(v.c0.c2.c0.into_bigint()), BigUint::from(v.c0.c2.c1.into_bigint()),
BigUint::from(v.c1.c0.c0.into_bigint()), BigUint::from(v.c1.c0.c1.into_bigint()),
BigUint::from(v.c1.c1.c0.into_bigint()), BigUint::from(v.c1.c1.c1.into_bigint()),
BigUint::from(v.c1.c2.c0.into_bigint()), BigUint::from(v.c1.c2.c1.into_bigint()),
]
}
let py_list = PyList::new(py, to(c.0));
return Ok(py_list.into());
}

panic!("Curve ID {} not supported", curve_id);
}

#[pyfunction]
fn get_final_exp_witness(py: Python, curve_id: usize, py_list: &PyList) -> PyResult<PyObject> {
let f_0: BigUint = py_list[0].extract()?;
Expand Down
7 changes: 1 addition & 6 deletions tools/gnark_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,7 @@ def pair(self, input: list[int], n_pairs: int, raw: bool = True):
assert (
len(input) == 6 * n_pairs
), f"Expected {6 * n_pairs} input points, got {len(input)}"
args = ["n_pair", "pair", str(n_pairs)]
for x in input:
args.append(str(x))
output = self.run_command(args)
res = self.parse_fp_elements(output)
assert len(res) == 12, f"Got {output}"
res = garaga_rs.multi_pairing(self.curve.id, input)
if raw:
return res
return E12(res, self.curve_id.value)
Expand Down

0 comments on commit eef53f0

Please sign in to comment.