Skip to content
Closed
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
2 changes: 1 addition & 1 deletion mithril-stm/benches/size_benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ where
let mut key_reg = KeyRegistration::initialize();
for stake in parties {
let p = Initializer::new(params, stake, &mut rng);
key_reg.register_by_entry(&p.clone().into()).unwrap();
key_reg.register_by_entry(&p.clone().try_into().unwrap()).unwrap();
ps.push(p);
}

Expand Down
4 changes: 2 additions & 2 deletions mithril-stm/benches/stm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn stm_benches<D: MembershipDigest>(
// We need to initialise the key_reg at each iteration
key_reg = KeyRegistration::initialize();
for p in initializers.iter() {
key_reg.register_by_entry(&p.clone().into()).unwrap();
key_reg.register_by_entry(&p.clone().try_into().unwrap()).unwrap();
}
})
});
Expand Down Expand Up @@ -115,7 +115,7 @@ fn batch_benches<D>(
}
let mut key_reg = KeyRegistration::initialize();
for p in initializers.iter() {
key_reg.register_by_entry(&p.clone().into()).unwrap();
key_reg.register_by_entry(&p.clone().try_into().unwrap()).unwrap();
}

let closed_reg = key_reg.close_registration();
Expand Down
7 changes: 7 additions & 0 deletions mithril-stm/src/membership_commitment/merkle_tree/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ pub enum MerkleTreeError {
/// Invalid merkle batch path
#[error("Batch path does not verify against root")]
BatchPathInvalid(Vec<u8>),

/// Leaf not found in the merkle tree
#[cfg(feature = "future_snark")]
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
#[error("Leaf not found in the merkle tree")]
LeafNotFound,
}
12 changes: 12 additions & 0 deletions mithril-stm/src/membership_commitment/merkle_tree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,18 @@ impl<D: Digest + FixedOutput, L: MerkleTreeLeaf> MerkleTree<D, L> {
})
}

/// Find the index of a leaf in the Merkle tree.
/// Returns the index if the leaf is found, or an error otherwise.
#[cfg(feature = "future_snark")]
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
pub(crate) fn find_leaf_index(&self, leaf: &L) -> StmResult<usize> {
let leaf_hash = D::digest(leaf.as_bytes_for_merkle_tree()).to_vec();
(0..self.n)
.find(|&i| self.nodes[self.leaf_off + i] == leaf_hash)
.ok_or_else(|| MerkleTreeError::LeafNotFound.into())
}

