Skip to content

Commit f4986c0

Browse files
authored
Add more tests (#3)
* Add more tests * Add verification tests
1 parent 6b6424b commit f4986c0

File tree

61 files changed

+2721
-114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2721
-114
lines changed

crates/bls_utils/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ pub mod verification;
55
pub use input::{read_bls_shared_data_from_host, read_finalization_data};
66

77
pub use verification::{
8-
verify_generations, verify_initial_commitment, verify_seed_exchange_commitment, ProveResult,
8+
verify_generations, verify_initial_commitment_hash, verify_seed_exchange_commitment, VerificationErrors
99
};

crates/bls_utils/src/verification.rs

Lines changed: 78 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,17 @@ use crate::bls::{
77
bls_id_from_u32, bls_verify, evaluate_polynomial, lagrange_interpolation, PublicKey, SecretKey,
88
};
99

10-
pub enum ProveResult {
11-
Ok,
12-
SlashableError,
13-
UnslashableError,
14-
}
15-
1610
#[derive(Debug)]
1711
pub enum VerificationErrors {
18-
InvalidCommitment(String),
19-
InvalidSharedSecret(String),
20-
InvalidSignature(String),
21-
InvalidVerificationVector(String),
22-
InvalidCommitmentHash(String),
23-
InvalidSignatureHash(String),
12+
SlashableError(String),
13+
UnslashableError(String),
2414
}
2515

2616
impl std::fmt::Display for VerificationErrors {
2717
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2818
match self {
29-
VerificationErrors::InvalidCommitment(msg) => write!(f, "Invalid commitment: {}", msg),
30-
VerificationErrors::InvalidSharedSecret(msg) => {
31-
write!(f, "Invalid shared secret: {}", msg)
32-
}
33-
VerificationErrors::InvalidSignature(msg) => write!(f, "Invalid signature: {}", msg),
34-
VerificationErrors::InvalidVerificationVector(msg) => {
35-
write!(f, "Invalid verification vector: {}", msg)
36-
}
37-
VerificationErrors::InvalidCommitmentHash(msg) => {
38-
write!(f, "Invalid commitment hash: {}", msg)
39-
}
40-
VerificationErrors::InvalidSignatureHash(msg) => {
41-
write!(f, "Invalid signature hash: {}", msg)
42-
}
19+
VerificationErrors::SlashableError(e) => write!(f, "{}", e),
20+
VerificationErrors::UnslashableError(e) => write!(f, "{}", e),
4321
}
4422
}
4523
}
@@ -89,7 +67,7 @@ pub fn verify_seed_exchange_commitment(
8967
verification_hashes: &dvt_abi::AbiVerificationHashes,
9068
seed_exchange: &dvt_abi::AbiSeedExchangeCommitment,
9169
initial_commitment: &dvt_abi::AbiInitialCommitment,
92-
) -> ProveResult {
70+
) -> Result<(), Box<dyn std::error::Error>> {
9371
let commitment = &seed_exchange.commitment;
9472
let shared_secret = &seed_exchange.shared_secret;
9573

@@ -102,26 +80,37 @@ pub fn verify_seed_exchange_commitment(
10280
.unwrap(),
10381
&commitment.hash,
10482
) {
105-
print!("Failed to verify seed exchange commitment\n");
106-
return ProveResult::UnslashableError;
83+
// Return unslashable error
84+
return Err(Box::new(VerificationErrors::UnslashableError(
85+
String::from(format!(
86+
"Invalid field seeds_exchange_commitment.commitment.signature {}\n",
87+
hex::encode(commitment.signature)
88+
)),
89+
)));
10790
}
10891

109-
if SecretKey::from_bytes(&shared_secret.secret).is_err() {
110-
print!("Invalid field seeds_exchange_commitment.shared_secret.secret\n");
111-
return ProveResult::SlashableError;
92+
let sk = SecretKey::from_bytes(&shared_secret.secret);
93+
if sk.is_err() {
94+
return Err(Box::new(VerificationErrors::SlashableError(String::from(
95+
format!(
96+
"Invalid field seeds_exchange_commitment.shared_secret.secret: {} \n",
97+
sk.unwrap_err()
98+
),
99+
))));
112100
}
113101

114-
let sk = SecretKey::from_bytes(&shared_secret.secret).unwrap();
102+
let sk = sk.unwrap();
115103

116104
let computed_commitment_hash = compute_seed_exchange_hash(seed_exchange);
117105

118106
if computed_commitment_hash.to_vec() != seed_exchange.commitment.hash {
119-
print!(
120-
"Invalid field seeds_exchange_commitment.commitment.hash. Expected: {:?}, got hash: {:?}\n",
121-
hex::encode(seed_exchange.commitment.hash),
122-
hex::encode(computed_commitment_hash.to_vec())
123-
);
124-
return ProveResult::SlashableError;
107+
return Err(Box::new(VerificationErrors::SlashableError(
108+
String::from(format!(
109+
"Invalid field seeds_exchange_commitment.commitment.hash. Expected: {:?}, got hash: {:?}\n",
110+
hex::encode(seed_exchange.commitment.hash),
111+
hex::encode(computed_commitment_hash.to_vec())
112+
)),
113+
)));
125114
}
126115

127116
let dest_id = get_index_in_commitments(
@@ -130,8 +119,12 @@ pub fn verify_seed_exchange_commitment(
130119
);
131120

132121
if dest_id.is_err() {
133-
print!("Invalid field seeds_exchange_commitment.shared_secret.dst_id\n");
134-
return ProveResult::SlashableError;
122+
return Err(Box::new(VerificationErrors::SlashableError(String::from(
123+
format!(
124+
"Invalid field seeds_exchange_commitment.shared_secret.dst_id: {} \n",
125+
dest_id.unwrap_err()
126+
),
127+
))));
135128
}
136129

137130
let unwraped = dest_id.unwrap() + 1;
@@ -147,24 +140,26 @@ pub fn verify_seed_exchange_commitment(
147140
let id = Scalar::from_bytes(&le_bytes).unwrap();
148141

149142
if id != test_id {
150-
print!("Invalid field seeds_exchange_commitment.shared_secret.dst_id\n");
151-
return ProveResult::SlashableError;
143+
return Err(Box::new(VerificationErrors::SlashableError(String::from(
144+
"Invalid field seeds_exchange_commitment.shared_secret.dst_id\n",
145+
))));
152146
}
153147
let eval_result = evaluate_polynomial(cfst, id);
154148

155149
if !sk.to_public_key().eq(&eval_result) {
156-
print!(
157-
"Bad secret field : {:?}, got pk: {:?}\n",
158-
PublicKey::from_g1(&eval_result),
159-
sk.to_public_key()
160-
);
161-
return ProveResult::SlashableError;
150+
return Err(Box::new(VerificationErrors::SlashableError(String::from(
151+
format!(
152+
"Bad secret field : Expected secret with public key: {:?}, got public key: {:?}\n",
153+
PublicKey::from_g1(&eval_result),
154+
sk.to_public_key()
155+
),
156+
))));
162157
}
163158

164-
ProveResult::Ok
159+
Ok(())
165160
}
166161

167-
pub fn verify_initial_commitment(commitment: &dvt_abi::AbiInitialCommitment) -> ProveResult {
162+
pub fn verify_initial_commitment_hash(commitment: &dvt_abi::AbiInitialCommitment) -> bool {
168163
let mut hasher = Sha256::new();
169164

170165
hasher.update([commitment.settings.n]);
@@ -173,12 +168,8 @@ pub fn verify_initial_commitment(commitment: &dvt_abi::AbiInitialCommitment) ->
173168
for pubkey in &commitment.verification_vector.pubkeys {
174169
hasher.update(&pubkey);
175170
}
176-
177-
if hasher.finalize().to_vec() != commitment.hash {
178-
return ProveResult::UnslashableError;
179-
}
180-
181-
ProveResult::Ok
171+
let computed_hash = hasher.finalize().to_vec();
172+
computed_hash == commitment.hash
182173
}
183174

184175
fn verify_generation_sig(
@@ -224,7 +215,6 @@ fn print_vec_g1_as_hex(v: &Vec<G1Affine>) {
224215

225216
fn compute_agg_key_from_dvt(
226217
verification_vectors: Vec<dvt_abi::AbiVerificationVector>,
227-
settings: &dvt_abi::AbiGenerateSettings,
228218
ids: &Vec<Scalar>,
229219
) -> Result<G1Affine, Box<dyn std::error::Error>> {
230220
let verification_vectors: Vec<Vec<G1Affine>> = verification_vectors
@@ -240,12 +230,6 @@ fn compute_agg_key_from_dvt(
240230

241231
let mut all_pts = Vec::new();
242232

243-
print!("n = {}, k = {}\n", settings.n, settings.k);
244-
print!(
245-
"shares = {}, vectors = {}\n",
246-
verification_vectors.len(),
247-
verification_vectors.len()
248-
);
249233
for i in 0..verification_vectors.len() {
250234
let mut pts = Vec::new();
251235
let share_id = ids[i];
@@ -265,9 +249,6 @@ fn compute_agg_key_from_dvt(
265249
final_keys.push(key);
266250
}
267251

268-
print!("Final keys: \n");
269-
print_vec_g1_as_hex(&final_keys);
270-
271252
let agg_key = lagrange_interpolation(&final_keys, &ids)?;
272253
return Ok(agg_key);
273254
}
@@ -277,6 +258,14 @@ pub fn verify_generations(
277258
settings: &dvt_abi::AbiGenerateSettings,
278259
agg_key: &dvt_abi::BLSPubkey,
279260
) -> Result<(), Box<dyn std::error::Error>> {
261+
262+
if generations.len() != settings.n as usize {
263+
return Err(Box::new(std::io::Error::new(
264+
std::io::ErrorKind::InvalidData,
265+
"Invalid number of generations",
266+
)));
267+
}
268+
280269
let mut sorted = generations.to_vec();
281270
sorted.sort_by(|a, b| a.base_hash.cmp(&b.base_hash));
282271

@@ -295,15 +284,25 @@ pub fn verify_generations(
295284
.map(|(i, _)| -> Scalar { bls_id_from_u32((i + 1) as u32) })
296285
.collect();
297286

298-
let computed_key = compute_agg_key_from_dvt(verification_vectors, settings, &ids)?;
287+
let computed_key = compute_agg_key_from_dvt(verification_vectors, &ids)?;
299288

300-
if computed_key != G1Affine::from_compressed(agg_key).into_option().unwrap() {
289+
let agg_key = G1Affine::from_compressed(agg_key).into_option();
290+
291+
if agg_key.is_none() {
301292
return Err(Box::new(std::io::Error::new(
302293
std::io::ErrorKind::InvalidData,
303294
"Invalid aggregate public key",
304295
)));
305296
}
306297

298+
let agg_key = agg_key.unwrap();
299+
if computed_key != agg_key {
300+
return Err(Box::new(std::io::Error::new(
301+
std::io::ErrorKind::InvalidData,
302+
format!("Computed key {} does not match aggregate public key {}", hex::encode(computed_key.to_compressed()), hex::encode(agg_key.to_compressed())),
303+
)));
304+
}
305+
307306
let partial_keys = sorted
308307
.iter()
309308
.map(|generation| -> G1Affine {
@@ -315,31 +314,24 @@ pub fn verify_generations(
315314

316315
let computed_key = lagrange_interpolation(&partial_keys, &ids)?;
317316

318-
if computed_key != G1Affine::from_compressed(agg_key).into_option().unwrap() {
317+
if computed_key != agg_key {
319318
return Err(Box::new(std::io::Error::new(
320319
std::io::ErrorKind::InvalidData,
321-
"Invalid aggregate public key",
320+
format!("Computed key {} does not match aggregate public key {}", hex::encode(computed_key.to_compressed()), hex::encode(agg_key.to_compressed())),
322321
)));
323322
}
324323

325324
for (_, generation) in generations.iter().enumerate() {
326325
verify_generation_sig(generation)?;
327326
let initial_commitment = generate_initial_commitment(generation, &settings);
328-
let ok = verify_initial_commitment(&initial_commitment);
329-
match ok {
330-
ProveResult::SlashableError => {
331-
return Err(Box::new(std::io::Error::new(
332-
std::io::ErrorKind::InvalidData,
333-
"Slashable error while verifying initial commitment",
334-
)));
335-
}
336-
ProveResult::UnslashableError => {
337-
return Err(Box::new(std::io::Error::new(
338-
std::io::ErrorKind::InvalidData,
339-
"Unslashable error while verifying initial commitment",
340-
)));
341-
}
342-
ProveResult::Ok => (),
327+
let ok = verify_initial_commitment_hash(&initial_commitment);
328+
if !ok {
329+
return Err(Box::new(VerificationErrors::UnslashableError(
330+
String::from(format!(
331+
"Invalid initial commitment hash {}\n",
332+
hex::encode(initial_commitment.hash)
333+
)),
334+
)));
343335
}
344336
}
345337
Ok(())

crates/share_exchange_prove/src/main.rs

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,54 @@ sp1_zkvm::entrypoint!(main);
44

55
use core::panic;
66

7-
use bls_utils;
7+
use bls_utils::{self, VerificationErrors};
88

99
pub fn main() {
1010
let data = bls_utils::read_bls_shared_data_from_host();
1111

12-
match bls_utils::verify_initial_commitment(&data.initial_commitment) {
13-
bls_utils::ProveResult::SlashableError => {
14-
print!("Slashable error while verifying initial commitment\n");
15-
return;
16-
}
17-
bls_utils::ProveResult::UnslashableError => {
18-
print!("Unslashable error while verifying initial commitment\n");
19-
panic!();
20-
}
21-
bls_utils::ProveResult::Ok => {
22-
print!("OK while verifying initial commitment\n");
23-
}
12+
if data.verification_hashes.len() == data.initial_commitment.settings.n as usize {
13+
panic!("The number of verification hashes does not match the number of keys\n");
14+
}
15+
16+
if data.initial_commitment.settings.n < data.initial_commitment.settings.k {
17+
panic!("N should be greater than or equal to k\n");
18+
}
19+
20+
let found = data.verification_hashes.iter().find(|h| {
21+
h == &&data.initial_commitment.hash
22+
});
23+
24+
if found.is_none() {
25+
panic!("The seed exchange commitment is not part of the verification hashes\n");
26+
}
27+
28+
if !bls_utils::verify_initial_commitment_hash(&data.initial_commitment) {
29+
panic!("Unsalshable error while verifying commitment hash\n");
2430
}
2531

2632
match bls_utils::verify_seed_exchange_commitment(
2733
&data.verification_hashes,
2834
&data.seeds_exchange_commitment,
2935
&data.initial_commitment,
3036
) {
31-
bls_utils::ProveResult::SlashableError => {
32-
print!("Slashable error while verifying seed exchange commitment\n");
33-
return;
34-
}
35-
bls_utils::ProveResult::UnslashableError => {
36-
print!("Unslashable error while verifying seed exchange commitment\n");
37-
panic!();
37+
Ok(()) => {
38+
println!("OK while verifying initial commitment");
3839
}
39-
bls_utils::ProveResult::Ok => {
40-
print!("OK while verifying seed exchange commitment\n");
40+
Err(e) => {
41+
if let Some(verification_error) = e.downcast_ref::<VerificationErrors>() {
42+
match verification_error {
43+
VerificationErrors::SlashableError(err) => {
44+
println!("Slashable error while verifying initial: {}", err);
45+
return;
46+
}
47+
VerificationErrors::UnslashableError(err) => {
48+
println!("Unslashable error while verifying: {}", err);
49+
panic!();
50+
}
51+
}
52+
} else {
53+
panic!("Unknown error while verifying initial: {}", e);
54+
}
4155
}
4256
}
4357

0 commit comments

Comments
 (0)