1use alloy::primitives::U256;
10use ark_serialize::SerializationError;
11use bitvec::{slice::BitSlice, vec::BitVec};
12use digest::generic_array::GenericArray;
13use jf_signature::{
14 bls_over_bn254::{BLSOverBN254CurveSignatureScheme, KeyPair, SignKey, VerKey},
15 SignatureError, SignatureScheme,
16};
17use rand::SeedableRng;
18use rand_chacha::ChaCha20Rng;
19use tracing::instrument;
20
21use crate::{
22 light_client::{CircuitField, LightClientState, StakeTableState},
23 qc::{BitVectorQc, QcParams},
24 stake_table::StakeTableEntry,
25 traits::{
26 qc::QuorumCertificateScheme,
27 signature_key::{
28 BuilderSignatureKey, LCV1StateSignatureKey, LCV2StateSignatureKey,
29 LCV3StateSignatureKey, PrivateSignatureKey, SignatureKey, StateSignatureKey,
30 },
31 },
32};
33
34pub type BLSPrivKey = SignKey;
36pub type BLSPubKey = VerKey;
38pub type BLSKeyPair = KeyPair;
40pub type BLSPublicParam = ();
42pub type BLSSignature = jf_signature::bls_over_bn254::Signature;
44
45impl PrivateSignatureKey for BLSPrivKey {
46 fn to_bytes(&self) -> Vec<u8> {
47 self.to_bytes()
48 }
49
50 fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
51 Ok(Self::from_bytes(bytes))
52 }
53
54 fn to_tagged_base64(&self) -> Result<tagged_base64::TaggedBase64, tagged_base64::Tb64Error> {
55 self.to_tagged_base64()
56 }
57}
58
59impl SignatureKey for BLSPubKey {
60 type PrivateKey = BLSPrivKey;
61 type StakeTableEntry = StakeTableEntry<VerKey>;
62 type QcParams<'a> = QcParams<
63 'a,
64 BLSPubKey,
65 <BLSOverBN254CurveSignatureScheme as SignatureScheme>::PublicParameter,
66 >;
67 type PureAssembledSignatureType =
68 <BLSOverBN254CurveSignatureScheme as SignatureScheme>::Signature;
69 type QcType = (Self::PureAssembledSignatureType, BitVec);
70 type SignError = SignatureError;
71
72 #[instrument(skip(self))]
73 fn validate(&self, signature: &Self::PureAssembledSignatureType, data: &[u8]) -> bool {
74 BLSOverBN254CurveSignatureScheme::verify(&(), self, data, signature).is_ok()
76 }
77
78 fn sign(
79 sk: &Self::PrivateKey,
80 data: &[u8],
81 ) -> Result<Self::PureAssembledSignatureType, Self::SignError> {
82 BitVectorQc::<BLSOverBN254CurveSignatureScheme>::sign(
83 &(),
84 sk,
85 data,
86 &mut rand::thread_rng(),
87 )
88 }
89
90 fn from_private(private_key: &Self::PrivateKey) -> Self {
91 BLSPubKey::from(private_key)
92 }
93
94 fn to_bytes(&self) -> Vec<u8> {
95 let mut buf = vec![];
96 ark_serialize::CanonicalSerialize::serialize_compressed(self, &mut buf)
97 .expect("Serialization should not fail.");
98 buf
99 }
100
101 fn from_bytes(bytes: &[u8]) -> Result<Self, SerializationError> {
102 ark_serialize::CanonicalDeserialize::deserialize_compressed(bytes)
103 }
104
105 fn generated_from_seed_indexed(seed: [u8; 32], index: u64) -> (Self, Self::PrivateKey) {
106 let mut hasher = blake3::Hasher::new();
107 hasher.update(&seed);
108 hasher.update(&index.to_le_bytes());
109 let new_seed = *hasher.finalize().as_bytes();
110 let kp = KeyPair::generate(&mut ChaCha20Rng::from_seed(new_seed));
111 (kp.ver_key(), kp.sign_key_ref().clone())
112 }
113
114 fn stake_table_entry(&self, stake: U256) -> Self::StakeTableEntry {
115 StakeTableEntry {
116 stake_key: *self,
117 stake_amount: stake,
118 }
119 }
120
121 fn public_key(entry: &Self::StakeTableEntry) -> Self {
122 entry.stake_key
123 }
124
125 fn public_parameter(
126 stake_entries: &'_ [Self::StakeTableEntry],
127 threshold: U256,
128 ) -> Self::QcParams<'_> {
129 QcParams {
130 stake_entries,
131 threshold,
132 agg_sig_pp: (),
133 }
134 }
135
136 fn check(
137 real_qc_pp: &Self::QcParams<'_>,
138 data: &[u8],
139 qc: &Self::QcType,
140 ) -> Result<(), SignatureError> {
141 let msg = GenericArray::from_slice(data);
142 BitVectorQc::<BLSOverBN254CurveSignatureScheme>::check(real_qc_pp, msg, qc).map(|_| ())
143 }
144
145 fn sig_proof(signature: &Self::QcType) -> (Self::PureAssembledSignatureType, BitVec) {
146 signature.clone()
147 }
148
149 fn assemble(
150 real_qc_pp: &Self::QcParams<'_>,
151 signers: &BitSlice,
152 sigs: &[Self::PureAssembledSignatureType],
153 ) -> Self::QcType {
154 BitVectorQc::<BLSOverBN254CurveSignatureScheme>::assemble(real_qc_pp, signers, sigs)
155 .expect("this assembling shouldn't fail")
156 }
157
158 fn genesis_proposer_pk() -> Self {
159 let kp = KeyPair::generate(&mut ChaCha20Rng::from_seed([0u8; 32]));
160 kp.ver_key()
161 }
162}
163
164pub type BuilderKey = BLSPubKey;
168
169impl BuilderSignatureKey for BuilderKey {
170 type BuilderPrivateKey = BLSPrivKey;
171 type BuilderSignature = <BLSOverBN254CurveSignatureScheme as SignatureScheme>::Signature;
172 type SignError = SignatureError;
173
174 fn sign_builder_message(
175 private_key: &Self::BuilderPrivateKey,
176 data: &[u8],
177 ) -> Result<Self::BuilderSignature, Self::SignError> {
178 BitVectorQc::<BLSOverBN254CurveSignatureScheme>::sign(
179 &(),
180 private_key,
181 data,
182 &mut rand::thread_rng(),
183 )
184 }
185
186 fn validate_builder_signature(&self, signature: &Self::BuilderSignature, data: &[u8]) -> bool {
187 BLSOverBN254CurveSignatureScheme::verify(&(), self, data, signature).is_ok()
188 }
189
190 fn generated_from_seed_indexed(seed: [u8; 32], index: u64) -> (Self, Self::BuilderPrivateKey) {
191 let mut hasher = blake3::Hasher::new();
192 hasher.update(&seed);
193 hasher.update(&index.to_le_bytes());
194 let new_seed = *hasher.finalize().as_bytes();
195 let kp = KeyPair::generate(&mut ChaCha20Rng::from_seed(new_seed));
196 (kp.ver_key(), kp.sign_key_ref().clone())
197 }
198}
199
200pub type SchnorrPubKey = jf_signature::schnorr::VerKey<ark_ed_on_bn254::EdwardsConfig>;
201pub type SchnorrPrivKey = jf_signature::schnorr::SignKey<ark_ed_on_bn254::Fr>;
202pub type SchnorrSignatureScheme =
203 jf_signature::schnorr::SchnorrSignatureScheme<ark_ed_on_bn254::EdwardsConfig>;
204
205impl PrivateSignatureKey for SchnorrPrivKey {
206 fn to_bytes(&self) -> Vec<u8> {
207 self.to_bytes()
208 }
209
210 fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
211 Ok(Self::from_bytes(bytes))
212 }
213
214 fn to_tagged_base64(&self) -> Result<tagged_base64::TaggedBase64, tagged_base64::Tb64Error> {
215 self.to_tagged_base64()
216 }
217}
218
219impl StateSignatureKey for SchnorrPubKey {
220 type StatePrivateKey = SchnorrPrivKey;
221
222 type StateSignature = jf_signature::schnorr::Signature<ark_ed_on_bn254::EdwardsConfig>;
223
224 type SignError = SignatureError;
225
226 fn generated_from_seed_indexed(seed: [u8; 32], index: u64) -> (Self, Self::StatePrivateKey) {
227 let mut hasher = blake3::Hasher::new();
228 hasher.update(&seed);
229 hasher.update(&index.to_le_bytes());
230 let new_seed = *hasher.finalize().as_bytes();
231 let kp = jf_signature::schnorr::KeyPair::generate(&mut ChaCha20Rng::from_seed(new_seed));
232 (kp.ver_key(), kp.sign_key())
233 }
234}
235
236impl LCV1StateSignatureKey for SchnorrPubKey {
237 fn sign_state(
238 sk: &Self::StatePrivateKey,
239 light_client_state: &LightClientState,
240 ) -> Result<Self::StateSignature, Self::SignError> {
241 let state_msg: [_; 3] = light_client_state.into();
242 SchnorrSignatureScheme::sign(&(), sk, state_msg, &mut rand::thread_rng())
243 }
244
245 fn verify_state_sig(
246 &self,
247 signature: &Self::StateSignature,
248 light_client_state: &LightClientState,
249 ) -> bool {
250 let state_msg: [_; 3] = light_client_state.into();
251 SchnorrSignatureScheme::verify(&(), self, state_msg, signature).is_ok()
252 }
253}
254
255impl LCV2StateSignatureKey for SchnorrPubKey {
256 fn sign_state(
257 sk: &Self::StatePrivateKey,
258 light_client_state: &LightClientState,
259 next_stake_table_state: &StakeTableState,
260 ) -> Result<Self::StateSignature, Self::SignError> {
261 let mut msg = Vec::with_capacity(7);
262 let state_msg: [_; 3] = light_client_state.into();
263 msg.extend_from_slice(&state_msg);
264 let adv_st_state_msg: [_; 4] = (*next_stake_table_state).into();
265 msg.extend_from_slice(&adv_st_state_msg);
266 SchnorrSignatureScheme::sign(&(), sk, msg, &mut rand::thread_rng())
267 }
268
269 fn verify_state_sig(
270 &self,
271 signature: &Self::StateSignature,
272 light_client_state: &LightClientState,
273 next_stake_table_state: &StakeTableState,
274 ) -> bool {
275 let mut msg = Vec::with_capacity(7);
276 let state_msg: [_; 3] = light_client_state.into();
277 msg.extend_from_slice(&state_msg);
278 let adv_st_state_msg: [_; 4] = (*next_stake_table_state).into();
279 msg.extend_from_slice(&adv_st_state_msg);
280 SchnorrSignatureScheme::verify(&(), self, msg, signature).is_ok()
281 }
282}
283
284impl LCV3StateSignatureKey for SchnorrPubKey {
285 fn sign_state(
289 private_key: &Self::StatePrivateKey,
290 msg: CircuitField,
291 ) -> Result<Self::StateSignature, Self::SignError> {
292 SchnorrSignatureScheme::sign(&(), private_key, [msg], &mut rand::thread_rng())
293 }
294
295 fn verify_state_sig(&self, signature: &Self::StateSignature, msg: CircuitField) -> bool {
299 SchnorrSignatureScheme::verify(&(), self, [msg], signature).is_ok()
300 }
301}