chia_sdk_bindings/
bls.rs

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}