Skip to content

Commit a038fc1

Browse files
committed
Add project for encrypted shares
1 parent d6298d1 commit a038fc1

File tree

12 files changed

+199
-69
lines changed

12 files changed

+199
-69
lines changed

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ fn main() {
22
sp1_build::build_program("crates/share_exchange_prove");
33
sp1_build::build_program("crates/finalization_prove");
44
sp1_build::build_program("crates/wrong_final_key_generation_prove");
5+
sp1_build::build_program("crates/bad_encrypted_share_prove");
56
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "bad_encrypted_share_prove"
3+
version = "1.1.0"
4+
edition = "2021"
5+
publish = false
6+
7+
[dependencies]
8+
sp1-zkvm = "3.4.0"
9+
ff = "0.13.0"
10+
rand = "0.8.5"
11+
group = "0.13.0"
12+
serde = "1.0.216"
13+
dvt_abi = { path = "../dvt_abi" }
14+
bls_utils = { path = "../bls_utils" }
15+
hex = "0.4"
16+
chacha20 = "0.9.1"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#![no_main]
2+
3+
sp1_zkvm::entrypoint!(main);
4+
5+
use core::panic;
6+
7+
use bls_utils::{self};
8+
9+
use chacha20::cipher::{KeyIvInit, StreamCipher, StreamCipherSeek};
10+
use chacha20::ChaCha20;
11+
12+
pub fn main() {
13+
let data = bls_utils::read_wrong_final_key_generation_data();
14+
print!("{:?}", data);
15+
16+
let ok = bls_utils::prove_wrong_final_key_generation(&data);
17+
if ok.is_err() {
18+
panic!("{:?}", ok.unwrap_err().to_string());
19+
}
20+
21+
let key = [0x42; 32];
22+
let nonce = [0x24; 12];
23+
let plaintext = hex::decode("000102030405060708090A0B0C0D0E0F").unwrap();
24+
let ciphertext = hex::decode("e405626e4f1236b3670ee428332ea20e").unwrap();
25+
26+
// Key and IV must be references to the `GenericArray` type.
27+
// Here we use the `Into` trait to convert arrays into it.
28+
let mut cipher = ChaCha20::new(&key.into(), &nonce.into());
29+
30+
let mut buffer = plaintext.clone();
31+
32+
// apply keystream (encrypt)
33+
cipher.apply_keystream(&mut buffer);
34+
assert_eq!(buffer, ciphertext);
35+
36+
let ciphertext = buffer.clone();
37+
38+
// ChaCha ciphers support seeking
39+
cipher.seek(0u32);
40+
41+
// decrypt ciphertext by applying keystream again
42+
cipher.apply_keystream(&mut buffer);
43+
assert_eq!(buffer, plaintext);
44+
45+
// stream ciphers can be used with streaming messages
46+
cipher.seek(0u32);
47+
for chunk in buffer.chunks_mut(3) {
48+
cipher.apply_keystream(chunk);
49+
}
50+
assert_eq!(buffer, ciphertext);
51+
print!("{:?}", ciphertext);
52+
}

crates/bls_utils/src/bls.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn evaluate_polynomial(cfs: Vec<G1Affine>, x: Scalar) -> G1Affine {
3939
}
4040
}
4141

