Skip to main content
Version: 4.0.0

Pairings

The pairing interface in icicle-core gives you access to efficient bilinear pairings on supported curves (BN254, BLS12-377, BLS12-381, BW6-761, …). Everything is wrapped in a safe, idiomatic Rust layer that automatically moves data between host and device memory when necessary.


Trait & helper function

use icicle_core::{field::Field, projective::Projective};
use icicle_runtime::errors::IcicleError;

pub trait Pairing<P1: Projective, P2: Projective, F: Field> {
fn pairing(p: &P1::Affine, q: &P2::Affine) -> Result<F, IcicleError>;
}

/// Convenience free-function that dispatches to the trait implementation
pub fn pairing<P1, P2, F>(p: &P1::Affine, q: &P2::Affine) -> Result<F, IcicleError>
where
P1: Projective + Pairing<P1, P2, F>,
P2: Projective,
F: Field,
{
P1::pairing(p, q)
}

Each curve crate that supports pairings provides the concrete implementation via the impl_pairing! macro. For BN254 (which is equipped with a single‐thread pairing on G1×G2) the types look like:

use icicle_bn254::curve::{G1Projective, G2Projective};
use icicle_bn254::pairing::PairingTargetField; // 12-degree extension field Fₚ¹²

Example

use icicle_bn254::curve::{G1Projective, G2Projective};
use icicle_core::pairing::pairing; // helper free-function
use icicle_core::traits::GenerateRandom;

// Generate random points (G1 + G2 live in different groups)
let p = G1Projective::generate_random(1)[0].to_affine();
let q = G2Projective::generate_random(1)[0].to_affine();
// Compute the pairing e(P, Q)
let gt = pairing::<G1Projective, G2Projective, _>(&p, &q).unwrap();
println!("e(P, Q) = {:?}", gt);

The return value gt lives in the target field (e.g. Fₚ¹² for BN254/BLS12 curves). The exact name of the type depends on the curve crate – consult the module pairing inside each crate.