Skip to content

Commit c9213ca

Browse files
authored
Merge pull request #254 from input-output-hk/backend_flag
Compilation flag with zcash's implementation
2 parents 23abfd2 + cf5d3ff commit c9213ca

File tree

10 files changed

+752
-53
lines changed

10 files changed

+752
-53
lines changed

Cargo.lock

Lines changed: 89 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-core/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ crate-type = ["lib", "cdylib", "staticlib"]
99

1010
[dependencies]
1111
blake2 = "0.9.2"
12-
blst = "0.3.7"
12+
bls12_381 = { version = "0.7.0", features = ["experimental"], optional = true }
13+
blst = { version = "0.3.7", optional = true }
1314
bytes = "1"
1415
digest = { version = "0.9.0", features = ["alloc"] }
1516
generic-array = "0.14"
17+
group = { version = "0.12.0", features = ["tests"], optional = true }
1618
libc = "0.2.40"
1719
num-bigint = "0.4.0"
1820
num-integer = { version = "0.1.44", optional = true }
@@ -52,6 +54,8 @@ name = "size_benches"
5254
harness = false
5355

5456
[features]
55-
default = ["rug"]
57+
default = ["rug", "zcash"]
5658
rug-backend = ["rug/default"]
5759
num-integer-backend = ["num-integer/default"]
60+
zcash = ["bls12_381", "group"]
61+
blast = ["blst"]

mithril-core/src/error.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
//! Crate specific errors
22
33
use crate::merkle_tree::Path;
4-
use crate::multi_sig::{Signature, VerificationKey, VerificationKeyPoP};
4+
#[cfg(feature = "zcash")]
5+
use crate::multi_sig_zcash::{Signature, VerificationKey, VerificationKeyPoP};
56
use crate::stm::PartyId;
6-
use blst::BLST_ERROR;
77
use digest::{Digest, FixedOutput};
8+
#[cfg(not(feature = "zcash"))]
9+
use {
10+
crate::multi_sig::{Signature, VerificationKey, VerificationKeyPoP},
11+
blst::BLST_ERROR,
12+
};
813

914
// todo: better organise these errors.
1015

@@ -81,6 +86,9 @@ pub enum AggregationFailure {
8186
/// Not enough signatures were collected, got this many instead.
8287
#[error("Not enough signatures. Got only {0} out of {1}.")]
8388
NotEnoughSignatures(u64, u64),
89+
/// This error happens when we try to convert a u64 to a usize and it does not fit
90+
#[error("Invalid usize conversion")]
91+
InvalidUsizeConversion,
8492
}
8593

8694
/// Error types for single signature verification
@@ -116,7 +124,7 @@ pub enum MerkleTreeError {
116124
pub enum RegisterError {
117125
/// This key has already been registered by a participant
118126
#[error("This key has already been registered.")]
119-
KeyRegistered(VerificationKey),
127+
KeyRegistered(Box<VerificationKey>),
120128
/// This participant has already been registered
121129
#[error("Participant {0} has already been registered.")]
122130
PartyRegistered(PartyId),
@@ -168,6 +176,7 @@ impl<D: Digest + Clone + FixedOutput> From<VerificationFailure<D>> for MithrilWi
168176
}
169177
}
170178

