code/pallets/drand/src/bls12_381.rs
/*
* Copyright 2024 by Ideal Labs, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use ark_ec::pairing::Pairing;
use ark_std::{Zero, ops::Neg};
use sp_crypto_ec_utils::bls12_381::{
Bls12_381 as Bls12_381Opt, G1Affine as G1AffineOpt, G2Affine as G2AffineOpt,
};
/// An optimized way to verify Drand pulses from quicket
/// Instead of computing two pairings and comparing them, we instead compute a multi miller loop,
/// and then take the final exponentiation, saving a lot of computational cost.
///
/// This function is also inlined as a way to optimize performance.
///
/// * `signature`:
/// * `q`:
/// * `msg_on_curve`: The message signed by Drand, hashed to G1
/// * `p_pub`: The beacon public key
#[inline]
pub fn fast_pairing_opt(
signature: G1AffineOpt,
q: G2AffineOpt,
r: G1AffineOpt,
s: G2AffineOpt,
) -> bool {
let looped = Bls12_381Opt::multi_miller_loop([signature.neg(), r], [q, s]);
let exp = Bls12_381Opt::final_exponentiation(looped);
match exp {
Some(e) => e.is_zero(),
None => false,
}
}