mithril_stm/protocol/aggregate_signature/
aggregate_key.rs1use serde::{Deserialize, Serialize};
2
3use crate::{
4 ClosedKeyRegistration, MembershipDigest, Stake,
5 membership_commitment::{
6 MerkleBatchPath, MerkleTreeBatchCommitment, MerkleTreeConcatenationLeaf,
7 },
8};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(bound(
14 serialize = "MerkleBatchPath<D::ConcatenationHash>: Serialize",
15 deserialize = "MerkleBatchPath<D::ConcatenationHash>: Deserialize<'de>"
16))]
17pub struct AggregateVerificationKey<D: MembershipDigest> {
18 mt_commitment: MerkleTreeBatchCommitment<D::ConcatenationHash, MerkleTreeConcatenationLeaf>,
19 total_stake: Stake,
20}
21
22impl<D: MembershipDigest> AggregateVerificationKey<D> {
23 pub(crate) fn get_merkle_tree_batch_commitment(
24 &self,
25 ) -> MerkleTreeBatchCommitment<D::ConcatenationHash, MerkleTreeConcatenationLeaf> {
26 self.mt_commitment.clone()
27 }
28
29 pub fn get_total_stake(&self) -> Stake {
30 self.total_stake
31 }
32}
33
34impl<D: MembershipDigest> PartialEq for AggregateVerificationKey<D> {
35 fn eq(&self, other: &Self) -> bool {
36 self.mt_commitment == other.mt_commitment && self.total_stake == other.total_stake
37 }
38}
39
40impl<D: MembershipDigest> Eq for AggregateVerificationKey<D> {}
41
42impl<D: MembershipDigest> From<&ClosedKeyRegistration<D>> for AggregateVerificationKey<D> {
43 fn from(reg: &ClosedKeyRegistration<D>) -> Self {
44 Self {
45 mt_commitment: reg.merkle_tree.to_merkle_tree_batch_commitment(),
46 total_stake: reg.total_stake,
47 }
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use rand_chacha::ChaCha20Rng;
54 use rand_core::SeedableRng;
55
56 use super::*;
57
58 mod golden {
59
60 use crate::{Clerk, Initializer, KeyRegistration, MithrilMembershipDigest, Parameters};
61
62 use super::*;
63
64 const GOLDEN_JSON: &str = r#"
65 {
66 "mt_commitment":{
67 "root":[4,3,108,183,145,65,166,69,250,202,51,64,90,232,45,103,56,138,102,63,209,245,81,22,120,16,6,96,140,204,210,55],
68 "nr_leaves":4,
69 "hasher":null
70 },
71 "total_stake":6
72 }"#;
73
74 fn golden_value() -> AggregateVerificationKey<MithrilMembershipDigest> {
75 let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
76 let params = Parameters {
77 m: 10,
78 k: 5,
79 phi_f: 0.8,
80 };
81 let number_of_parties = 4;
82 let mut key_reg = KeyRegistration::init();
83 for stake in 0..number_of_parties {
84 let initializer = Initializer::new(params, stake, &mut rng);
85 key_reg.register(initializer.stake, initializer.pk).unwrap();
86 }
87
88 let closed_key_reg: ClosedKeyRegistration<MithrilMembershipDigest> = key_reg.close();
89 let clerk = Clerk::new_clerk_from_closed_key_registration(¶ms, &closed_key_reg);
90 clerk.compute_aggregate_verification_key()
91 }
92
93 #[test]
94 fn golden_conversions() {
95 let value = serde_json::from_str(GOLDEN_JSON)
96 .expect("This JSON deserialization should not fail");
97 assert_eq!(golden_value(), value);
98
99 let serialized =
100 serde_json::to_string(&value).expect("This JSON serialization should not fail");
101 let golden_serialized = serde_json::to_string(&golden_value())
102 .expect("This JSON serialization should not fail");
103 assert_eq!(golden_serialized, serialized);
104 }
105 }
106}