falcon_multisig/
address.rs1#[cfg(not(feature = "std"))]
16use alloc::{string::String, vec::Vec};
17
18use sha3::{Digest, Sha3_256};
19
20use crate::keypair::PublicKey;
21
22#[derive(Clone, Debug, PartialEq, Eq, Hash)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31pub struct SingleKeyAddress(String);
32
33impl SingleKeyAddress {
34 pub fn from_public_key(pk: &PublicKey) -> Self {
36 let hash = Sha3_256::digest(pk.as_bytes());
37 Self(format!("0x{}", hex::encode(&hash[..20])))
38 }
39
40 pub fn as_str(&self) -> &str {
42 &self.0
43 }
44}
45
46impl core::fmt::Display for SingleKeyAddress {
47 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
48 f.write_str(&self.0)
49 }
50}
51
52impl AsRef<str> for SingleKeyAddress {
53 fn as_ref(&self) -> &str {
54 &self.0
55 }
56}
57
58#[derive(Clone, Debug, PartialEq, Eq, Hash)]
75#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76pub struct MultisigAddress(String);
77
78impl MultisigAddress {
79 pub fn derive(public_keys: &[PublicKey], required: usize, total: usize) -> Self {
88 let mut sorted: Vec<&[u8]> = public_keys.iter().map(PublicKey::as_bytes).collect();
90 sorted.sort_unstable();
91
92 let mut hasher = Sha3_256::new();
93 hasher.update(&[required as u8, total as u8]);
96 for key in &sorted {
97 hasher.update(key);
98 }
99 let hash = hasher.finalize();
100 Self(format!("ms{}", hex::encode(&hash[..20])))
101 }
102
103 pub fn from_string(s: String) -> Self {
108 Self(s)
109 }
110
111 pub fn as_str(&self) -> &str {
113 &self.0
114 }
115}
116
117impl core::fmt::Display for MultisigAddress {
118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
119 f.write_str(&self.0)
120 }
121}
122
123impl AsRef<str> for MultisigAddress {
124 fn as_ref(&self) -> &str {
125 &self.0
126 }
127}
128
129#[cfg(test)]
134mod tests {
135 use super::*;
136 use crate::keypair::KeyPair;
137
138 #[test]
139 fn single_key_address_prefix() {
140 let kp = KeyPair::generate();
141 let addr = SingleKeyAddress::from_public_key(kp.public_key());
142 assert!(addr.as_str().starts_with("0x"), "single-key address must start with 0x");
143 assert_eq!(addr.as_str().len(), 42, "0x + 40 hex chars = 42");
144 }
145
146 #[test]
147 fn single_key_address_is_deterministic() {
148 let kp = KeyPair::generate();
149 let addr1 = SingleKeyAddress::from_public_key(kp.public_key());
150 let addr2 = SingleKeyAddress::from_public_key(kp.public_key());
151 assert_eq!(addr1, addr2);
152 }
153
154 #[test]
155 fn multisig_address_prefix() {
156 let keys: Vec<PublicKey> = (0..3)
157 .map(|_| KeyPair::generate().public_key().clone())
158 .collect();
159 let addr = MultisigAddress::derive(&keys, 2, 3);
160 assert!(addr.as_str().starts_with("ms"), "multisig address must start with ms");
161 assert_eq!(addr.as_str().len(), 42, "ms + 40 hex chars = 42");
162 }
163
164 #[test]
165 fn multisig_address_order_independent() {
166 let k0 = KeyPair::generate().public_key().clone();
167 let k1 = KeyPair::generate().public_key().clone();
168 let k2 = KeyPair::generate().public_key().clone();
169
170 let order_a = vec![k0.clone(), k1.clone(), k2.clone()];
171 let order_b = vec![k2.clone(), k0.clone(), k1.clone()];
172 let order_c = vec![k1.clone(), k2.clone(), k0.clone()];
173
174 let addr_a = MultisigAddress::derive(&order_a, 2, 3);
175 let addr_b = MultisigAddress::derive(&order_b, 2, 3);
176 let addr_c = MultisigAddress::derive(&order_c, 2, 3);
177
178 assert_eq!(addr_a, addr_b);
179 assert_eq!(addr_b, addr_c);
180 }
181
182 #[test]
183 fn different_policies_different_addresses() {
184 let keys: Vec<PublicKey> = (0..3)
185 .map(|_| KeyPair::generate().public_key().clone())
186 .collect();
187
188 let addr_2of3 = MultisigAddress::derive(&keys, 2, 3);
189 let addr_3of3 = MultisigAddress::derive(&keys, 3, 3);
190
191 assert_ne!(
192 addr_2of3, addr_3of3,
193 "2-of-3 and 3-of-3 must produce different addresses for the same keyset"
194 );
195 }
196
197 #[test]
198 fn different_keysets_different_addresses() {
199 let keys_a: Vec<PublicKey> = (0..3)
200 .map(|_| KeyPair::generate().public_key().clone())
201 .collect();
202 let keys_b: Vec<PublicKey> = (0..3)
203 .map(|_| KeyPair::generate().public_key().clone())
204 .collect();
205
206 let addr_a = MultisigAddress::derive(&keys_a, 2, 3);
207 let addr_b = MultisigAddress::derive(&keys_b, 2, 3);
208
209 assert_ne!(addr_a, addr_b);
210 }
211
212 #[test]
213 fn multisig_address_is_deterministic() {
214 let keys: Vec<PublicKey> = (0..3)
215 .map(|_| KeyPair::generate().public_key().clone())
216 .collect();
217 let a1 = MultisigAddress::derive(&keys, 2, 3);
218 let a2 = MultisigAddress::derive(&keys, 2, 3);
219 assert_eq!(a1, a2);
220 }
221}