mirror of
https://github.com/logos-blockchain/logos-blockchain-pocs.git
synced 2026-01-10 09:03:12 +00:00
compact serialization (#46)
This commit is contained in:
parent
edec3632f1
commit
236a0d0d47
@ -19,7 +19,7 @@ pub fn leaf(data: &[u8]) -> [u8; 32] {
|
||||
hasher.finalize().into()
|
||||
}
|
||||
|
||||
pub fn node(a: [u8; 32], b: [u8; 32]) -> [u8; 32] {
|
||||
pub fn node(a: impl AsRef<[u8]>, b: impl AsRef<[u8]>) -> [u8; 32] {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"NOMOS_MERKLE_NODE");
|
||||
hasher.update(a);
|
||||
@ -55,12 +55,12 @@ pub fn path_root(leaf: [u8; 32], path: &[PathNode]) -> [u8; 32] {
|
||||
let mut computed_hash = leaf;
|
||||
|
||||
for path_node in path {
|
||||
match path_node {
|
||||
match &path_node {
|
||||
PathNode::Left(sibling_hash) => {
|
||||
computed_hash = node(*sibling_hash, computed_hash);
|
||||
computed_hash = node(sibling_hash, computed_hash);
|
||||
}
|
||||
PathNode::Right(sibling_hash) => {
|
||||
computed_hash = node(computed_hash, *sibling_hash);
|
||||
computed_hash = node(computed_hash, sibling_hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ledger_proof_statements::ledger::{LedgerBundleWitness, LedgerProofPrivate, LedgerProofPublic};
|
||||
use ledger_proof_statements::ledger::{
|
||||
CompactNullifierProofs, LedgerBundleWitness, LedgerProofPrivate, LedgerProofPublic,
|
||||
};
|
||||
|
||||
use crate::bundle::ProvedBundle;
|
||||
use cl::zone_layer::{ledger::LedgerState, notes::ZoneId};
|
||||
@ -49,7 +51,7 @@ impl ProvedLedgerTransition {
|
||||
let ledger_bundle = LedgerBundleWitness {
|
||||
bundle,
|
||||
cm_root_proofs,
|
||||
nf_proofs,
|
||||
nf_proofs: CompactNullifierProofs::from_paths(nf_proofs),
|
||||
};
|
||||
|
||||
witness.bundles.push(ledger_bundle)
|
||||
@ -93,3 +95,5 @@ impl ProvedLedgerTransition {
|
||||
.is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,4 +6,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
cl = { path = "../cl" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
sha2 = "0.10"
|
||||
sha2 = "0.10"
|
||||
@ -29,7 +29,7 @@ pub struct LedgerProofPrivate {
|
||||
pub struct LedgerBundleWitness {
|
||||
pub bundle: BundlePublic,
|
||||
pub cm_root_proofs: BTreeMap<[u8; 32], merkle::Path>,
|
||||
pub nf_proofs: Vec<merkle::Path>,
|
||||
pub nf_proofs: CompactNullifierProofs,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
@ -37,3 +37,104 @@ pub struct CrossZoneBundle {
|
||||
pub id: BundleId,
|
||||
pub zones: Vec<ZoneId>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct CompactNullifierProofs {
|
||||
pub siblings: Vec<u8>,
|
||||
pub paths: Vec<[u8; 32]>,
|
||||
}
|
||||
|
||||
impl CompactNullifierProofs {
|
||||
pub fn from_paths(input: Vec<merkle::Path>) -> Self {
|
||||
let mut siblings = Vec::with_capacity(input.len());
|
||||
let mut paths = Vec::with_capacity(input.len());
|
||||
|
||||
for path in input {
|
||||
let mut path_bits = [0u8; 32];
|
||||
assert_eq!(path.len(), 256);
|
||||
|
||||
for (i, node) in path.iter().enumerate().rev() {
|
||||
match node {
|
||||
merkle::PathNode::Left(sibling) => {
|
||||
siblings.extend(sibling.into_iter());
|
||||
}
|
||||
merkle::PathNode::Right(sibling) => {
|
||||
siblings.extend(sibling.into_iter());
|
||||
set_bit(i as u8, &mut path_bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
paths.push(path_bits);
|
||||
}
|
||||
|
||||
Self { siblings, paths }
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.paths.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for CompactNullifierProofs {
|
||||
type Item = merkle::Path;
|
||||
type IntoIter = CompactNfIterator;
|
||||
|
||||
fn into_iter(self) -> CompactNfIterator {
|
||||
CompactNfIterator {
|
||||
siblings: self.siblings,
|
||||
paths: self.paths,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CompactNfIterator {
|
||||
pub siblings: Vec<u8>,
|
||||
pub paths: Vec<[u8; 32]>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for CompactNfIterator {
|
||||
type Item = merkle::Path;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.paths.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let path = self.paths.pop().unwrap();
|
||||
|
||||
let mut res = Vec::with_capacity(256);
|
||||
|
||||
for i in 0..=255 {
|
||||
if get_bit(i, path) {
|
||||
res.push(merkle::PathNode::Right(
|
||||
self.siblings[self.siblings.len() - 32..]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
))
|
||||
} else {
|
||||
res.push(merkle::PathNode::Left(
|
||||
self.siblings[self.siblings.len() - 32..]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
))
|
||||
};
|
||||
self.siblings.truncate(self.siblings.len() - 32);
|
||||
}
|
||||
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_bit(idx: u8, elem: [u8; 32]) -> bool {
|
||||
let byte = idx / 8;
|
||||
let bit_in_byte = idx - byte * 8;
|
||||
|
||||
(elem[byte as usize] & (1 << bit_in_byte)) != 0
|
||||
}
|
||||
|
||||
fn set_bit(idx: u8, elem: &mut [u8; 32]) {
|
||||
let byte = idx / 8;
|
||||
let bit_in_byte = idx - byte * 8;
|
||||
|
||||
elem[byte as usize] |= 1 << bit_in_byte;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use cl::cl::merkle;
|
||||
use ledger_proof_statements::{
|
||||
ledger::{CrossZoneBundle, LedgerProofPrivate, LedgerProofPublic, LedgerBundleWitness},
|
||||
use ledger_proof_statements::ledger::{
|
||||
CrossZoneBundle, LedgerBundleWitness, LedgerProofPrivate, LedgerProofPublic,
|
||||
};
|
||||
use risc0_zkvm::{guest::env, serde};
|
||||
|
||||
@ -15,12 +15,23 @@ fn main() {
|
||||
let mut cross_bundles = vec![];
|
||||
let mut outputs = vec![];
|
||||
|
||||
for LedgerBundleWitness { bundle, cm_root_proofs, nf_proofs } in bundles {
|
||||
env::verify(nomos_cl_bundle_risc0_proof::BUNDLE_ID, &serde::to_vec(&bundle).unwrap()).unwrap();
|
||||
for LedgerBundleWitness {
|
||||
bundle,
|
||||
cm_root_proofs,
|
||||
nf_proofs,
|
||||
} in bundles
|
||||
{
|
||||
env::verify(
|
||||
nomos_cl_bundle_risc0_proof::BUNDLE_ID,
|
||||
&serde::to_vec(&bundle).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(ledger_update) = bundle.zone_ledger_updates.get(&id) {
|
||||
for past_cm_root in &ledger_update.cm_roots {
|
||||
let past_cm_root_proof = cm_root_proofs.get(past_cm_root).expect("missing cm root proof");
|
||||
let past_cm_root_proof = cm_root_proofs
|
||||
.get(past_cm_root)
|
||||
.expect("missing cm root proof");
|
||||
let expected_current_cm_root = merkle::path_root(*past_cm_root, past_cm_root_proof);
|
||||
assert!(old_ledger.valid_cm_root(expected_current_cm_root))
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user