Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5d725cc
feat(WIP): nova
distractedm1nd Aug 3, 2024
2bc7a86
fix: not using struct variants in step enum
distractedm1nd Aug 4, 2024
43f23de
removing dead code
distractedm1nd Aug 4, 2024
40a0cb6
fuck this man what am i even doing
distractedm1nd Aug 4, 2024
7dc7200
feat: beginning of migration to jmt
distractedm1nd Aug 8, 2024
fbb8aa9
refactor: redis as JMT backend (temporarily)
distractedm1nd Aug 8, 2024
8ee6bd4
progress on JMT migration: removing lifetime annotations to own TreeR…
distractedm1nd Aug 11, 2024
7f9b30c
build errors
distractedm1nd Aug 11, 2024
519638e
supernova
distractedm1nd Aug 17, 2024
26fcf3f
fix some things
sebasti810 Aug 20, 2024
a3367da
write_batch
distractedm1nd Aug 20, 2024
a9195b1
failing test
distractedm1nd Aug 20, 2024
dbff1d4
nova batch updates
distractedm1nd Aug 22, 2024
4b1e826
cargo fix imports
distractedm1nd Aug 22, 2024
84b92c9
removing unused deps
distractedm1nd Aug 22, 2024
a529be0
adding pp serde
distractedm1nd Aug 22, 2024
fbf51c8
updating cargo toml
distractedm1nd Aug 23, 2024
5cefa2a
feat: playing around with supernova rehashing
sebasti810 Aug 29, 2024
728e28b
membership proof
distractedm1nd Sep 8, 2024
503f862
invalid witness length
distractedm1nd Sep 9, 2024
06028ca
i give up
distractedm1nd Sep 9, 2024
9a32adf
restructuring to crates
distractedm1nd Sep 11, 2024
b03b8eb
readding groth16 as new crate
distractedm1nd Sep 11, 2024
fcbb881
readding groth16 as new crate
distractedm1nd Sep 11, 2024
6eea609
adding sp1 crate
distractedm1nd Sep 11, 2024
7ec533e
trimming deps
distractedm1nd Sep 11, 2024
1cbc0ba
readmes
distractedm1nd Sep 11, 2024
cc64352
clippy
distractedm1nd Sep 11, 2024
e7d657f
readmes and clippy
distractedm1nd Sep 11, 2024
54316b8
merging
distractedm1nd Sep 11, 2024
9ef3ea5
debugging storage.rs for jmt
distractedm1nd Sep 11, 2024
f4931f9
fixing tests
distractedm1nd Sep 11, 2024
300b76d
patches
distractedm1nd Sep 11, 2024
91a5e68
clippy
distractedm1nd Sep 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,068 changes: 1,038 additions & 2,030 deletions Cargo.lock

Large diffs are not rendered by default.

