Skip to content

Commit 0f0c02a

Browse files
using sp1 proofs
1 parent 91a5e68 commit 0f0c02a

File tree

10 files changed

+3564
-385
lines changed

10 files changed

+3564
-385
lines changed

Cargo.lock

Lines changed: 3487 additions & 315 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,29 +65,26 @@ keystore-rs = "0.1.0"
6565
toml = "0.8.14"
6666
dirs = "5.0.1"
6767
anyhow = "1.0.44"
68-
jmt = { version = "0.10.0", features = ["mocks"] }
68+
jmt = { git = "https://github.com/deltadevsde/jmt", branch = "rehashing-circuit", features = [
69+
"mocks",
70+
] }
6971
bellpepper-core = { version = "0.4.0", default-features = false }
7072
bellpepper = "0.4.1"
71-
itertools = "0.13.0" # zip_eq
72-
arecibo = "0.2.0"
73+
itertools = "0.13.0" # zip_eq
74+
arecibo = { git = "https://github.com/deltadevsde/arecibo" }
7375
sha2 = "0.10.8"
7476
auto_impl = "1.2.0"
7577
bincode = "1.3.3"
76-
blake2 = "0.10.6"
7778
sp1-zkvm = { version = "1.2.0" }
79+
sp1-sdk = { version = "1.2.0" }
7880
prism-common = { path = "crates/common" }
7981
prism-nova = { path = "crates/nova" }
8082
prism-errors = { path = "crates/errors" }
8183
prism-main = { path = "crates/prism" }
8284
prism-groth16 = { path = "crates/groth16" }
83-
sp1-helper = "1.2.0"
8485

8586
[patch.crates-io]
8687
sha2-v0-10-8 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha2", branch = "patch-sha2-v0.10.8" }
87-
arecibo = { git = "https://github.com/deltadevsde/arecibo" }
88-
jmt = { git = "https://github.com/deltadevsde/jmt", branch = "rehashing-circuit", features = [
89-
"mocks",
90-
] }
9188

9289
# [workspace.dev-dependencies]
9390
# serial_test = "3.1.1"

crates/common/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@ jmt.workspace = true
1414
serde.workspace = true
1515
hex.workspace = true
1616
sha2.workspace = true
17-
blake2.workspace = true
1817
celestia-types.workspace = true

crates/common/src/tree.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ use crate::hashchain::Hashchain;
1414
pub const SPARSE_MERKLE_PLACEHOLDER_HASH: Digest =
1515
Digest::new(*b"SPARSE_MERKLE_PLACEHOLDER_HASH__");
1616

17-
pub type Hasher = blake2::Blake2s256;
17+
pub type Hasher = sha2::Sha256;
18+
19+
pub fn hash(data: &[u8]) -> Digest {
20+
let mut hasher = Hasher::new();
21+
hasher.update(data);
22+
Digest(hasher.finalize())
23+
}
1824

1925
#[derive(
2026
Debug, Clone, BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Copy,
@@ -97,12 +103,6 @@ impl Digest {
97103
}
98104
}
99105

