pairing_engine.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the deltavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use crate::traits::{AffineCurve, PairingCurve, ProjectiveCurve}; 17 use deltavm_fields::{Field, PrimeField, SquareRootField, ToConstraintField}; 18 19 use core::{fmt::Debug, hash::Hash, iter}; 20 21 pub trait PairingEngine: Sized + 'static + Copy + Debug + PartialEq + Eq + Hash + Sync + Send { 22 /// This is the scalar field of the G1/G2 groups. 23 type Fr: PrimeField + SquareRootField + Into<<Self::Fr as PrimeField>::BigInteger>; 24 25 /// The projective representation of an element in G1. 26 type G1Projective: ProjectiveCurve<BaseField = Self::Fq, ScalarField = Self::Fr, Affine = Self::G1Affine> 27 + From<Self::G1Affine>; 28 29 /// The affine representation of an element in G1. 30 type G1Affine: AffineCurve<BaseField = Self::Fq, ScalarField = Self::Fr, Projective = Self::G1Projective> 31 + PairingCurve<PairWith = Self::G2Affine, PairingResult = Self::Fqk> 32 + From<Self::G1Projective> 33 + ToConstraintField<Self::Fq>; 34 35 /// The projective representation of an element in G2. 36 type G2Projective: ProjectiveCurve<BaseField = Self::Fqe, ScalarField = Self::Fr, Affine = Self::G2Affine> 37 + From<Self::G2Affine>; 38 39 /// The affine representation of an element in G2. 40 type G2Affine: AffineCurve<BaseField = Self::Fqe, ScalarField = Self::Fr, Projective = Self::G2Projective> 41 + PairingCurve<PairWith = Self::G1Affine, PairingResult = Self::Fqk> 42 + From<Self::G2Projective> 43 + ToConstraintField<Self::Fq>; 44 45 /// The base field that hosts G1. 46 type Fq: PrimeField + SquareRootField; 47 48 /// The extension field that hosts G2. 49 type Fqe: SquareRootField; 50 51 /// The extension field that hosts the target group of the pairing. 52 type Fqk: Field; 53 54 /// Perform a miller loop with some number of (G1, G2) pairs. 55 #[must_use] 56 fn miller_loop<'a, I>(i: I) -> Self::Fqk 57 where 58 I: Iterator< 59 Item = (&'a <Self::G1Affine as PairingCurve>::Prepared, &'a <Self::G2Affine as PairingCurve>::Prepared), 60 >; 61 62 /// Perform final exponentiation of the result of a miller loop. 63 #[must_use] 64 fn final_exponentiation(_: &Self::Fqk) -> Option<Self::Fqk>; 65 66 /// Computes a product of pairings. 67 #[must_use] 68 fn product_of_pairings<'a, I>(i: I) -> Self::Fqk 69 where 70 I: Iterator< 71 Item = (&'a <Self::G1Affine as PairingCurve>::Prepared, &'a <Self::G2Affine as PairingCurve>::Prepared), 72 >, 73 { 74 Self::final_exponentiation(&Self::miller_loop(i)).unwrap() 75 } 76 77 /// Performs multiple pairing operations 78 #[must_use] 79 fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk 80 where 81 G1: Into<Self::G1Affine>, 82 G2: Into<Self::G2Affine>, 83 { 84 Self::final_exponentiation(&Self::miller_loop(iter::once((&p.into().prepare(), &q.into().prepare())))).unwrap() 85 } 86 }