Skip to content

Commit dd4c7b8

Browse files
committed
make vdaf::verify_finish take IntoIterator
`verify_finish` wants to consume a collection of `VerifierMessage`. Accomplishing this with `Vec<VerifierMessage>` forces allocation and copying to the heap. We instead take `IntoIterator<Item = VerifierMessage>`, which allows callers to pass either a slice of `VerifierMessage` on the stack or a `Vec` on the heap, or anything else that implements `IntoIterator`. Besides the flexibility, `IntoIterator.into_iter` is infallible, so this doesn't introduce any new error cases to handle.
1 parent e58a06d commit dd4c7b8

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

src/vdaf.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ use crate::prng::{Prng, PrngError};
1515
use crate::vdaf::suite::{Key, KeyDeriver, KeyStream, Suite, SuiteError};
1616
use serde::{Deserialize, Serialize};
1717
use std::convert::TryFrom;
18+
use std::iter::IntoIterator;
1819

1920
/// Errors emitted by this module.
2021
#[derive(Debug, thiserror::Error)]
2122
pub enum VdafError {
2223
/// An error occurred.
23-
#[error("ppm error: {0}")]
24+
#[error("vdaf error: {0}")]
2425
Uncategorized(String),
2526

2627
/// The distributed input was deemed invalid.
@@ -374,15 +375,21 @@ pub fn verify_start<V: Value>(
374375
/// [`VerifierMessage`] messages broadcast by all of the aggregators and produces the aggregator's
375376
/// input share.
376377
// TODO(cjpatton) Check for ciphersuite mismatch between `state` and `msgs` and among `msgs`.
377-
pub fn verify_finish<V: Value>(
378-
state: AggregatorState<V>,
379-
msgs: Vec<VerifierMessage<V::Field>>,
380-
) -> Result<V, VdafError> {
381-
if msgs.is_empty() {
382-
return Err(VdafError::Uncategorized(
383-
"verify_finish(): expected at least one inbound messages; got none".to_string(),
384-
));
385-
}
378+
pub fn verify_finish<M, V>(state: AggregatorState<V>, msgs: M) -> Result<V, VdafError>
379+
where
380+
V: Value,
381+
M: IntoIterator<Item = VerifierMessage<V::Field>>,
382+
{
383+
let mut msgs = msgs.into_iter().peekable();
384+
385+
let verifier_length = match msgs.peek() {
386+
Some(message) => message.verifier_share.as_slice().len(),
387+
None => {
388+
return Err(VdafError::Uncategorized(
389+
"verify_finish(): expected at least one inbound messages; got none".to_string(),
390+
));
391+
}
392+
};
386393

387394
let (input_share, mut joint_rand_seed) = match state {
388395
AggregatorState::Wait {
@@ -398,7 +405,7 @@ pub fn verify_finish<V: Value>(
398405
};
399406

400407
// Combine the verifier messages.
401-
let mut verifier_data = vec![V::Field::zero(); msgs[0].verifier_share.as_slice().len()];
408+
let mut verifier_data = vec![V::Field::zero(); verifier_length];
402409
for msg in msgs {
403410
if msg.verifier_share.as_slice().len() != verifier_data.len() {
404411
return Err(VdafError::Uncategorized(format!(
@@ -446,14 +453,14 @@ mod tests {
446453
#[test]
447454
fn test_prio() {
448455
let suite = Suite::Blake3;
449-
let num_shares = 23;
456+
const NUM_SHARES: usize = 23;
450457
let input: Boolean<Field64> = Boolean::new(true);
451458

452459
// Client runs the input and proof distribution algorithms.
453-
let input_shares = dist_input(suite, &input, num_shares as u8).unwrap();
460+
let input_shares = dist_input(suite, &input, NUM_SHARES as u8).unwrap();
454461

455462
// Aggregators agree on query randomness.
456-
let states = dist_init(suite, (), num_shares).unwrap();
463+
let states = dist_init(suite, (), NUM_SHARES as u8).unwrap();
457464

458465
// Aggregators receive their proof shares and broadcast their verifier messages.
459466
let (states, verifiers): (

0 commit comments

Comments
 (0)