1use ruc::*;
2use serde::{Deserialize, Serialize};
3
4use crate::validator::{ValidatorId, ValidatorSet};
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7pub struct Signature(pub Vec<u8>);
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub struct PublicKey(pub Vec<u8>);
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct AggregateSignature {
15 pub signers: Vec<bool>,
16 pub signatures: Vec<Signature>,
17}
18
19impl AggregateSignature {
20 pub fn new(validator_count: usize) -> Self {
21 Self {
22 signers: vec![false; validator_count],
23 signatures: Vec::new(),
24 }
25 }
26
27 pub fn add(&mut self, index: usize, sig: Signature) -> Result<()> {
28 if index >= self.signers.len() {
29 return Err(eg!("signer index out of bounds"));
30 }
31 if self.signers[index] {
32 return Err(eg!("duplicate signature from validator {}", index));
33 }
34 self.signers[index] = true;
35 self.signatures.push(sig);
36 Ok(())
37 }
38
39 pub fn count(&self) -> usize {
40 self.signers.iter().filter(|&&s| s).count()
41 }
42}
43
44pub trait Signer: Send + Sync {
45 fn sign(&self, message: &[u8]) -> Signature;
46 fn public_key(&self) -> PublicKey;
47 fn validator_id(&self) -> ValidatorId;
48}
49
50pub trait Verifier: Send + Sync {
51 fn verify(&self, pk: &PublicKey, msg: &[u8], sig: &Signature) -> bool;
52 fn verify_aggregate(&self, vs: &ValidatorSet, msg: &[u8], agg: &AggregateSignature) -> bool;
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_aggregate_signature_add() {
61 let mut agg = AggregateSignature::new(4);
62 assert_eq!(agg.count(), 0);
63 agg.add(0, Signature(vec![1])).unwrap();
64 assert_eq!(agg.count(), 1);
65 agg.add(2, Signature(vec![2])).unwrap();
66 assert_eq!(agg.count(), 2);
67 }
68
69 #[test]
70 fn test_aggregate_signature_duplicate_rejected() {
71 let mut agg = AggregateSignature::new(4);
72 agg.add(1, Signature(vec![1])).unwrap();
73 assert!(agg.add(1, Signature(vec![2])).is_err());
74 }
75
76 #[test]
77 fn test_aggregate_signature_out_of_bounds() {
78 let mut agg = AggregateSignature::new(3);
79 assert!(agg.add(3, Signature(vec![1])).is_err());
80 assert!(agg.add(100, Signature(vec![1])).is_err());
81 }
82
83 #[test]
84 fn test_aggregate_signature_zero_size() {
85 let agg = AggregateSignature::new(0);
86 assert_eq!(agg.count(), 0);
87 }
88}