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