use crate::PrecompileHalt;
use std::vec::Vec;
#[inline]
pub(super) fn pairing_check_bytes_generic<G1, G2, ReadG1, ReadG2, PairingCheck>(
pairs: &[super::PairingPair],
read_g1: ReadG1,
read_g2: ReadG2,
pairing_check: PairingCheck,
) -> Result<bool, PrecompileHalt>
where
ReadG1: Fn(&[u8; 48], &[u8; 48]) -> Result<G1, PrecompileHalt>,
ReadG2: Fn(&[u8; 48], &[u8; 48], &[u8; 48], &[u8; 48]) -> Result<G2, PrecompileHalt>,
PairingCheck: FnOnce(&[(G1, G2)]) -> bool,
{
if pairs.is_empty() {
return Ok(true);
}
let mut parsed_pairs = Vec::with_capacity(pairs.len());
for ((g1_x, g1_y), (g2_x_0, g2_x_1, g2_y_0, g2_y_1)) in pairs {
let g1_is_zero = g1_x.iter().all(|&b| b == 0) && g1_y.iter().all(|&b| b == 0);
let g2_is_zero = g2_x_0.iter().all(|&b| b == 0)
&& g2_x_1.iter().all(|&b| b == 0)
&& g2_y_0.iter().all(|&b| b == 0)
&& g2_y_1.iter().all(|&b| b == 0);
if g1_is_zero || g2_is_zero {
if !g1_is_zero {
let _ = read_g1(g1_x, g1_y)?;
}
if !g2_is_zero {
let _ = read_g2(g2_x_0, g2_x_1, g2_y_0, g2_y_1)?;
}
continue;
}
let g1_point = read_g1(g1_x, g1_y)?;
let g2_point = read_g2(g2_x_0, g2_x_1, g2_y_0, g2_y_1)?;
parsed_pairs.push((g1_point, g2_point));
}
if parsed_pairs.is_empty() {
return Ok(true);
}
Ok(pairing_check(&parsed_pairs))
}