1use bindy::Result;
2use chia_bls::{DerivableKey, PublicKey, SecretKey, Signature, aggregate_verify, sign, verify};
3use chia_protocol::{Bytes, Bytes32, Bytes48, Bytes96};
4use chia_puzzle_types::DeriveSynthetic;
5
6pub trait SecretKeyExt: Sized {
7 fn from_seed(seed: Bytes) -> Result<Self>;
8 fn from_bytes(bytes: Bytes32) -> Result<Self>;
9 fn to_bytes(&self) -> Result<Bytes32>;
10 fn public_key(&self) -> Result<PublicKey>;
11 fn sign(&self, message: Bytes) -> Result<Signature>;
12 fn derive_unhardened(&self, index: u32) -> Result<Self>;
13 fn derive_hardened(&self, index: u32) -> Result<Self>;
14 fn derive_unhardened_path(&self, path: Vec<u32>) -> Result<Self>;
15 fn derive_hardened_path(&self, path: Vec<u32>) -> Result<Self>;
16 fn derive_synthetic(&self) -> Result<Self>;
17 fn derive_synthetic_hidden(&self, hidden_puzzle_hash: Bytes32) -> Result<Self>;
18}
19
20impl SecretKeyExt for SecretKey {
21 fn from_seed(seed: Bytes) -> Result<Self> {
22 Ok(Self::from_seed(&seed))
23 }
24
25 fn from_bytes(bytes: Bytes32) -> Result<Self> {
26 Ok(Self::from_bytes(&bytes.to_bytes())?)
27 }
28
29 fn to_bytes(&self) -> Result<Bytes32> {
30 Ok(Bytes32::new(self.to_bytes()))
31 }
32
33 fn public_key(&self) -> Result<PublicKey> {
34 Ok(self.public_key())
35 }
36
37 fn sign(&self, message: Bytes) -> Result<Signature> {
38 Ok(sign(self, message))
39 }
40
41 fn derive_unhardened(&self, index: u32) -> Result<Self> {
42 Ok(DerivableKey::derive_unhardened(self, index))
43 }
44
45 fn derive_hardened(&self, index: u32) -> Result<Self> {
46 Ok(self.derive_hardened(index))
47 }
48
49 fn derive_unhardened_path(&self, path: Vec<u32>) -> Result<Self> {
50 let mut result = self.clone();
51
52 for index in path {
53 result = DerivableKey::derive_unhardened(&result, index);
54 }
55
56 Ok(result)
57 }
58
59 fn derive_hardened_path(&self, path: Vec<u32>) -> Result<Self> {
60 let mut result = self.clone();
61
62 for index in path {
63 result = result.derive_hardened(index);
64 }
65
66 Ok(result)
67 }
68
69 fn derive_synthetic(&self) -> Result<Self> {
70 Ok(DeriveSynthetic::derive_synthetic(self))
71 }
72
73 fn derive_synthetic_hidden(&self, hidden_puzzle_hash: Bytes32) -> Result<Self> {
74 Ok(DeriveSynthetic::derive_synthetic_hidden(
75 self,
76 &hidden_puzzle_hash.to_bytes(),
77 ))
78 }
79}
80
81pub trait PublicKeyExt: Sized {
82 fn infinity() -> Result<Self>;
83 fn aggregate(public_keys: Vec<Self>) -> Result<Self>;
84 fn aggregate_verify(
85 public_keys: Vec<Self>,
86 messages: Vec<Bytes>,
87 signature: Signature,
88 ) -> Result<bool>;
89 fn from_bytes(bytes: Bytes48) -> Result<Self>;
90 fn to_bytes(&self) -> Result<Bytes48>;
91 fn verify(&self, message: Bytes, signature: Signature) -> Result<bool>;
92 fn fingerprint(&self) -> Result<u32>;
93 fn is_infinity(&self) -> Result<bool>;
94 fn is_valid(&self) -> Result<bool>;
95 fn derive_unhardened(&self, index: u32) -> Result<Self>;
96 fn derive_unhardened_path(&self, path: Vec<u32>) -> Result<Self>;
97 fn derive_synthetic(&self) -> Result<Self>;
98 fn derive_synthetic_hidden(&self, hidden_puzzle_hash: Bytes32) -> Result<Self>;
99}
100
101impl PublicKeyExt for PublicKey {
102 fn infinity() -> Result<Self> {
103 Ok(Self::default())
104 }
105
106 fn aggregate(mut public_keys: Vec<Self>) -> Result<Self> {
107 if public_keys.is_empty() {
108 return Self::infinity();
109 }
110
111 let mut result = public_keys.remove(0);
112
113 for pk in public_keys {
114 result += &pk;
115 }
116
117 Ok(result)
118 }
119
120 fn aggregate_verify(
121 public_keys: Vec<Self>,
122 messages: Vec<Bytes>,
123 signature: Signature,
124 ) -> Result<bool> {
125 Ok(aggregate_verify(
126 &signature,
127 public_keys.iter().zip(messages.iter().map(Bytes::as_slice)),
128 ))
129 }
130
131 fn from_bytes(bytes: Bytes48) -> Result<Self> {
132 Ok(Self::from_bytes(&bytes.to_bytes())?)
133 }
134
135 fn to_bytes(&self) -> Result<Bytes48> {
136 Ok(Bytes48::new(self.to_bytes()))
137 }
138
139 fn verify(&self, message: Bytes, signature: Signature) -> Result<bool> {
140 Ok(verify(&signature, self, message))
141 }
142
143 fn fingerprint(&self) -> Result<u32> {
144 Ok(self.get_fingerprint())
145 }
146
147 fn is_infinity(&self) -> Result<bool> {
148 Ok(self.is_inf())
149 }
150
151 fn is_valid(&self) -> Result<bool> {
152 Ok(self.is_valid())
153 }
154
155 fn derive_unhardened(&self, index: u32) -> Result<Self> {
156 Ok(DerivableKey::derive_unhardened(self, index))
157 }
158
159 fn derive_unhardened_path(&self, path: Vec<u32>) -> Result<Self> {
160 let mut result = *self;
161
162 for index in path {
163 result = DerivableKey::derive_unhardened(&result, index);
164 }
165
166 Ok(result)
167 }
168
169 fn derive_synthetic(&self) -> Result<Self> {
170 Ok(DeriveSynthetic::derive_synthetic(self))
171 }
172
173 fn derive_synthetic_hidden(&self, hidden_puzzle_hash: Bytes32) -> Result<Self> {
174 Ok(DeriveSynthetic::derive_synthetic_hidden(
175 self,
176 &hidden_puzzle_hash.to_bytes(),
177 ))
178 }
179}
180
181pub trait SignatureExt: Sized {
182 fn infinity() -> Result<Self>;
183 fn aggregate(signatures: Vec<Self>) -> Result<Self>;
184 fn from_bytes(bytes: Bytes96) -> Result<Self>;
185 fn to_bytes(&self) -> Result<Bytes96>;
186 fn is_infinity(&self) -> Result<bool>;
187 fn is_valid(&self) -> Result<bool>;
188}
189
190impl SignatureExt for Signature {
191 fn infinity() -> Result<Self> {
192 Ok(Self::default())
193 }
194
195 fn aggregate(mut signatures: Vec<Self>) -> Result<Self> {
196 if signatures.is_empty() {
197 return Self::infinity();
198 }
199
200 let mut result = signatures.remove(0);
201
202 for sig in signatures {
203 result += &sig;
204 }
205
206 Ok(result)
207 }
208
209 fn from_bytes(bytes: Bytes96) -> Result<Self> {
210 Ok(Self::from_bytes(&bytes.to_bytes())?)
211 }
212
213 fn to_bytes(&self) -> Result<Bytes96> {
214 Ok(Bytes96::new(self.to_bytes()))
215 }
216
217 fn is_infinity(&self) -> Result<bool> {
218 Ok(self == &Self::default())
219 }
220
221 fn is_valid(&self) -> Result<bool> {
222 Ok(self.is_valid())
223 }
224}