179+
#[cfg(not(feature = "zcash"))]
171180
pub(crate) fn blst_err_to_atms(e: BLST_ERROR) -> Result<(), MultiSignatureError> {
172181
match e {
173182
BLST_ERROR::BLST_SUCCESS => Ok(()),

mithril-core/src/key_reg.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ use digest::{Digest, FixedOutput};
55
use std::collections::{HashMap, HashSet};
66
use std::sync::Arc;
77

8-
use super::multi_sig::VerificationKeyPoP;
9-
use super::stm::{PartyId, Stake};
8+
#[cfg(not(feature = "zcash"))]
9+
use crate::multi_sig::{VerificationKey, VerificationKeyPoP};
10+
#[cfg(feature = "zcash")]
11+
use crate::multi_sig_zcash::{VerificationKey, VerificationKeyPoP};
1012

13+
use super::stm::{PartyId, Stake};
1114
use crate::merkle_tree::{MTLeaf, MerkleTree};
12-
use crate::multi_sig::VerificationKey;
1315

1416
/// Struct that collects public keys and stakes of parties. Each participant (both the
1517
/// signers and the clerks) need to run their own instance of the key registration.
@@ -73,7 +75,7 @@ impl KeyReg {
7375
pk: VerificationKeyPoP,
7476
) -> Result<(), RegisterError> {
7577
if self.keys.contains(&pk.vk) {
76-
return Err(RegisterError::KeyRegistered(pk.vk));
78+
return Err(RegisterError::KeyRegistered(Box::new(pk.vk)));
7779
}
7880

7981
if let Some(mut party) = self.parties.get_mut(&party_id) {
@@ -95,13 +97,17 @@ impl KeyReg {
9597
where
9698
D: Digest + FixedOutput,
9799
{
98-
let mut total_stake = 0;
100+
let mut total_stake: Stake = 0;
99101
let mut reg_parties = self
100102
.parties
101103
.iter()
102104
.filter_map(|(_, party)| {
103105
if let Some(vk) = party.vk {
104-
total_stake += party.stake;
106+
let (res, overflow) = total_stake.overflowing_add(party.stake);
107+
if overflow {
108+
panic!("Total stake overflow");
109+
}
110+
total_stake = res;
105111
return Some(MTLeaf(vk, party.stake));
106112
}
107113
None
@@ -126,15 +132,19 @@ impl Default for KeyReg {
126132
#[cfg(test)]
127133
mod tests {
128134
use super::*;
135+
#[cfg(not(feature = "zcash"))]
129136
use crate::multi_sig::SigningKey;
137+
#[cfg(feature = "zcash")]
138+
use crate::multi_sig_zcash::SigningKey;
130139
use blake2::Blake2b;
131140
use proptest::collection::vec;
132141
use proptest::prelude::*;
133142
use rand_chacha::ChaCha20Rng;
134143
use rand_core::SeedableRng;
135144

136145
fn arb_participants(min: usize, max: usize) -> impl Strategy<Value = Vec<(PartyId, Stake)>> {
137-
vec(any::<Stake>(), min..=max).prop_map(|v| {
146+
vec(1..1u64 << 60, min..=max).prop_map(|v| {
147+
// 1<<60 to avoid overflows
138148
v.into_iter()
139149
.enumerate()
140150
.map(|(index, value)| (index as u64, value))
@@ -184,7 +194,7 @@ mod tests {
184194
assert!(parties.insert(p.0));
185195
},
186196
Err(RegisterError::KeyRegistered(pk1)) => {
187-
assert!(pk1 == pk.vk);
197+
assert!(pk1.as_ref() == &pk.vk);
188198
assert!(keys.contains(&pk.vk));
189199
}
190200
Err(RegisterError::PartyRegistered(party)) => {

mithril-core/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ mod dense_mapping;
77
pub mod error;
88
pub mod key_reg;
99
pub mod merkle_tree;
10+
#[cfg(not(feature = "zcash"))]
1011
mod multi_sig;
12+
#[cfg(feature = "zcash")]
13+
mod multi_sig_zcash;
1114
pub mod stm;

mithril-core/src/merkle_tree.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Creation and verification of Merkle Trees
22
use crate::error::MerkleTreeError;
3+
#[cfg(not(feature = "zcash"))]
34
use crate::multi_sig::VerificationKey;
5+
#[cfg(feature = "zcash")]
6+
use crate::multi_sig_zcash::VerificationKey;
47
use crate::stm::Stake;
58
use digest::{Digest, FixedOutput};
69
use serde::{Deserialize, Serialize};
@@ -240,11 +243,7 @@ where
240243
/// * All nodes of the merkle tree (starting with the root)
241244
pub fn to_bytes(&self) -> Vec<u8> {
242245
let mut result = Vec::with_capacity(8 + self.nodes.len() * D::output_size());
243-
result.extend_from_slice(
244-
&u64::try_from(self.n)
245-
.expect("Length must fit in u32")
246-
.to_be_bytes(),
247-
);
246+
result.extend_from_slice(&u64::try_from(self.n).unwrap().to_be_bytes());
248247
for node in self.nodes.iter() {
249248
result.extend_from_slice(node);
250249
}
@@ -255,7 +254,8 @@ where
255254
pub fn from_bytes(bytes: &[u8]) -> Result<Self, MerkleTreeError> {
256255
let mut u64_bytes = [0u8; 8];
257256
u64_bytes.copy_from_slice(&bytes[..8]);
258-
let n = usize::try_from(u64::from_be_bytes(u64_bytes)).unwrap(); // todo: handle the conversion
257+
let n = usize::try_from(u64::from_be_bytes(u64_bytes))
258+
.map_err(|_| MerkleTreeError::SerializationError)?;
259259
let num_nodes = n + n.next_power_of_two() - 1;
260260
let mut nodes = Vec::with_capacity(num_nodes);
261261
for i in 0..num_nodes {

0 commit comments

Comments
 (0)