Skip to content

Commit

Permalink
feat: implement "commitment" and add placeholder "verify" functions t…
Browse files Browse the repository at this point in the history
…o node types
  • Loading branch information
morph-dev committed Jul 16, 2024
1 parent 2f0954e commit e77bbdb
Show file tree
Hide file tree
Showing 11 changed files with 358 additions and 71 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions portal-verkle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ once_cell = "1"
serde = { version = "1", features = ["derive"] }
sha2 = "0.10"
ssz_types = "0.6"
thiserror = "1"

[dev-dependencies]
anyhow = "1"
Expand Down
10 changes: 5 additions & 5 deletions portal-verkle/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pub const HEADER_STORAGE_OFFSET: U256 = U256::from_limbs([64, 0, 0, 0]);
pub const CODE_OFFSET: U256 = U256::from_limbs([128, 0, 0, 0]);
pub const MAIN_STORAGE_OFFSET: U256 = U256::from_limbs([0, 0, 0, 1 << 56]);

// Extension node indices
pub const EXTENSION_MARKER_INDEX: usize = 0;
pub const EXTENSION_STEM_INDEX: usize = 1;
pub const EXTENSION_C1_INDEX: usize = 2;
pub const EXTENSION_C2_INDEX: usize = 3;
// Leaf node indices
pub const LEAF_MARKER_INDEX: usize = 0;
pub const LEAF_STEM_INDEX: usize = 1;
pub const LEAF_C1_INDEX: usize = 2;
pub const LEAF_C2_INDEX: usize = 3;
7 changes: 7 additions & 0 deletions portal-verkle/src/ec/point.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{
fmt::Debug,
iter::Sum,
ops::{Add, Sub},
};

Expand Down Expand Up @@ -116,3 +117,9 @@ impl Sub<&Self> for Point {
Self(self.0 - rhs.0)
}
}

impl<'a> Sum<&'a Self> for Point {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(Self::zero(), |sum, item| sum + item)
}
}
66 changes: 66 additions & 0 deletions portal-verkle/src/nodes/branch_bundle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::cell::OnceCell;

use alloy_primitives::B256;
use ssz_derive::{Decode, Encode};

use crate::{
constants::PORTAL_NETWORK_NODE_WIDTH,
proof::BundleProof,
ssz::{SparseVector, TriePath, TrieProof},
Point,
};

use super::NodeVerificationError;

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct BranchBundleNodeWithProof {
pub node: BranchBundleNode,
pub block_hash: B256,
pub path: TriePath,
pub proof: TrieProof,
}

impl BranchBundleNodeWithProof {
pub fn verify(
&self,
commitment: &Point,
_state_root: &B256,
) -> Result<(), NodeVerificationError> {
if commitment != self.node.commitment() {
return Err(NodeVerificationError::new_wrong_commitment(
commitment,
self.node.commitment(),
));
}
// TODO: add implementataion
Ok(())
}
}

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct BranchBundleNode {
fragments: SparseVector<Point, PORTAL_NETWORK_NODE_WIDTH>,
bundle_proof: BundleProof,
#[ssz(skip_serializing, skip_deserializing)]
commitment: OnceCell<Point>,
}

impl BranchBundleNode {
pub fn fragments(&self) -> &SparseVector<Point, PORTAL_NETWORK_NODE_WIDTH> {
&self.fragments
}

pub fn bundle_proof(&self) -> &BundleProof {
&self.bundle_proof
}

pub fn verify_bundle_proof(&self) -> Result<(), NodeVerificationError> {
// TODO: add implementataion
Ok(())
}

pub fn commitment(&self) -> &Point {
self.commitment
.get_or_init(|| self.fragments.iter_set_items().sum())
}
}
68 changes: 68 additions & 0 deletions portal-verkle/src/nodes/branch_fragment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::cell::OnceCell;

use alloy_primitives::B256;
use ssz_derive::{Decode, Encode};

use crate::{
constants::PORTAL_NETWORK_NODE_WIDTH,
msm::{DefaultMsm, MultiScalarMultiplicator},
ssz::{SparseVector, TriePath, TrieProof},
Point,
};

use super::NodeVerificationError;

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct BranchFragmentNodeWithProof {
pub node: BranchFragmentNode,
pub block_hash: B256,
pub path: TriePath,
pub proof: TrieProof,
}

impl BranchFragmentNodeWithProof {
pub fn verify(
&self,
commitment: &Point,
_state_root: &B256,
) -> Result<(), NodeVerificationError> {
if commitment != self.node.commitment() {
return Err(NodeVerificationError::new_wrong_commitment(
commitment,
self.node.commitment(),
));
}
// TODO: add implementataion
Ok(())
}
}

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct BranchFragmentNode {
fragment_index: u8,
children: SparseVector<Point, PORTAL_NETWORK_NODE_WIDTH>,
#[ssz(skip_serializing, skip_deserializing)]
commitment: OnceCell<Point>,
}

impl BranchFragmentNode {
pub fn fragment_index(&self) -> usize {
self.fragment_index as usize
}

pub fn children(&self) -> &SparseVector<Point, PORTAL_NETWORK_NODE_WIDTH> {
&self.children
}

pub fn commitment(&self) -> &Point {
self.commitment.get_or_init(|| {
self.children
.iter_enumerated_set_items()
.map(|(child_index, child)| {
let index = child_index + self.fragment_index() * PORTAL_NETWORK_NODE_WIDTH;
DefaultMsm.scalar_mul(index, child.map_to_scalar_field())
})
.sum()
})
}
}
24 changes: 24 additions & 0 deletions portal-verkle/src/nodes/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use thiserror::Error;

use crate::Point;

