Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion rust-toolchain

This file was deleted.

46 changes: 37 additions & 9 deletions src/pairing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ use subtle::{Choice, ConditionallySelectable};

use blst::*;

/// Execute a complete pairing operation `(p, q)`.
pub fn pairing(p: &G1Affine, q: &G2Affine) -> Gt {
/// Execute a Miller loop operation `(p, q)`, which is the first part of the
/// full [`pairing`] operation.
pub fn miller_loop(p: &G1Affine, q: &G2Affine) -> MillerLoopResult {
let mut tmp = blst_fp12::default();
unsafe { blst_miller_loop(&mut tmp, &q.0, &p.0) };
MillerLoopResult(Fp12(tmp))
}

let mut out = blst_fp12::default();
unsafe { blst_final_exp(&mut out, &tmp) };

Gt(Fp12(out))
/// Execute a complete pairing operation `(p, q)`.
pub fn pairing(p: &G1Affine, q: &G2Affine) -> Gt {
miller_loop(p, q).final_exponentiation()
}

macro_rules! impl_pairing {
Expand Down Expand Up @@ -146,12 +148,38 @@ pub fn unique_messages(msgs: &[&[u8]]) -> bool {
}

/// Represents results of a Miller loop, one of the most expensive portions
/// of the pairing function. `MillerLoopResult`s cannot be compared with each
/// other until `.final_exponentiation()` is called, which is also expensive.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
/// of the pairing function.
///
/// `MillerLoopResult`s can't be compared together numerically for equality. However, two
/// `MillerLoopResult`s can be compared with [`MillerLoopResult::final_verify`], which is
/// faster than performing [`MillerLoopResult::final_exponentiation`] on both and then comparing
/// the results.
#[derive(Copy, Clone, Debug)]
#[repr(transparent)]
pub struct MillerLoopResult(pub(crate) Fp12);

impl MillerLoopResult {
/// Perform the final exponentiation to convert the Miller loop result
/// into a full pairing result.
pub fn final_exponentiation(&self) -> Gt {
let mut out = blst_fp12::default();
unsafe { blst_final_exp(&mut out, &self.0.0) };
Gt(Fp12(out))
}

pub fn final_verify(&self, other: &MillerLoopResult) -> bool {
unsafe { blst::blst_fp12_finalverify(&self.0.0, &other.0.0) }
}
}

impl PartialEq for MillerLoopResult {
fn eq(&self, other: &Self) -> bool {
self.final_verify(other)
}
}

impl Eq for MillerLoopResult {}

impl ConditionallySelectable for MillerLoopResult {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
MillerLoopResult(Fp12::conditional_select(&a.0, &b.0, choice))
Expand Down