From ffc88ece69e91370359e325ff9d0edc916d5444b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 19 Oct 2023 15:18:40 -0700 Subject: [PATCH] Replace the quadradic duplicate check logic with a linear version It's ~2% slower with 10 hashes and ~2% faster with 100 hashes (with very noisy benchmarks). But the important part is that the runtime should scale linearly with the number of inputs. E.g., this version is 2.5x faster for 1000 signatures. fixes #68 --- src/signature.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/signature.rs b/src/signature.rs index a3f3ed4..f5ffb64 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -1,4 +1,4 @@ -use std::io; +use std::{collections::HashSet, io}; #[cfg(feature = "multicore")] use rayon::prelude::*; @@ -139,12 +139,15 @@ pub fn verify(signature: &Signature, hashes: &[G2Projective], public_keys: &[Pub // Enforce that messages are distinct as a countermeasure against BLS's rogue-key attack. // See Section 3.1. of the IRTF's BLS signatures spec: // https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02#section-3.1 - for i in 0..(n_hashes - 1) { - for j in (i + 1)..n_hashes { - if hashes[i] == hashes[j] { - return false; - } - } + if hashes + .iter() + // This is the best way to get something we can actually hash. + .map(|h| G2Affine::from(h).to_compressed()) + .collect::>() + .len() + != hashes.len() + { + return false; } #[cfg(feature = "multicore")]