Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 7 additions & 7 deletions Cargo.lock

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

8 changes: 6 additions & 2 deletions mithril-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ chrono = { workspace = true }
ciborium = "0.2.2"
ckb-merkle-mountain-range = "0.6.1"
digest = { workspace = true }
ed25519-dalek = { version = "2.2.0", features = ["rand_core", "serde"] }
fixed = "1.31.0"
# Exact-pinned to 2.1.1 for compatibility with the RISC0 `curve25519-dalek`
# precompile fork (tagged on the 2.1.x line).
ed25519-dalek = { version = "=2.1.1", features = ["rand_core", "serde"] }
# Exact-pinned to 1.29.0 to stay buildable on the rustc the RISC0
# toolchain ships (fixed 1.30+ requires rustc 1.93).
fixed = "=1.29.0"
hex = { workspace = true }
kes-summed-ed25519 = { version = "0.2.1", features = ["serde_enabled", "sk_clone_enabled"] }
mithril-stm = { path = "../mithril-stm", version = ">=0.9", default-features = false }
Expand Down
4 changes: 3 additions & 1 deletion mithril-stm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ rug-backend = ["rug/default"]
anyhow = { workspace = true }
blake2 = "0.10.6"
# Enforce blst portable feature for runtime detection of Intel ADX instruction set.
blst = { version = "0.3.16", features = ["portable"] }
# Exact-pinned to 0.3.15 to match the dwarf harness divergence-1 pin
# (BLS identity-rejection layer). Bump in lockstep with that pin if upgraded.
blst = { version = "=0.3.15", features = ["portable"] }
ciborium = "0.2.2"
digest = { workspace = true }
ff = { version = "0.13.1", optional = true }
Expand Down
11 changes: 9 additions & 2 deletions mithril-stm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ mod proof_system;
mod protocol;
mod signature_scheme;

