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 let pos = self.signers[..index].iter().filter(|&&s| s).count();
38 self.signatures.insert(pos, sig);
39 Ok(())
40 }
41
42 pub fn count(&self) -> usize {
43 self.signers.iter().filter(|&&s| s).count()
44 }
45}
46
47pub trait Signer: Send + Sync {
48 fn sign(&self, message: &[u8]) -> Signature;
49 fn public_key(&self) -> PublicKey;
50 fn validator_id(&self) -> ValidatorId;
51}
52
53pub trait Verifier: Send + Sync {
54 fn verify(&self, pk: &PublicKey, msg: &[u8], sig: &Signature) -> bool;
55 fn verify_aggregate(&self, vs: &ValidatorSet, msg: &[u8], agg: &AggregateSignature) -> bool;
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_aggregate_signature_add() {
64 let mut agg = AggregateSignature::new(4);
65 assert_eq!(agg.count(), 0);
66 agg.add(0, Signature(vec![1])).unwrap();
67 assert_eq!(agg.count(), 1);
68 agg.add(2, Signature(vec![2])).unwrap();
69 assert_eq!(agg.count(), 2);
70 }
71
72 #[test]
73 fn test_aggregate_signature_duplicate_rejected() {
74 let mut agg = AggregateSignature::new(4);
75 agg.add(1, Signature(vec![1])).unwrap();
76 assert!(agg.add(1, Signature(vec![2])).is_err());
77 }
78
79 #[test]
80 fn test_aggregate_signature_out_of_bounds() {
81 let mut agg = AggregateSignature::new(3);
82 assert!(agg.add(3, Signature(vec![1])).is_err());
83 assert!(agg.add(100, Signature(vec![1])).is_err());
84 }
85
86 #[test]
87 fn test_aggregate_signature_zero_size() {
88 let agg = AggregateSignature::new(0);
89 assert_eq!(agg.count(), 0);
90 }
91}