Function ed25519_dalek::verify_batch
source · pub fn verify_batch(
messages: &[&[u8]],
signatures: &[Signature],
verifying_keys: &[VerifyingKey]
) -> Result<(), SignatureError>
batch
only.Expand description
Verify a batch of signatures
on messages
with their respective verifying_keys
.
§Inputs
messages
is a slice of byte slices, one per signed message.signatures
is a slice ofSignature
s.verifying_keys
is a slice ofVerifyingKey
s.
§Returns
- A
Result
whoseOk
value is an empty tuple and whoseErr
value is aSignatureError
containing a description of the internal error which occurred.
§On Deterministic Nonces
The nonces for batch signature verification are derived purely from the inputs to this function themselves.
In any sigma protocol it is wise to include as much context pertaining to the public state in the protocol as possible, to avoid malleability attacks where an adversary alters publics in an algebraic manner that manages to satisfy the equations for the protocol in question.
For ed25519 batch verification we include the following as scalars in the protocol transcript:
- All of the computed
H(R||A||M)
s to the protocol transcript, and - All of the
s
components of each signature.
The former, while not quite as elegant as adding the R
s, A
s, and
M
s separately, saves us a bit of context hashing since the
H(R||A||M)
s need to be computed for the verification equation anyway.
The latter prevents a malleability attack wherein an adversary, without access
to the signing key(s), can take any valid signature, (s,R)
, and swap
s
with s' = -z1
. This doesn’t constitute a signature forgery, merely
a vulnerability, as the resulting signature will not pass single
signature verification. (Thanks to Github users @real_or_random and
@jonasnick for pointing out this malleability issue.)
§Examples
use ed25519_dalek::{
verify_batch, SigningKey, VerifyingKey, Signer, Signature,
};
use rand::rngs::OsRng;
let mut csprng = OsRng;
let signing_keys: Vec<_> = (0..64).map(|_| SigningKey::generate(&mut csprng)).collect();
let msg: &[u8] = b"They're good dogs Brant";
let messages: Vec<_> = (0..64).map(|_| msg).collect();
let signatures: Vec<_> = signing_keys.iter().map(|key| key.sign(&msg)).collect();
let verifying_keys: Vec<_> = signing_keys.iter().map(|key| key.verifying_key()).collect();
let result = verify_batch(&messages, &signatures, &verifying_keys);
assert!(result.is_ok());