pub use proof_system::AggregateVerificationKeyForConcatenation;
pub use proof_system::{
AggregateVerificationKeyForConcatenation, ConcatenationProof, SingleSignatureForConcatenation,
};
pub use protocol::{
AggregateSignature, AggregateSignatureError, AggregateSignatureType, AggregateVerificationKey,
AggregationError, Clerk, ClosedKeyRegistration, ClosedRegistrationEntry, Initializer,
Expand All @@ -134,6 +136,11 @@ pub use protocol::{
};
pub use signature_scheme::BlsSignatureError;

// Re-export Merkle types for custom serializer / deserializer consumers (e.g. risc0).
pub use membership_commitment::{
MerkleBatchPath, MerkleTreeBatchCommitment, MerkleTreeConcatenationLeaf, MerkleTreeLeaf,
};

use blake2::{Blake2b, digest::consts::U32};
use digest::{Digest, FixedOutput};
use std::fmt::Debug;
Expand All @@ -152,7 +159,7 @@ pub use signature_scheme::{
#[cfg(all(feature = "future_snark", not(feature = "benchmark-internals")))]
use hash::poseidon::MidnightPoseidonDigest;

#[cfg(feature = "benchmark-internals")]
#[cfg(all(feature = "benchmark-internals", feature = "future_snark"))]
pub use hash::poseidon::MidnightPoseidonDigest;

#[cfg(feature = "future_snark")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ pub struct MerkleTreeBatchCommitment<D: Digest, L: MerkleTreeLeaf> {
}

impl<D: Digest + FixedOutput, L: MerkleTreeLeaf> MerkleTreeBatchCommitment<D, L> {
pub(crate) fn new(root: Vec<u8>, nr_leaves: usize) -> Self {
// Made public for AVK reconstruction from byte form in custom serializer
// consumers (e.g. risc0).
pub fn new(root: Vec<u8>, nr_leaves: usize) -> Self {
Self {
root,
nr_leaves,
Expand All @@ -127,6 +129,11 @@ impl<D: Digest + FixedOutput, L: MerkleTreeLeaf> MerkleTreeBatchCommitment<D, L>
}
}

/// Number of leaves in the committed Merkle tree.
pub fn nr_leaves(&self) -> usize {
self.nr_leaves
}

#[cfg(feature = "future_snark")]
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
Expand Down
12 changes: 12 additions & 0 deletions mithril-stm/src/membership_commitment/merkle_tree/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ impl<D: Digest + FixedOutput> MerkleBatchPath<D> {
codec::to_cbor_bytes(self)
}

/// Borrow the path's value list. Exposed for custom serializer / deserializer
/// consumers (e.g. risc0) that need the legacy raw byte layout.
pub fn values(&self) -> &[Vec<u8>] {
&self.values
}

/// Borrow the path's index list. Exposed for custom serializer / deserializer
/// consumers (e.g. risc0) that need the legacy raw byte layout.
pub fn indices(&self) -> &[usize] {
&self.indices
}

/// Try to convert a byte string into a `BatchPath`.
pub fn from_bytes(bytes: &[u8]) -> StmResult<Self> {
codec::from_versioned_bytes(bytes, Self::from_bytes_legacy)
Expand Down
31 changes: 28 additions & 3 deletions mithril-stm/src/proof_system/concatenation/aggregate_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,33 @@ pub struct AggregateVerificationKeyForConcatenation<D: MembershipDigest> {
}

impl<D: MembershipDigest> AggregateVerificationKeyForConcatenation<D> {
/// Construct from already-built components. Exposed for custom
/// serializer / deserializer consumers (e.g. risc0).
pub fn new(
mt_commitment: MerkleTreeBatchCommitment<D::ConcatenationHash, MerkleTreeConcatenationLeaf>,
total_stake: Stake,
) -> Self {
Self {
mt_commitment,
total_stake,
}
}

/// Get the Merkle tree batch commitment.
pub(crate) fn get_merkle_tree_batch_commitment(
&self,
) -> MerkleTreeBatchCommitment<D::ConcatenationHash, MerkleTreeConcatenationLeaf> {
self.mt_commitment.clone()
}

/// Borrow the Merkle tree batch commitment. Exposed for custom
/// serializer consumers that need byte-level access to root + nr_leaves.
pub fn get_mt_commitment(
&self,
) -> &MerkleTreeBatchCommitment<D::ConcatenationHash, MerkleTreeConcatenationLeaf> {
&self.mt_commitment
}

/// Get the total stake.
pub fn get_total_stake(&self) -> Stake {
self.total_stake
Expand All @@ -48,11 +68,16 @@ impl<D: MembershipDigest> AggregateVerificationKeyForConcatenation<D> {
let mut u64_bytes = [0u8; 8];
let size = bytes.len();

// Guard against short inputs: a legacy AVK ends with an 8-byte
// stake suffix. Without this check, `&bytes[size - 8..]` panics
// with an out-of-range slice index on inputs shorter than 8
// bytes instead of returning a proper serialization error.
let mt_commitment_slice = bytes
.get(..size.checked_sub(8).ok_or(MerkleTreeError::SerializationError)?)
.ok_or(MerkleTreeError::SerializationError)?;
u64_bytes.copy_from_slice(&bytes[size - 8..]);
let stake = u64::from_be_bytes(u64_bytes);
let mt_commitment = MerkleTreeBatchCommitment::from_bytes(
bytes.get(..size - 8).ok_or(MerkleTreeError::SerializationError)?,
)?;
let mt_commitment = MerkleTreeBatchCommitment::from_bytes(mt_commitment_slice)?;
Ok(Self {
mt_commitment,
total_stake: stake,
Expand Down
2 changes: 1 addition & 1 deletion mithril-stm/src/proof_system/concatenation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ pub use clerk::ConcatenationClerk;
pub(super) use eligibility::is_lottery_won;
pub use proof::ConcatenationProof;
pub(crate) use signer::ConcatenationProofSigner;
pub(crate) use single_signature::SingleSignatureForConcatenation;
pub use single_signature::SingleSignatureForConcatenation;
17 changes: 17 additions & 0 deletions mithril-stm/src/proof_system/concatenation/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ pub struct ConcatenationProof<D: MembershipDigest> {
}

impl<D: MembershipDigest> ConcatenationProof<D> {
/// Construct a `ConcatenationProof` from already-aggregated components.
/// Exposed for custom serializer / deserializer consumers (e.g. risc0).
pub fn new(
signatures: Vec<SingleSignatureWithRegisteredParty>,
batch_proof: MerkleBatchPath<D::ConcatenationHash>,
) -> Self {
Self {
signatures,
batch_proof,
}
}

/// Borrow the underlying signatures. Exposed for custom serializer consumers.
pub fn signatures(&self) -> &[SingleSignatureWithRegisteredParty] {
&self.signatures
}

/// Aggregate a set of signatures for their corresponding indices.
///
/// This function first deduplicates the repeated signatures, and if there are enough signatures, it collects the merkle tree indexes of unique signatures.
Expand Down
16 changes: 13 additions & 3 deletions mithril-stm/src/proof_system/concatenation/single_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::is_lottery_won;

/// Single signature for the concatenation proof system.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct SingleSignatureForConcatenation {
pub struct SingleSignatureForConcatenation {
/// The underlying BLS signature
sigma: BlsSignature,
/// The index(es) for which the signature is valid
Expand All @@ -22,11 +22,21 @@ pub(crate) struct SingleSignatureForConcatenation {

impl SingleSignatureForConcatenation {
/// Create and return a new instance of `SingleSignatureForConcatenation` for given `sigma` and
/// `indexes`.
pub(crate) fn new(sigma: BlsSignature, indexes: Vec<LotteryIndex>) -> Self {
/// `indexes`. Exposed for custom serializer / deserializer consumers (e.g. risc0).
pub fn new(sigma: BlsSignature, indexes: Vec<LotteryIndex>) -> Self {
Self { sigma, indexes }
}

/// Borrow the underlying BLS signature. Exposed for custom serializer consumers.
pub fn sigma(&self) -> &BlsSignature {
&self.sigma
}

/// Borrow the lottery indices the signature is valid for. Exposed for custom serializer consumers.
pub fn indexes(&self) -> &[LotteryIndex] {
&self.indexes
}

/// Verify a `SingleSignatureForConcatenation` by validating the underlying BLS signature and checking
/// that the lottery was won for all indexes.
pub(crate) fn verify<D: MembershipDigest>(
Expand Down
3 changes: 2 additions & 1 deletion mithril-stm/src/proof_system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ mod halo2_snark;

pub use concatenation::{
AggregateVerificationKeyForConcatenation, ConcatenationClerk, ConcatenationProof,
SingleSignatureForConcatenation,
};
pub(crate) use concatenation::{ConcatenationProofSigner, SingleSignatureForConcatenation};
pub(crate) use concatenation::ConcatenationProofSigner;

#[cfg(feature = "future_snark")]
pub use halo2_snark::AggregateVerificationKeyForSnark;
Expand Down
20 changes: 20 additions & 0 deletions mithril-stm/src/protocol/single_signature/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@
}

impl SingleSignature {
/// Construct a `SingleSignature` from already-built components.
/// Exposed for custom serializer / deserializer consumers (e.g. risc0).
pub fn new(
concatenation_signature: SingleSignatureForConcatenation,
signer_index: SignerIndex,
#[cfg(feature = "future_snark")] snark_signature: Option<SingleSignatureForSnark>,
) -> Self {

Check warning

Code scanning / clippy

type proof_system::halo2_snark::single_signature::SingleSignatureForSnark is more private than the item protocol::single_signature::signature::SingleSignature::new Warning

type proof_system::halo2_snark::single_signature::SingleSignatureForSnark is more private than the item protocol::single_signature::signature::SingleSignature::new

Check warning

Code scanning / clippy

type proof_system::halo2_snark::single_signature::SingleSignatureForSnark is more private than the item protocol::single_signature::signature::SingleSignature::new Warning

type proof_system::halo2_snark::single_signature::SingleSignatureForSnark is more private than the item protocol::single_signature::signature::SingleSignature::new

Check warning

Code scanning / clippy

type proof_system::halo2_snark::single_signature::SingleSignatureForSnark is more private than the item protocol::single_signature::signature::SingleSignature::new Warning

type proof_system::halo2_snark::single_signature::SingleSignatureForSnark is more private than the item protocol::single_signature::signature::SingleSignature::new
Comment on lines +35 to +39
Comment on lines +35 to +39
Self {
concatenation_signature,
signer_index,
#[cfg(feature = "future_snark")]
snark_signature,
}
}

/// Borrow the concatenation-proof-system signature. Exposed for custom serializer consumers.
pub fn concatenation_signature(&self) -> &SingleSignatureForConcatenation {
&self.concatenation_signature
}

/// Verify a `SingleSignature` by validating the underlying single signature for proof system.
pub fn verify<D: MembershipDigest>(
&self,
Expand Down
Loading