42-
pub fn evaluate_polynomial_g1_projection(cfs: &Vec<G1Projective>, x: Scalar) -> G1Projective {
42+
pub fn evaluate_polynomial_g1_projection(cfs: &Vec<G1Projective>, x: Scalar) -> G1Projective {
4343
let count = cfs.len();
4444
if count == 0 {
4545
return G1Projective::identity();
@@ -109,10 +109,14 @@ pub fn hash_message_to_g2(msg: &[u8]) -> G2Projective {
109109
<G2Projective as HashToCurve<ExpandMsgXmd<Sha256>>>::hash_to_curve(msg, domain)
110110
}
111111

112-
pub fn bls_verify_precomputed_hash(pubkey: &G1Affine, signature: &G2Affine, hashed_msg: &G2Affine) -> bool {
112+
pub fn bls_verify_precomputed_hash(
113+
pubkey: &G1Affine,
114+
signature: &G2Affine,
115+
hashed_msg: &G2Affine,
116+
) -> bool {
113117
let left = pairing(&pubkey, &hashed_msg);
114118
let right = pairing(&G1Affine::generator(), &signature);
115-
119+
116120
left == right
117121
}
118122
pub fn bls_verify(pubkey: &G1Affine, signature: &G2Affine, message: &[u8]) -> bool {

crates/bls_utils/src/input.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,7 @@ pub fn read_wrong_final_key_generation_data() -> dvt_abi::AbiWrongFinalKeyGenera
171171
perpatrator_hash: perpatrator_hash,
172172
}
173173
}
174+
175+
pub fn read_bad_encrypted_share() -> dvt_abi::AbiBadEncryptedShare {
176+
dvt_abi::AbiBadEncryptedShare {}
177+
}

crates/bls_utils/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ pub mod bls;
22
pub mod input;
33
pub mod verification;
44

5-
pub use input::{read_bls_shared_data_from_host, read_finalization_data, read_wrong_final_key_generation_data};
5+
pub use input::{
6+
read_bls_shared_data_from_host, read_finalization_data, read_wrong_final_key_generation_data,
7+
};
68

79
pub use verification::{
8-
verify_generations, verify_initial_commitment_hash, verify_seed_exchange_commitment, prove_wrong_final_key_generation, VerificationErrors
10+
prove_wrong_final_key_generation, verify_generations, verify_initial_commitment_hash,
11+
verify_seed_exchange_commitment, VerificationErrors,
912
};

crates/bls_utils/src/verification.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use bls12_381::{G1Affine, G1Projective, G2Affine, Scalar};
22

33
use dvt_abi::{self};
4-
use group::GroupEncoding;
54
use sha2::{Digest, Sha256};
6-
use sp1_zkvm;
75

86
use crate::bls::{
9-
bls_id_from_u32, bls_verify, bls_verify_precomputed_hash, evaluate_polynomial, evaluate_polynomial_g1_projection, hash_message_to_g2, lagrange_interpolation, PublicKey, SecretKey
7+
bls_id_from_u32, bls_verify_precomputed_hash, evaluate_polynomial,
8+
evaluate_polynomial_g1_projection, hash_message_to_g2, lagrange_interpolation, PublicKey,
9+
SecretKey,
1010
};
1111

1212
#[derive(Debug)]
@@ -73,7 +73,6 @@ pub fn to_g1_projection(pubkey: &dvt_abi::BLSPubkey) -> G1Projective {
7373
G1Projective::from(to_g1_affine(pubkey))
7474
}
7575

76-
7776
pub fn verify_seed_exchange_commitment(
7877
verification_hashes: &dvt_abi::AbiVerificationHashes,
7978
seed_exchange: &dvt_abi::AbiSeedExchangeCommitment,
@@ -84,16 +83,14 @@ pub fn verify_seed_exchange_commitment(
8483

8584
let g1_pubkey = to_g1_affine(&commitment.pubkey);
8685

87-
88-
let g2_sig = &G2Affine::from_compressed(&commitment.signature)
89-
.into_option();
86+
let g2_sig = &G2Affine::from_compressed(&commitment.signature).into_option();
9087
if g2_sig.is_none() {
9188
return Err(Box::new(VerificationErrors::UnslashableError(
9289
String::from(format!(
93-
"Invalid field seeds_exchange_commitment.commitment.signature {}\n",
90+
"Invalid field seeds_exchange_commitment.commitment.signature {}\n",
9491
hex::encode(commitment.signature)
95-
))
96-
)))
92+
)),
93+
)));
9794
}
9895
if !bls_verify_precomputed_hash(
9996
&g1_pubkey,
@@ -112,7 +109,6 @@ pub fn verify_seed_exchange_commitment(
112109
let sk = SecretKey::from_bytes(&shared_secret.secret);
113110
if sk.is_err() {
114111
return Err(Box::new(VerificationErrors::SlashableError(String::from(
115-
116112
format!(
117113
"Invalid field seeds_exchange_commitment.shared_secret.secret: {} \n",
118114
sk.unwrap_err()
@@ -226,7 +222,7 @@ fn agg_final_keys(
226222
.collect();
227223

228224
let mut final_cfs = Vec::new();
229-
for i in 0..verification_vectors[0].len() {
225+
for i in 0..verification_vectors[0].len() {
230226
let mut sum = G1Projective::identity();
231227
for j in 0..verification_vectors.len() {
232228
sum = sum + verification_vectors[j][i];
@@ -237,7 +233,7 @@ fn agg_final_keys(
237233
for i in 0..ids.len() {
238234
let tmp = evaluate_polynomial_g1_projection(&final_cfs, ids[i]);
239235
final_keys.push(tmp);
240-
}
236+
}
241237
final_keys.iter().map(|x| G1Affine::from(x)).collect()
242238
}
243239

@@ -275,7 +271,9 @@ pub fn verify_generation_hashes(
275271
// opcode count for n=5 924_860_863
276272
let ok = bls_verify_precomputed_hash(
277273
&to_g1_affine(&generation.partial_pubkey),
278-
&G2Affine::from_compressed(&generation.message_signature).into_option().unwrap(),
274+
&G2Affine::from_compressed(&generation.message_signature)
275+
.into_option()
276+
.unwrap(),
279277
&hashed_msg,
280278
);
281279

@@ -366,7 +364,7 @@ pub fn verify_generations(
366364
})
367365
.collect();
368366

369-
let computed_key = lagrange_interpolation(&partial_keys, &ids)?;
367+
let computed_key = lagrange_interpolation(&partial_keys, &ids)?;
370368

371369
if computed_key != agg_key {
372370
return Err(Box::new(std::io::Error::new(

crates/dvt_abi/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ pub struct DvtWrongFinalKeyGeneration {
110110
perpatrator_hash: String,
111111
}
112112

113+
#[derive(Debug, Deserialize)]
114+
pub struct DvtBadEncryptedShare {
115+
// TODO: implement
116+
}
117+
113118
#[derive(Debug)]
114119
pub struct AbiVerificationVector {
115120
pub pubkeys: Vec<BLSPubkey>,
@@ -183,6 +188,11 @@ pub struct AbiWrongFinalKeyGeneration {
183188
pub perpatrator_hash: SHA256,
184189
}
185190

191+
#[derive(Debug)]
192+
pub struct AbiBadEncryptedShare {
193+
// TODO: implement
194+
}
195+
186196
fn decode_hex<const N: usize>(input: &str) -> Result<[u8; N], Box<dyn Error>> {
187197
let bytes = decode(input).map_err(|e| format!("Failed to decode input: {}", e))?;
188198

@@ -358,7 +368,14 @@ impl DvtWrongFinalKeyGeneration {
358368
.collect::<Result<Vec<AbiGeneration>, _>>()?,
359369
perpatrator_hash: decode_hex::<SHA256_SIZE>(&self.perpatrator_hash)
360370
.map_err(|e| format!("Invalid perpatrator_hash: {}", e))?,
361-
371+
})
372+
}
373+
}
374+
375+
impl DvtBadEncryptedShare {
376+
pub fn to_abi(&self) -> Result<AbiBadEncryptedShare, Box<dyn std::error::Error>> {
377+
Ok(AbiBadEncryptedShare {
378+
// TODO: implement
362379
})
363380
}
364381
}

crates/dvt_abi_host/src/lib.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
use dvt_abi;
21
use sp1_sdk::SP1Stdin;
32
fn write_array_to_prover<const N: usize>(stdin: &mut SP1Stdin, data: &[u8; N]) {
4-
for i in 0..N {
5-
stdin.write(&[data[i]]);
3+
for x in data.iter().take(N) {
4+
stdin.write(x);
65
}
76
}
87
pub trait ProverSerialize {
@@ -63,16 +62,19 @@ impl ProverSerialize for dvt_abi::AbiBlsSharedData {
6362
self.initial_commitment.write(stdin);
6463
self.seeds_exchange_commitment.write(stdin);
6564
if (self.initial_commitment.settings.n as usize) != self.verification_hashes.len() {
66-
panic!("k != verification_hashes.len() {}", self.verification_hashes.len());
65+
panic!(
66+
"k != verification_hashes.len() {}",
67+
self.verification_hashes.len()
68+
);
6769
}
6870
self.verification_hashes.write(stdin);
6971
}
7072
}
7173

7274
impl ProverSerialize for dvt_abi::AbiVerificationHashes {
7375
fn write(&self, stdin: &mut SP1Stdin) {
74-
for i in 0..self.len() {
75-
write_array_to_prover(stdin, &self[i]);
76+
for x in self {
77+
write_array_to_prover(stdin, x);
7678
}
7779
}
7880
}
@@ -100,7 +102,7 @@ impl ProverSerialize for dvt_abi::AbiFinalizationData {
100102
if self.settings.n as usize != self.generations.len() {
101103
panic!("k != generations.len() {}", self.generations.len());
102104
}
103-
105+
104106
for i in 0..self.generations.len() {
105107
self.generations[i].write(stdin);
106108
}
@@ -116,4 +118,10 @@ impl ProverSerialize for dvt_abi::AbiWrongFinalKeyGeneration {
116118
}
117119
write_array_to_prover(stdin, &self.perpatrator_hash);
118120
}
119-
}
121+
}
122+
123+
impl ProverSerialize for dvt_abi::AbiBadEncryptedShare {
124+
fn write(&self, _stdin: &mut SP1Stdin) {
125+
// TODO: implement
126+
}
127+
}

crates/share_exchange_prove/src/main.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ use bls_utils::{self, VerificationErrors};
99
pub fn main() {
1010
let data = bls_utils::read_bls_shared_data_from_host();
1111

12-
if data.verification_hashes.len() != data.initial_commitment.settings.n as usize {
12+
if data.verification_hashes.len() != data.initial_commitment.settings.n as usize {
1313
panic!("The number of verification hashes does not match the number of keys\n");
1414
}
1515

1616
if data.initial_commitment.settings.n < data.initial_commitment.settings.k {
1717
panic!("N should be greater than or equal to k\n");
1818
}
1919

20-
let found = data.verification_hashes.iter().find(|h| {
21-
h == &&data.initial_commitment.hash
22-
});
20+
let found = data
21+
.verification_hashes
22+
.iter()
23+
.find(|h| h == &&data.initial_commitment.hash);
2324

2425
if found.is_none() {
2526
panic!("The seed exchange commitment is not part of the verification hashes\n");
@@ -37,18 +38,18 @@ pub fn main() {
3738
Ok(()) => {
3839
println!("The share is valid. We can't prove participant share is corrupted.");
3940
}
40-
41+
4142
Err(e) => {
4243
if let Some(verification_error) = e.downcast_ref::<VerificationErrors>() {
4344
match verification_error {
4445
VerificationErrors::SlashableError(err) => {
4546
println!("Slashable error seed exchange commitment: {}", err);
46-
47+
4748
for h in data.verification_hashes.iter() {
4849
println!("Verification hash: {}", hex::encode(h));
4950
sp1_zkvm::io::commit(h);
5051
}
51-
52+
5253
return;
5354
}
5455
VerificationErrors::UnslashableError(err) => {

0 commit comments

Comments
 (0)