openvm_pairing_guest/pairing/
mod.rs1mod final_exp;
2mod line;
3mod miller_loop;
4mod miller_step;
5
6pub use final_exp::*;
7pub use line::*;
8pub use miller_loop::*;
9pub use miller_step::*;
10use openvm_algebra_guest::{
11 field::{ComplexConjugate, FieldExtension},
12 ExpBytes, Field, IntMod,
13};
14use openvm_ecc_guest::AffinePoint;
15
16use crate::PairingBaseFunct7;
17
18pub trait PairingIntrinsics {
19 type Fp: Field + IntMod;
20 type Fp2: Field + FieldExtension<Self::Fp> + ComplexConjugate;
21 type Fp12: FieldExtension<Self::Fp2> + ComplexConjugate;
22
23 const PAIRING_IDX: usize;
25 const XI: Self::Fp2;
27 const FROBENIUS_COEFFS: [[Self::Fp2; 5]; 12];
30
31 const FP2_TWO: Self::Fp2;
32 const FP2_THREE: Self::Fp2;
33}
34
35#[allow(non_snake_case)]
36pub trait PairingCheck {
37 type Fp: Field;
38 type Fp2: Field + FieldExtension<Self::Fp> + ComplexConjugate;
39 type Fp12: FieldExtension<Self::Fp2> + ComplexConjugate;
40
41 fn pairing_check_hint(
53 P: &[AffinePoint<Self::Fp>],
54 Q: &[AffinePoint<Self::Fp2>],
55 ) -> (Self::Fp12, Self::Fp12);
56
57 fn pairing_check(
66 P: &[AffinePoint<Self::Fp>],
67 Q: &[AffinePoint<Self::Fp2>],
68 ) -> Result<(), PairingCheckError>;
69}
70
71pub fn exp_check_fallback<F: Field + ExpBytes>(f: &F, exp: &[u8]) -> Result<(), PairingCheckError>
75where
76 for<'a> &'a F: core::ops::Mul<&'a F, Output = F>,
77{
78 if f.exp_bytes(true, exp) == F::ONE {
79 Ok(())
80 } else {
81 Err(PairingCheckError)
82 }
83}
84
85pub const fn shifted_funct7<P: PairingIntrinsics>(funct7: PairingBaseFunct7) -> usize {
86 P::PAIRING_IDX * (PairingBaseFunct7::PAIRING_MAX_KINDS as usize) + funct7 as usize
87}
88
89#[derive(Debug, Clone, PartialEq)]
90pub struct PairingCheckError;
91
92impl core::error::Error for PairingCheckError {}
93impl core::fmt::Display for PairingCheckError {
94 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95 write!(f, "Pairing check failed")
96 }
97}
98
99#[cfg(all(test, not(target_os = "zkvm")))]
100mod tests {
101 use num_bigint::BigUint;
102 use openvm_algebra_moduli_macros::{moduli_declare, moduli_init};
103
104 use super::*;
105
106 moduli_declare! {
107 F13 { modulus = "13" },
108 }
109
110 moduli_init! {
111 "13",
112 }
113
114 #[test]
115 fn test_pairing_check_fallback() {
116 let a = F13::from_u8(2);
117 let b = BigUint::from(12u32);
118 let result = exp_check_fallback(&a, &b.to_bytes_be());
119 assert_eq!(result, Ok(()));
120
121 let b = BigUint::from(11u32);
122 let result = exp_check_fallback(&a, &b.to_bytes_be());
123 assert_eq!(result, Err(PairingCheckError));
124 }
125}