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