Skip to content

Commit 8eaff99

Browse files
authored
feat: use batch bn256 pair operation (bluealloy#1643)
* feat: use batch bn256 pair operation We are currently not taking advantage of the batch pair operation from the `bn` library for the pairing check precompile. This yields a ~27% speedup on the existing bench: ``` Crypto Precompile benchmarks/precompile bench | ecpairing precompile time: [2.2389 ms 2.2441 ms 2.2495 ms] change: [-27.689% -27.469% -27.227%] (p = 0.00 < 0.05) Performance has improved. ``` * use with_capacity * import vec
1 parent a605d05 commit 8eaff99

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

Diff for: crates/precompile/src/bn128.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
};
55
use bn::{AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2};
66
use revm_primitives::PrecompileOutput;
7+
use std::vec::Vec;
78

89
pub mod add {
910
use super::*;
@@ -179,7 +180,9 @@ pub fn run_pair(
179180
} else {
180181
let elements = input.len() / PAIR_ELEMENT_LEN;
181182

182-
let mut mul = Gt::one();
183+
let mut points = Vec::with_capacity(elements);
184+
185+
// read points
183186
for idx in 0..elements {
184187
let read_fq_at = |n: usize| {
185188
debug_assert!(n < PAIR_ELEMENT_LEN / 32);
@@ -200,16 +203,19 @@ pub fn run_pair(
200203
let b = {
201204
let ba = Fq2::new(bax, bay);
202205
let bb = Fq2::new(bbx, bby);
206+
// TODO: check whether or not we need these zero checks
203207
if ba.is_zero() && bb.is_zero() {
204208
G2::zero()
205209
} else {
206210
G2::from(AffineG2::new(ba, bb).map_err(|_| Error::Bn128AffineGFailedToCreate)?)
207211
}
208212
};
209213

210-
mul = mul * bn::pairing(a, b);
214+
points.push((a, b));
211215
}
212216

217+
let mul = bn::pairing_batch(&points);
218+
213219
mul == Gt::one()
214220
};
215221
Ok(PrecompileOutput::new(gas_used, bool_to_bytes32(success)))

0 commit comments

Comments
 (0)