#[derive(Debug, Error)]
pub enum NodeVerificationError {
#[error("Commitment doesn't match. expected: {expected:?} actual: {actual:?}")]
WrongCommitment {
expected: Box<Point>,
actual: Box<Point>,
},

#[error("Bundle proof is invalid")]
InvalidBundleProof,
}

impl NodeVerificationError {
pub fn new_wrong_commitment(expected: &Point, actual: &Point) -> Self {
Self::WrongCommitment {
expected: expected.clone().into(),
actual: actual.clone().into(),
}
}
}
94 changes: 94 additions & 0 deletions portal-verkle/src/nodes/leaf_bundle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::cell::OnceCell;

use alloy_primitives::B256;
use ssz_derive::{Decode, Encode};

use crate::{
constants::{
LEAF_C1_INDEX, LEAF_C2_INDEX, LEAF_MARKER_INDEX, LEAF_STEM_INDEX, PORTAL_NETWORK_NODE_WIDTH,
},
msm::{DefaultMsm, MultiScalarMultiplicator},
proof::BundleProof,
ssz::{SparseVector, TrieProof},
Point, ScalarField, Stem,
};

use super::NodeVerificationError;

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct LeafBundleNodeWithProof {
pub node: LeafBundleNode,
pub block_hash: B256,
pub proof: TrieProof,
}

impl LeafBundleNodeWithProof {
pub fn verify(
&self,
commitment: &Point,
_state_root: &B256,
) -> Result<(), NodeVerificationError> {
if commitment != self.node.commitment() {
return Err(NodeVerificationError::new_wrong_commitment(
commitment,
self.node.commitment(),
));
}
// TODO: add implementataion
Ok(())
}
}

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct LeafBundleNode {
marker: u64,
stem: Stem,
fragments: SparseVector<Point, PORTAL_NETWORK_NODE_WIDTH>,
bundle_proof: BundleProof,
#[ssz(skip_serializing, skip_deserializing)]
commitment: OnceCell<Point>,
}

impl LeafBundleNode {
pub fn marker(&self) -> u64 {
self.marker
}

pub fn stem(&self) -> &Stem {
&self.stem
}

pub fn fragments(&self) -> &SparseVector<Point, PORTAL_NETWORK_NODE_WIDTH> {
&self.fragments
}

pub fn bundle_proof(&self) -> &BundleProof {
&self.bundle_proof
}

pub fn verify_bundle_proof(&self) -> Result<(), NodeVerificationError> {
// TODO: add implementataion
Ok(())
}

pub fn commitment(&self) -> &Point {
self.commitment.get_or_init(|| {
let (c1, c2) = self.fragments.iter_enumerated_set_items().fold(
(Point::zero(), Point::zero()),
|(c1, c2), (index, child)| {
if index < PORTAL_NETWORK_NODE_WIDTH / 2 {
(c1 + child, c2)
} else {
(c1, c2 + child)
}
},
);
DefaultMsm.commit_sparse(&[
(LEAF_MARKER_INDEX, ScalarField::from(self.marker)),
(LEAF_STEM_INDEX, ScalarField::from(&self.stem)),
(LEAF_C1_INDEX, c1.map_to_scalar_field()),
(LEAF_C2_INDEX, c2.map_to_scalar_field()),
])
})
}
}
79 changes: 79 additions & 0 deletions portal-verkle/src/nodes/leaf_fragment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::cell::OnceCell;

use alloy_primitives::B256;
use ssz_derive::{Decode, Encode};

use crate::{
constants::PORTAL_NETWORK_NODE_WIDTH,
msm::{DefaultMsm, MultiScalarMultiplicator},
ssz::{SparseVector, TrieProof},
Point, Stem, TrieValue, TrieValueSplit,
};

use super::NodeVerificationError;

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct LeafFragmentNodeWithProof {
pub node: LeafFragmentNode,
pub block_hash: B256,
pub proof: TrieProof,
}

impl LeafFragmentNodeWithProof {
pub fn verify(
&self,
commitment: &Point,
_state_root: &B256,
_stem: &Stem,
) -> Result<(), NodeVerificationError> {
if commitment != self.node.commitment() {
return Err(NodeVerificationError::new_wrong_commitment(
commitment,
self.node.commitment(),
));
}
// TODO: add implementataion
Ok(())
}
}

#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct LeafFragmentNode {
fragment_index: u8,
children: SparseVector<TrieValue, PORTAL_NETWORK_NODE_WIDTH>,
#[ssz(skip_serializing, skip_deserializing)]
commitment: OnceCell<Point>,
}

impl LeafFragmentNode {
pub fn fragment_index(&self) -> usize {
self.fragment_index as usize
}

pub fn children(&self) -> &SparseVector<TrieValue, PORTAL_NETWORK_NODE_WIDTH> {
&self.children
}

pub fn commitment(&self) -> &Point {
self.commitment.get_or_init(|| {
self.children
.iter_enumerated_set_items()
.map(|(child_index, child)| {
let (low_index, high_index) = self.bases_indices(child_index);
let (low_value, high_value) = child.split();
DefaultMsm.scalar_mul(low_index, low_value)
+ DefaultMsm.scalar_mul(high_index, high_value)
})
.sum()
})
}

/// Returns the bases indices that correspond to the child index.
fn bases_indices(&self, child_index: usize) -> (usize, usize) {
let fragment_starting_index =
self.fragment_index() % (PORTAL_NETWORK_NODE_WIDTH / 2) * 2 * PORTAL_NETWORK_NODE_WIDTH;
let low_index = fragment_starting_index + 2 * child_index;
let high_index = low_index + 1;
(low_index, high_index)
}
}
Loading

0 comments on commit e77bbdb

Please sign in to comment.