#[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
2 changes: 1 addition & 1 deletion mithril-stm/src/proof_system/concatenation/clerk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ mod tests {
for i in 0..nparties {
let stake = (i as u64 + 1) * 10;
let initializer = Initializer::new(params, stake, &mut rng);
key_registration.register_by_entry(&initializer.clone().into()).unwrap();
key_registration.register_by_entry(&initializer.clone().try_into().unwrap()).unwrap();
initializers.push(initializer);
}

Expand Down
141 changes: 141 additions & 0 deletions mithril-stm/src/proof_system/halo2_snark/clerk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use std::collections::{BTreeMap, HashMap, HashSet};

use crate::{
AggregationError, ClosedKeyRegistration, LotteryIndex, MembershipDigest, Parameters,
RegistrationEntryForSnark, Signer, StmResult,
};

use super::{AggregateVerificationKeyForSnark, witness::SignatureRegistrationEntry};

/// The `SnarkClerk` is responsible for managing the proof system related to
/// SNARK signatures.
#[derive(Debug, Clone)]
pub struct SnarkClerk {
Comment thread Fixed
Comment thread Fixed
/// The closed key registration associated with this clerk.
pub(crate) closed_key_registration: ClosedKeyRegistration,
/// Protocol parameters
pub(crate) parameters: Parameters,
Comment thread Fixed
Comment thread Fixed
}

// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
impl SnarkClerk {
/// Create a new `SnarkClerk` from a closed registration instance.
pub fn new_clerk_from_closed_key_registration(
parameters: &Parameters,
closed_key_registration: &ClosedKeyRegistration,
) -> Self {
Self {
parameters: *parameters,
closed_key_registration: closed_key_registration.clone(),
}
}

/// Create a `SnarkClerk` from a signer.
pub fn new_clerk_from_signer<D: MembershipDigest>(signer: &Signer<D>) -> Self {
Self {
parameters: signer.parameters,
closed_key_registration: signer.closed_key_registration.clone(),
}
}

/// Compute the `AggregateVerificationKeyForSnark` related to the used registration.
pub fn compute_aggregate_verification_key_for_snark<D: MembershipDigest>(
&self,
) -> AggregateVerificationKeyForSnark<D> {
AggregateVerificationKeyForSnark::from(&self.closed_key_registration)
}

/// Get the SNARK registration entry for a given signer index.
pub fn get_snark_registration_entry(
&self,
signer_index: LotteryIndex,
) -> StmResult<Option<RegistrationEntryForSnark>> {
let closed_registration_entry = self
.closed_key_registration
.get_registration_entry_for_index(&signer_index)?;
Ok(closed_registration_entry.into())
}

/// Modifications:
/// Function inputs: remove `msg`, replace `sigs: &[SingleSignatureWithRegisteredParty]` with
/// `signatures: &[SignatureRegistrationEntry]`, remove avk.
/// Return value: `StmResult<Vec<SignatureRegistrationEntry>`.
/// Remove signature verification loop -> already done in aggregation step.
/// Rename `sig_reg` as `entry` for the first loop, since we iterate over entries now.
/// Rename `sig_reg` as `entry` for the second loop, since we iterate over entries now.
///
/// Note: schnorr sig, scalar field element, projective point are updated to satisfy `Hash`,
/// `Ord`, `PartialOrd`.
pub(crate) fn select_valid_signatures_for_k_indices(
parameters: &Parameters,
signatures: &[SignatureRegistrationEntry],
) -> StmResult<Vec<SignatureRegistrationEntry>> {
let mut sig_by_index: BTreeMap<LotteryIndex, &SignatureRegistrationEntry> = BTreeMap::new();
let mut removal_idx_by_vk: HashMap<&SignatureRegistrationEntry, Vec<LotteryIndex>> =
HashMap::new();

for entry in signatures.iter() {
for index in entry.get_signature().get_indices().iter() {
let mut insert_this_sig = false;
if let Some(&previous_entry) = sig_by_index.get(index) {
let entry_to_remove_index = if entry.get_signature().get_schnorr_signature()
< previous_entry.get_signature().get_schnorr_signature()
{
insert_this_sig = true;
previous_entry
} else {
entry
};

if let Some(indexes) = removal_idx_by_vk.get_mut(entry_to_remove_index) {
indexes.push(*index);
} else {
removal_idx_by_vk.insert(entry_to_remove_index, vec![*index]);
}
} else {
insert_this_sig = true;
}

if insert_this_sig {
sig_by_index.insert(*index, entry);
}
}
}

let mut dedup_sigs: HashSet<SignatureRegistrationEntry> = HashSet::new();
let mut count: u64 = 0;

for (_, &entry) in sig_by_index.iter() {
if dedup_sigs.contains(entry) {
continue;
}
let mut deduped_entry = entry.clone();
if let Some(indexes) = removal_idx_by_vk.get(entry) {
let indices = deduped_entry
.get_signature()
.get_indices()
.into_iter()
.filter(|i| !indexes.contains(i))
.collect::<Vec<LotteryIndex>>();
deduped_entry.set_indices(&indices);
}

let size: Result<u64, _> = deduped_entry.get_signature().get_indices().len().try_into();
if let Ok(size) = size {
if dedup_sigs.contains(&deduped_entry) {
panic!(
"Invariant violation: duplicate signature encountered in deduplication set, which should not be possible."
);
}
dedup_sigs.insert(deduped_entry);
count += size;

if count >= parameters.k {
return Ok(dedup_sigs.into_iter().collect());
}
}
}
Err(AggregationError::NotEnoughSignatures(count, parameters.k).into())
}
}
22 changes: 22 additions & 0 deletions mithril-stm/src/proof_system/halo2_snark/eligibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ cfg_num_integer! {
/// the value is. A value of 30 provides ~69 bits precision for phi_f=0.2
const TAYLOR_EXPANSION_ITERATIONS: usize = 30;

/// Computes the lottery target value for a given stake and total stake.
/// Phi_f is hardcoded for testing.
// TODO: pass phi_f as an argument instead of hardcoding it.
#[cfg(feature = "future_snark")]
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
pub fn compute_lottery_target_value(stake: Stake, total_stake: Stake) -> LotteryTargetValue{
let phi_f = 0.5;
let phi_f_ratio_int: Ratio<i64> =
Ratio::approximate_float(phi_f).expect("Only fails if the float is infinite or NaN.");
let phi_f_ratio = Ratio::new_raw(
BigInt::from(*phi_f_ratio_int.numer()),
BigInt::from(*phi_f_ratio_int.denom()),
);
let ln_one_minus_phi_f = ln_1p_taylor_expansion(
TAYLOR_EXPANSION_ITERATIONS,
phi_f_ratio.numer(),
phi_f_ratio.denom(),
);
compute_target_value(&ln_one_minus_phi_f, stake, total_stake)
}

#[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
Loading
Loading