100-
pub fn hash(data: &[u8]) -> Digest {
101-
let mut hasher = blake2::Blake2s256::new();
102-
hasher.update(data);
103-
Digest(hasher.finalize())
104-
}
105-
106106
#[derive(Serialize, Deserialize)]
107107
pub struct Batch {
108108
pub prev_root: Digest,
@@ -294,7 +294,6 @@ where
294294
let serialized_value = Self::serialize_value(&value)?;
295295

296296
let old_root = self.get_current_root()?;
297-
println!("key: {:?}", key);
298297
let (old_value, non_membership_merkle_proof) = self.jmt.get_with_proof(key, self.epoch)?;
299298

300299
let non_membership_proof = NonMembershipProof {

crates/prism/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ auto_impl = { workspace = true }
4545
prism-common = { workspace = true }
4646
prism-errors = { workspace = true }
4747
prism-groth16 = { workspace = true }
48+
sp1-sdk = { workspace = true }
4849

4950
[dev-dependencies]
5051
serial_test = "3.1.1"

crates/prism/src/da/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use borsh::{BorshDeserialize, BorshSerialize};
55
use ed25519::Signature;
66
use prism_common::{operation::Operation, tree::Digest};
77
use prism_errors::GeneralError;
8+
use serde::{Deserialize, Serialize};
9+
use sp1_sdk::SP1ProofWithPublicValues;
810
use std::{self, str::FromStr};
911

1012
pub mod celestia;
@@ -16,8 +18,7 @@ pub struct FinalizedEpoch {
1618
pub height: u64,
1719
pub prev_commitment: Digest,
1820
pub current_commitment: Digest,
19-
// pub proof: Bls12Proof,
20-
// pub verifying_key: VerifyingKey,
21+
pub proof: SP1ProofWithPublicValues,
2122
pub signature: Option<String>,
2223
}
2324

crates/prism/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use storage::RedisConnection;
1818
#[macro_use]
1919
extern crate log;
2020

21+
pub const PRISM_ELF: &[u8] = include_bytes!("../../../elf/riscv32im-succinct-zkvm-elf");
22+
2123
/// The main function that initializes and runs a prism client.
2224
#[tokio::main()]
2325
async fn main() -> std::io::Result<()> {

crates/prism/src/node_types/lightclient.rs

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ use crate::cfg::CelestiaConfig;
22
use anyhow::{Context, Result};
33
use async_trait::async_trait;
44
use prism_errors::{DataAvailabilityError, GeneralError};
5+
use sp1_sdk::{ProverClient, SP1VerifyingKey};
56
use std::{self, sync::Arc, time::Duration};
67
use tokio::{task::spawn, time::interval};
78

89
use crate::{da::DataAvailabilityLayer, node_types::NodeType, utils::verify_signature};
910

11+
pub const PRISM_ELF: &[u8] = include_bytes!("../../../../elf/riscv32im-succinct-zkvm-elf");
12+
1013
pub struct LightClient {
1114
pub da: Arc<dyn DataAvailabilityLayer>,
12-
// verifying_key is the [`VerifyingKey`] used to verify epochs from the prover/sequencer
13-
pub verifying_key: Option<String>,
14-
start_height: u64,
15+
pub sequencer_pubkey: Option<String>,
16+
pub client: ProverClient,
17+
pub verifying_key: SP1VerifyingKey,
18+
pub start_height: u64,
1519
}
1620

1721
#[async_trait]
@@ -35,11 +39,15 @@ impl LightClient {
3539
pub fn new(
3640
da: Arc<dyn DataAvailabilityLayer>,
3741
cfg: CelestiaConfig,
38-
sequencer_pub_key: Option<String>,
42+
sequencer_pubkey: Option<String>,
3943
) -> LightClient {
44+
let client = ProverClient::new();
45+
let (_, verifying_key) = client.setup(PRISM_ELF);
4046
LightClient {
4147
da,
42-
verifying_key: sequencer_pub_key,
48+
verifying_key,
49+
client,
50+
sequencer_pubkey,
4351
start_height: cfg.start_height,
4452
}
4553
}
@@ -71,33 +79,15 @@ impl LightClient {
7179

7280
// todo: verify adjacency to last heights, <- for this we need some sort of storage of epochs
7381
for epoch_json in epoch_json_vec {
74-
// let prev_commitment = &epoch_json.prev_commitment;
75-
// let current_commitment = &epoch_json.current_commitment;
76-
77-
// let proof = match epoch_json.proof.clone().try_into() {
78-
// Ok(proof) => proof,
79-
// Err(e) => {
80-
// error!("failed to deserialize proof, skipping a blob at height {}: {:?}", i, e);
81-
// continue;
82-
// }
83-
// };
84-
85-
// TODO(@distractedm1nd): i don't know rust yet but this seems like non-idiomatic rust -
86-
// is there not a Trait that can satisfy these properties for us?
87-
// let verifying_key = match epoch_json.verifying_key.clone().try_into() {
88-
// Ok(vk) => vk,
89-
// Err(e) => {
90-
// error!("failed to deserialize verifying key, skipping a blob at height {}: {:?}", i, e);
91-
// continue;
92-
// }
93-
// };
82+
let prev_commitment = &epoch_json.prev_commitment;
83+
let current_commitment = &epoch_json.current_commitment;
9484

9585
// if the user does not add a verifying key, we will not verify the signature,
9686
// but only log a warning on startup
97-
if self.verifying_key.is_some() {
87+
if self.sequencer_pubkey.is_some() {
9888
match verify_signature(
9989
&epoch_json.clone(),
100-
self.verifying_key.clone(),
90+
self.sequencer_pubkey.clone(),
10191
) {
10292
Ok(_) => trace!(
10393
"valid signature for epoch {}",
@@ -109,20 +99,20 @@ impl LightClient {
10999
}
110100
}
111101

112-
// match validate_epoch(
113-
// prev_commitment,
114-
// current_commitment,
115-
// proof,
116-
// verifying_key,
117-
// ) {
118-
// Ok(_) => {
119-
// info!(
120-
// "zkSNARK for epoch {} was validated successfully",
121-
// epoch_json.height
122-
// )
123-
// }
124-
// Err(err) => panic!("failed to validate epoch: {:?}", err),
125-
// }
102+
// TODO: compare commitment to epoch_json.proof.public_values
103+
104+
match self.client.verify(&epoch_json.proof, &self.verifying_key) {
105+
Ok(_) => {
106+
info!(
107+
"zkSNARK for epoch {} was validated successfully",
108+
epoch_json.height
109+
)
110+
}
111+
Err(err) => panic!(
112+
"failed to validate epoch at height {}: {:?}",
113+
epoch_json.height, err
114+
),
115+
}
126116
}
127117
}
128118
Err(e) => {

crates/prism/src/node_types/sequencer.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use async_trait::async_trait;
33
use ed25519::Signature;
44
use ed25519_dalek::{Signer, SigningKey};
55
use jmt::KeyHash;
6-
use prism_common::tree::{hash, Digest, Hasher, KeyDirectoryTree, Proof, SnarkableTree};
6+
use prism_common::tree::{hash, Batch, Digest, Hasher, KeyDirectoryTree, Proof, SnarkableTree};
77
use std::{self, str::FromStr, sync::Arc};
88
use tokio::{
99
sync::{
@@ -14,6 +14,8 @@ use tokio::{
1414
time::interval,
1515
};
1616

17+
use sp1_sdk::{ProverClient, SP1ProvingKey, SP1Stdin, SP1VerifyingKey};
18+
1719
#[cfg(test)]
1820
use prism_errors::DataAvailabilityError;
1921

@@ -31,6 +33,8 @@ use prism_common::{
3133
};
3234
use prism_errors::{DatabaseError, GeneralError};
3335

36+
pub const PRISM_ELF: &[u8] = include_bytes!("../../../../elf/riscv32im-succinct-zkvm-elf");
37+
3438
pub struct Sequencer {
3539
pub db: Arc<dyn Database>,
3640
pub da: Arc<dyn DataAvailabilityLayer>,
@@ -47,6 +51,10 @@ pub struct Sequencer {
4751
// posted to the DA layer.
4852
pending_operations: Arc<Mutex<Vec<Operation>>>,
4953
tree: Arc<Mutex<KeyDirectoryTree<Box<dyn Database>>>>,
54+
prover_client: Arc<Mutex<ProverClient>>,
55+
56+
proving_key: SP1ProvingKey,
57+
verifying_key: SP1VerifyingKey,
5058

5159
epoch_buffer_tx: Arc<Sender<FinalizedEpoch>>,
5260
epoch_buffer_rx: Arc<Mutex<Receiver<FinalizedEpoch>>>,
@@ -86,13 +94,19 @@ impl Sequencer {
8694

8795
// Create the KeyDirectory
8896
let tree = Arc::new(Mutex::new(KeyDirectoryTree::new(db.clone())));
97+
let prover_client = ProverClient::new();
98+
99+
let (pk, vk) = prover_client.setup(PRISM_ELF);
89100

90101
Ok(Sequencer {
91102
db: db.clone(),
92103
da,
93104
ws: WebServer::new(ws),
105+
proving_key: pk,
106+
verifying_key: vk,
94107
key,
95108
start_height,
109+
prover_client: Arc::new(Mutex::new(prover_client)),
96110
tree,
97111
pending_operations: Arc::new(Mutex::new(Vec::new())),
98112
epoch_buffer_tx: Arc::new(tx),
@@ -305,19 +319,23 @@ impl Sequencer {
305319
.set_commitment(&epoch, &current_commitment)
306320
.context("Failed to add commitment for new epoch")?;
307321

308-
// let batch_circuit =
309-
// BatchMerkleProofCircuit::new(&prev_commitment, &current_commitment, proofs)
310-
// .context("Failed to create BatchMerkleProofCircuit")?;
311-
// let (proof, verifying_key) = batch_circuit
312-
// .create_and_verify_snark()
313-
// .context("Failed to create and verify snark")?;
322+
let batch = Batch {
323+
prev_root: prev_commitment,
324+
new_root: current_commitment,
325+
proofs,
326+
};
327+
328+
let mut stdin = SP1Stdin::new();
329+
stdin.write(&batch);
330+
331+
let client = self.prover_client.lock().await;
332+
let proof = client.prove(&self.proving_key, stdin).plonk().run()?;
314333

315334
let epoch_json = FinalizedEpoch {
316335
height: epoch,
317336
prev_commitment,
318337
current_commitment,
319-
// proof: proof.into(),
320-
// verifying_key: verifying_key.into(),
338+
proof,
321339
signature: None,
322340
};
323341

elf/riscv32im-succinct-zkvm-elf

373 KB
Binary file not shown.

0 commit comments

Comments
 (0)