74 changes: 46 additions & 28 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[package]
[workspace.package]
name = "prism"
version = "0.1.0"
authors = [
Expand All @@ -13,66 +13,84 @@ license = "MIT"
keywords = ["crypto", "key-transparency"]
readme = "README.md"

[features]
default = []
key_transparency = []
[workspace]
members = [
"crates/prism",
"crates/common",
"crates/nova",
"crates/groth16",
"crates/errors",
"crates/sp1",
]
default-members = [
"crates/prism",
"crates/common",
"crates/nova",
"crates/groth16",
"crates/errors",
]
resolver = "2"

[dependencies]
[workspace.dependencies]
axum = "0.6"
borsh = { version = "1.5.1", features = ["derive"] }
tower-http = { version = "0.4", features = ["cors"] }
utoipa = { version = "3.3", features = ["axum_extras"] }
utoipa-swagger-ui = { version = "3.1", features = ["axum"] }
crypto-hash = "0.3.4"
async-trait = "0.1.68"
serde = { version = "1.0.151", features = ["derive"] }
serde_json = "1.0.79"
redis = "0.24.0"
actix-web = { version = "4.4.1" }
actix-cors = "0.7.0"
async-redis-session = "0.2.2"
ed25519-dalek = "2.1.0"
ed25519 = "2.2.0"
base64 = "0.22.0"
tokio = { version = "1.16.1", features = ["full"] }
reqwest = { version = "0.11.23", features = ["json"] }
ctrlc = "3.1.5"
num = "0.4.0"
bellman = "0.14.0"
pairing = "0.23.0"
jsonrpsee = { version = "0.22.2", features = ["ws-client"] }
bls12_381 = "0.8.0"
rand = "0.8.5"
rand07 = { package = "rand", version = "0.7.0" }
hex = "0.4.3"
ff = "0.13.0"
openssl = "0.10.66"
futures = "0.3"
lazy_static = "1.4"
colored = "2.0.0"
log = "0.4"
pretty_env_logger = "0.5.0"
clap = { version = "4.3.2", features = ["derive"] }
config = "0.14.0"
fs2 = "0.4.3"
thiserror = "1.0.62"
indexed-merkle-tree = "0.6.2"
dotenvy = "0.15.7"
ahash = "0.8.7"
celestia-rpc = "0.2.0"
celestia-types = "0.2.0"
mockall = "0.12.1"
keystore-rs = "0.1.0"
pyroscope = "0.5.7"
pyroscope_pprofrs = "0.2.7"
toml = "0.8.14"
dirs = "5.0.1"
anyhow = "1.0.44"
jmt = { path = "../jmt", features = [
"mocks",
] } #{ version = "0.10.0", features = ["mocks"] }
bellpepper-core = { version = "0.4.0", default-features = false }
bellpepper = "0.4.1"
arecibo = { git = "https://github.com/deltadevsde/arecibo" }
itertools = "0.13.0" # zip_eq
sha2 = "0.10.8"
auto_impl = "1.2.0"
bincode = "1.3.3"
blake2 = "0.10.6"
sp1-zkvm = { version = "1.2.0" }
prism-common = { path = "crates/common" }
prism-nova = { path = "crates/nova" }
prism-errors = { path = "crates/errors" }
prism-main = { path = "crates/prism" }
prism-groth16 = { path = "crates/groth16" }
sp1-helper = "1.2.0"

[patch.crates-io]
sha2-v0-10-8 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha2", branch = "patch-sha2-v0.10.8" }

[dev-dependencies]
serial_test = "3.1.1"
criterion = "0.5.1"
# [workspace.dev-dependencies]
# serial_test = "3.1.1"
# criterion = "0.5.1"

[[bench]]
name = "zk_benchmarks"
harness = false
# [[bench]]
# name = "zk_benchmarks"
# harness = false
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

## What is Prism?

Prism is a decentralized key transparency protocol, strongly inspired by the paper [Tzialla et. al](https://eprint.iacr.org/2021/1263.pdf), leveraging zkSNARKs to enable trust-minimized verification of E2EE services via WASM light clients. This eliminates the possibility for hidden backdoors in E2EE services through a user-verifiable key management system. It uses transparency dictionaries under the hood, offering a generalized solution for managing a label-value map in environments where the service maintaining the map is not completely trusted.
Prism is a decentralized key transparency protocol, first inspired by the paper [Tzialla et. al](https://eprint.iacr.org/2021/1263.pdf), leveraging zkSNARKs to enable trust-minimized verification of E2EE services via WASM light clients. This eliminates the possibility for hidden backdoors in E2EE services through a user-verifiable key management system. It uses transparency dictionaries under the hood, offering a generalized solution for managing a label-value map in environments where the service maintaining the map is not completely trusted.

Prism provides the first key-transparency solution to enable automatic verification of the service provider. This is achieved by providing constant size succinct proofs to WASM light clients over a data availbility layer. The system is designed to be efficient, scalable and secure, making it suitable for a wide range of applications.

Expand All @@ -30,6 +30,9 @@ The project is still in the early development phase, has not been audited, and i

Due to this ongoing development work, changes are still being made that may affect existing functionalities.

## Circuits
We are currently experimenting with various proof systems and have handwritten groth16 and supernova circuits to handle the epoch proofs. We are also experimenting with SP1 as an alternative, which you can find in the `prism-sp1` crate.

## Installation

### Prerequisites
Expand Down
27 changes: 13 additions & 14 deletions benches/zk_benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use indexed_merkle_tree::{
tree::{IndexedMerkleTree, Proof},
Hash,
};
use prism::{circuits::BatchMerkleProofCircuit, utils::validate_epoch};
use rand::Rng;
use std::time::Duration;

Expand Down Expand Up @@ -56,13 +55,13 @@ fn bench_proof_generation(c: &mut Criterion) {
let (_, proofs, prev_commitment, current_commitment) =
setup_tree_and_proofs(*tree_size, *batch_size);
b.iter(|| {
let circuit = BatchMerkleProofCircuit::new(
black_box(&prev_commitment),
black_box(&current_commitment),
black_box(proofs.clone()),
)
.unwrap();
let _ = circuit.create_and_verify_snark();
// let circuit = BatchMerkleProofCircuit::new(
// black_box(&prev_commitment),
// black_box(&current_commitment),
// black_box(proofs.clone()),
// )
// .unwrap();
// let _ = circuit.create_and_verify_snark();
});
},
);
Expand All @@ -85,17 +84,17 @@ fn bench_proof_verification(c: &mut Criterion) {
|b, &(tree_size, batch_size)| {
let (_, proofs, prev_commitment, current_commitment) =
setup_tree_and_proofs(*tree_size, *batch_size);
let circuit =
BatchMerkleProofCircuit::new(&prev_commitment, &current_commitment, proofs)
.unwrap();
let (proof, verifying_key) = circuit.create_and_verify_snark().unwrap();
// let circuit =
// BatchMerkleProofCircuit::new(&prev_commitment, &current_commitment, proofs)
// .unwrap();
// let (proof, verifying_key) = circuit.create_and_verify_snark().unwrap();
b.iter(|| {
let _ = validate_epoch(
/* let _ = validate_epoch(
black_box(&prev_commitment),
black_box(&current_commitment),
black_box(proof.clone()),
black_box(verifying_key.clone()),
);
); */
});
},
);
Expand Down
18 changes: 18 additions & 0 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "prism-common"
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true

[dependencies]
anyhow.workspace = true
bls12_381.workspace = true
borsh.workspace = true
jmt.workspace = true
serde.workspace = true
hex.workspace = true
sha2.workspace = true
blake2.workspace = true
celestia-types.workspace = true
161 changes: 161 additions & 0 deletions crates/common/src/hashchain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
use anyhow::{bail, Result};
use borsh::{BorshDeserialize, BorshSerialize};
use jmt::KeyHash;
use serde::{Deserialize, Serialize};
use std::ops::{Deref, DerefMut};

use crate::{
operation::{AccountSource, Operation},
tree::{hash, Digest, Hasher},
};

#[derive(Clone, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq)]
pub struct Hashchain {
id: String,
entries: Vec<HashchainEntry>,
}

impl IntoIterator for Hashchain {
type Item = HashchainEntry;
type IntoIter = std::vec::IntoIter<Self::Item>;

fn into_iter(self) -> Self::IntoIter {
self.entries.into_iter()
}
}

impl<'a> IntoIterator for &'a Hashchain {
type Item = &'a HashchainEntry;
type IntoIter = std::slice::Iter<'a, HashchainEntry>;

fn into_iter(self) -> Self::IntoIter {
self.entries.iter()
}
}

impl<'a> IntoIterator for &'a mut Hashchain {
type Item = &'a mut HashchainEntry;
type IntoIter = std::slice::IterMut<'a, HashchainEntry>;

fn into_iter(self) -> Self::IntoIter {
self.entries.iter_mut()
}
}

impl Deref for Hashchain {
type Target = Vec<HashchainEntry>;

fn deref(&self) -> &Self::Target {
&self.entries
}
}

impl DerefMut for Hashchain {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.entries
}
}

impl Hashchain {
pub fn new(id: String) -> Self {
Self {
id,
entries: Vec::new(),
}
}

pub fn iter(&self) -> std::slice::Iter<'_, HashchainEntry> {
self.entries.iter()
}

pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, HashchainEntry> {
self.entries.iter_mut()
}

pub fn create_account(&mut self, value: String, source: AccountSource) -> Result<Digest> {
let operation = Operation::CreateAccount {
id: self.id.clone(),
value,
source,
};
self.push(operation)
}

pub fn get(&self, idx: usize) -> &HashchainEntry {
&self.entries[idx]
}

pub fn push(&mut self, operation: Operation) -> Result<Digest> {
if let Operation::CreateAccount { .. } = operation {
bail!("Cannot CreateAccount on an already existing hashchain");
}
if operation.id() != self.id {
bail!("Operation ID does not match Hashchain ID");
}

let previous_hash = self
.entries
.last()
.map_or(Digest::new([0u8; 32]), |entry| entry.hash);

let entry = HashchainEntry::new(operation, previous_hash);
self.entries.push(entry.clone());

Ok(entry.hash)
}

// TODO: Obviously, this needs to be authenticated by an existing key.
pub fn add(&mut self, value: String) -> Result<Digest> {
let operation = Operation::Add {
id: self.id.clone(),
value,
};
self.push(operation)
}

pub fn revoke(&mut self, value: String) -> Result<Digest> {
let operation = Operation::Revoke {
id: self.id.clone(),
value,
};
self.push(operation)
}

pub fn get_keyhash(&self) -> KeyHash {
KeyHash::with::<Hasher>(self.id.clone())
}

pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}

pub fn len(&self) -> usize {
self.entries.len()
}
}

#[derive(Clone, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq)]
// A [`HashchainEntry`] represents a single entry in an account's hashchain.
// The value in the leaf of the corresponding account's node in the IMT is the hash of the last node in the hashchain.
pub struct HashchainEntry {
pub hash: Digest,
pub previous_hash: Digest,
pub operation: Operation,
}

impl HashchainEntry {
pub fn new(operation: Operation, previous_hash: Digest) -> Self {
let hash = {
let mut data = Vec::new();
data.extend_from_slice(operation.to_string().as_bytes());
data.extend_from_slice(previous_hash.as_ref());
// TODO: replace with sha256 after JMT complete
hash(&data)
};
Self {
hash,
previous_hash,
operation,
}
}
}
3 changes: 3 additions & 0 deletions crates/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod hashchain;
pub mod operation;
pub mod tree;
Loading
Loading