Skip to content

Commit 4035163

Browse files
committed
module single signature - stmsig
1 parent 52fff48 commit 4035163

File tree

5 files changed

+178
-154
lines changed

5 files changed

+178
-154
lines changed

mithril-stm/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod error;
77
mod key_reg;
88
mod merkle_tree;
99
mod participant;
10+
mod single_signature;
1011
mod stm;
1112

1213
pub use error::{
@@ -15,9 +16,10 @@ pub use error::{
1516
};
1617
pub use key_reg::{ClosedKeyReg, KeyReg};
1718
pub use participant::{StmInitializer, StmSigner, StmVerificationKey, StmVerificationKeyPoP};
19+
pub use single_signature::StmSig;
1820
pub use stm::{
1921
CoreVerifier, Index, Stake, StmAggrSig, StmAggrVerificationKey, StmClerk, StmParameters,
20-
StmSig, StmSigRegParty,
22+
StmSigRegParty,
2123
};
2224

2325
#[cfg(feature = "benchmark-internals")]

mithril-stm/src/participant/signer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::bls_multi_signature::{Signature, SigningKey, VerificationKey};
22
use crate::eligibility_check::ev_lt_phi;
33
use crate::key_reg::ClosedKeyReg;
4-
use crate::stm::{Stake, StmParameters, StmSig};
4+
use crate::single_signature::StmSig;
5+
use crate::stm::{Stake, StmParameters};
56
use blake2::digest::{Digest, FixedOutput};
67

78
/// Wrapper of the MultiSignature Verification key
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mod signature;
2+
3+
pub use crate::single_signature::signature::StmSig;
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
use crate::bls_multi_signature::Signature;
2+
use crate::eligibility_check::ev_lt_phi;
3+
use crate::{
4+
Index, Stake, StmAggrVerificationKey, StmParameters, StmSignatureError, StmVerificationKey,
5+
};
6+
use blake2::digest::{Digest, FixedOutput};
7+
use serde::{Deserialize, Serialize};
8+
use std::cmp::Ordering;
9+
use std::hash::{Hash, Hasher};
10+
11+
/// Signature created by a single party who has won the lottery.
12+
#[derive(Debug, Clone, Serialize, Deserialize)]
13+
pub struct StmSig {
14+
/// The signature from the underlying MSP scheme.
15+
pub sigma: Signature,
16+
/// The index(es) for which the signature is valid
17+
pub indexes: Vec<Index>,
18+
/// Merkle tree index of the signer.
19+
pub signer_index: Index,
20+
}
21+
22+
impl StmSig {
23+
/// Verify an stm signature by checking that the lottery was won, the merkle path is correct,
24+
/// the indexes are in the desired range and the underlying multi signature validates.
25+
pub fn verify<D: Clone + Digest + FixedOutput>(
26+
&self,
27+
params: &StmParameters,
28+
pk: &StmVerificationKey,
29+
stake: &Stake,
30+
avk: &StmAggrVerificationKey<D>,
31+
msg: &[u8],
32+
) -> Result<(), StmSignatureError> {
33+
let msgp = avk.get_mt_commitment().concat_with_msg(msg);
34+
self.verify_core(params, pk, stake, &msgp, &avk.get_total_stake())?;
35+
Ok(())
36+
}
37+
38+
/// Verify that all indices of a signature are valid.
39+
pub(crate) fn check_indices(
40+
&self,
41+
params: &StmParameters,
42+
stake: &Stake,
43+
msg: &[u8],
44+
total_stake: &Stake,
45+
) -> Result<(), StmSignatureError> {
46+
for &index in &self.indexes {
47+
if index > params.m {
48+
return Err(StmSignatureError::IndexBoundFailed(index, params.m));
49+
}
50+
51+
let ev = self.sigma.eval(msg, index);
52+
53+
if !ev_lt_phi(params.phi_f, ev, *stake, *total_stake) {
54+
return Err(StmSignatureError::LotteryLost);
55+
}
56+
}
57+
58+
Ok(())
59+
}
60+
61+
/// Convert an `StmSig` into bytes
62+
///
63+
/// # Layout
64+
/// * Stake
65+
/// * Number of valid indexes (as u64)
66+
/// * Indexes of the signature
67+
/// * Public Key
68+
/// * Signature
69+
/// * Merkle index of the signer.
70+
pub fn to_bytes(&self) -> Vec<u8> {
71+
let mut output = Vec::new();
72+
output.extend_from_slice(&(self.indexes.len() as u64).to_be_bytes());
73+
74+
for index in &self.indexes {
75+
output.extend_from_slice(&index.to_be_bytes());
76+
}
77+
78+
output.extend_from_slice(&self.sigma.to_bytes());
79+
80+
output.extend_from_slice(&self.signer_index.to_be_bytes());
81+
output
82+
}
83+
84+
/// Extract a batch compatible `StmSig` from a byte slice.
85+
pub fn from_bytes<D: Clone + Digest + FixedOutput>(
86+
bytes: &[u8],
87+
) -> Result<StmSig, StmSignatureError> {
88+
let mut u64_bytes = [0u8; 8];
89+
90+
u64_bytes.copy_from_slice(&bytes[0..8]);
91+
let nr_indexes = u64::from_be_bytes(u64_bytes) as usize;
92+
93+
let mut indexes = Vec::new();
94+
for i in 0..nr_indexes {
95+
u64_bytes.copy_from_slice(&bytes[8 + i * 8..16 + i * 8]);
96+
indexes.push(u64::from_be_bytes(u64_bytes));
97+
}
98+
99+
let offset = 8 + nr_indexes * 8;
100+
let sigma = Signature::from_bytes(&bytes[offset..offset + 48])?;
101+
102+
u64_bytes.copy_from_slice(&bytes[offset + 48..offset + 56]);
103+
let signer_index = u64::from_be_bytes(u64_bytes);
104+
105+
Ok(StmSig {
106+
sigma,
107+
indexes,
108+
signer_index,
109+
})
110+
}
111+
112+
/// Compare two `StmSig` by their signers' merkle tree indexes.
113+
pub fn cmp_stm_sig(&self, other: &Self) -> Ordering {
114+
self.signer_index.cmp(&other.signer_index)
115+
}
116+
117+
/// Verify a core signature by checking that the lottery was won,
118+
/// the indexes are in the desired range and the underlying multi signature validates.
119+
pub fn verify_core(
120+
&self,
121+
params: &StmParameters,
122+
pk: &StmVerificationKey,
123+
stake: &Stake,
124+
msg: &[u8],
125+
total_stake: &Stake,
126+
) -> Result<(), StmSignatureError> {
127+
self.sigma.verify(msg, pk)?;
128+
self.check_indices(params, stake, msg, total_stake)?;
129+
130+
Ok(())
131+
}
132+
}
133+
134+
impl Hash for StmSig {
135+
fn hash<H: Hasher>(&self, state: &mut H) {
136+
Hash::hash_slice(&self.sigma.to_bytes(), state)
137+
}
138+
}
139+
140+
impl PartialEq for StmSig {
141+
fn eq(&self, other: &Self) -> bool {
142+
self.sigma == other.sigma
143+
}
144+
}
145+
146+
impl Eq for StmSig {}
147+
148+
impl PartialOrd for StmSig {
149+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
150+
Some(std::cmp::Ord::cmp(self, other))
151+
}
152+
}
153+
154+
impl Ord for StmSig {
155+
fn cmp(&self, other: &Self) -> Ordering {
156+
self.cmp_stm_sig(other)
157+
}
158+
}

mithril-stm/src/stm.rs

Lines changed: 12 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -106,21 +106,20 @@
106106
//! ```
107107
108108
use crate::bls_multi_signature::{Signature, VerificationKey};
109-
use crate::eligibility_check::ev_lt_phi;
110109
use crate::error::{
111110
AggregationError, CoreVerifierError, RegisterError, StmAggregateSignatureError,
112111
StmSignatureError,
113112
};
114113
use crate::key_reg::{ClosedKeyReg, RegParty};
115114
use crate::merkle_tree::{BatchPath, MTLeaf, MerkleTreeCommitmentBatchCompat};
116115
use crate::participant::{StmSigner, StmVerificationKey};
116+
use crate::single_signature::StmSig;
117117
use blake2::digest::{Digest, FixedOutput};
118118
use serde::ser::SerializeTuple;
119119
use serde::{Deserialize, Serialize, Serializer};
120-
use std::cmp::Ordering;
121120
use std::collections::{BTreeMap, HashMap, HashSet};
122121
use std::convert::{From, TryFrom, TryInto};
123-
use std::hash::{Hash, Hasher};
122+
use std::hash::Hash;
124123

125124
/// The quantity of stake held by a party, represented as a `u64`.
126125
pub type Stake = u64;
@@ -192,6 +191,16 @@ pub struct StmAggrVerificationKey<D: Clone + Digest + FixedOutput> {
192191
total_stake: Stake,
193192
}
194193

194+
impl<D: Digest + Clone + FixedOutput> StmAggrVerificationKey<D> {
195+
pub fn get_mt_commitment(&self) -> MerkleTreeCommitmentBatchCompat<D> {
196+
self.mt_commitment.clone()
197+
}
198+
199+
pub fn get_total_stake(&self) -> Stake {
200+
self.total_stake
201+
}
202+
}
203+
195204
impl<D: Digest + Clone + FixedOutput> PartialEq for StmAggrVerificationKey<D> {
196205
fn eq(&self, other: &Self) -> bool {
197206
self.mt_commitment == other.mt_commitment && self.total_stake == other.total_stake
@@ -209,155 +218,6 @@ impl<D: Clone + Digest + FixedOutput> From<&ClosedKeyReg<D>> for StmAggrVerifica
209218
}
210219
}
211220

212-
/// Signature created by a single party who has won the lottery.
213-
#[derive(Debug, Clone, Serialize, Deserialize)]
214-
pub struct StmSig {
215-
/// The signature from the underlying MSP scheme.
216-
pub sigma: Signature,
217-
/// The index(es) for which the signature is valid
218-
pub indexes: Vec<Index>,
219-
/// Merkle tree index of the signer.
220-
pub signer_index: Index,
221-
}
222-
223-
impl StmSig {
224-
/// Verify an stm signature by checking that the lottery was won, the merkle path is correct,
225-
/// the indexes are in the desired range and the underlying multi signature validates.
226-
pub fn verify<D: Clone + Digest + FixedOutput>(
227-
&self,
228-
params: &StmParameters,
229-
pk: &StmVerificationKey,
230-
stake: &Stake,
231-
avk: &StmAggrVerificationKey<D>,
232-
msg: &[u8],
233-
) -> Result<(), StmSignatureError> {
234-
let msgp = avk.mt_commitment.concat_with_msg(msg);
235-
self.verify_core(params, pk, stake, &msgp, &avk.total_stake)?;
236-
Ok(())
237-
}
238-
239-
/// Verify that all indices of a signature are valid.
240-
pub(crate) fn check_indices(
241-
&self,
242-
params: &StmParameters,
243-
stake: &Stake,
244-
msg: &[u8],
245-
total_stake: &Stake,
246-
) -> Result<(), StmSignatureError> {
247-
for &index in &self.indexes {
248-
if index > params.m {
249-
return Err(StmSignatureError::IndexBoundFailed(index, params.m));
250-
}
251-
252-
let ev = self.sigma.eval(msg, index);
253-
254-
if !ev_lt_phi(params.phi_f, ev, *stake, *total_stake) {
255-
return Err(StmSignatureError::LotteryLost);
256-
}
257-
}
258-
259-
Ok(())
260-
}
261-
262-
/// Convert an `StmSig` into bytes
263-
///
264-
/// # Layout
265-
/// * Stake
266-
/// * Number of valid indexes (as u64)
267-
/// * Indexes of the signature
268-
/// * Public Key
269-
/// * Signature
270-
/// * Merkle index of the signer.
271-
pub fn to_bytes(&self) -> Vec<u8> {
272-
let mut output = Vec::new();
273-
output.extend_from_slice(&(self.indexes.len() as u64).to_be_bytes());
274-
275-
for index in &self.indexes {
276-
output.extend_from_slice(&index.to_be_bytes());
277-
}
278-
279-
output.extend_from_slice(&self.sigma.to_bytes());
280-
281-
output.extend_from_slice(&self.signer_index.to_be_bytes());
282-
output
283-
}
284-
285-
/// Extract a batch compatible `StmSig` from a byte slice.
286-
pub fn from_bytes<D: Clone + Digest + FixedOutput>(
287-
bytes: &[u8],
288-
) -> Result<StmSig, StmSignatureError> {
289-
let mut u64_bytes = [0u8; 8];
290-
291-
u64_bytes.copy_from_slice(&bytes[0..8]);
292-
let nr_indexes = u64::from_be_bytes(u64_bytes) as usize;
293-
294-
let mut indexes = Vec::new();
295-
for i in 0..nr_indexes {
296-
u64_bytes.copy_from_slice(&bytes[8 + i * 8..16 + i * 8]);
297-
indexes.push(u64::from_be_bytes(u64_bytes));
298-
}
299-
300-
let offset = 8 + nr_indexes * 8;
301-
let sigma = Signature::from_bytes(&bytes[offset..offset + 48])?;
302-
303-
u64_bytes.copy_from_slice(&bytes[offset + 48..offset + 56]);
304-
let signer_index = u64::from_be_bytes(u64_bytes);
305-
306-
Ok(StmSig {
307-
sigma,
308-
indexes,
309-
signer_index,
310-
})
311-
}
312-
313-
/// Compare two `StmSig` by their signers' merkle tree indexes.
314-
pub fn cmp_stm_sig(&self, other: &Self) -> Ordering {
315-
self.signer_index.cmp(&other.signer_index)
316-
}
317-
318-
/// Verify a core signature by checking that the lottery was won,
319-
/// the indexes are in the desired range and the underlying multi signature validates.
320-
pub fn verify_core(
321-
&self,
322-
params: &StmParameters,
323-
pk: &StmVerificationKey,
324-
stake: &Stake,
325-
msg: &[u8],
326-
total_stake: &Stake,
327-
) -> Result<(), StmSignatureError> {
328-
self.sigma.verify(msg, pk)?;
329-
self.check_indices(params, stake, msg, total_stake)?;
330-
331-
Ok(())
332-
}
333-
}
334-
335-
impl Hash for StmSig {
336-
fn hash<H: Hasher>(&self, state: &mut H) {
337-
Hash::hash_slice(&self.sigma.to_bytes(), state)
338-
}
339-
}
340-
341-
impl PartialEq for StmSig {
342-
fn eq(&self, other: &Self) -> bool {
343-
self.sigma == other.sigma
344-
}
345-
}
346-
347-
impl Eq for StmSig {}
348-
349-
impl PartialOrd for StmSig {
350-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
351-
Some(std::cmp::Ord::cmp(self, other))
352-
}
353-
}
354-
355-
impl Ord for StmSig {
356-
fn cmp(&self, other: &Self) -> Ordering {
357-
self.cmp_stm_sig(other)
358-
}
359-
}
360-
361221
/// Signature with its registered party.
362222
#[derive(Debug, Clone, Hash, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
363223
pub struct StmSigRegParty {

0 commit comments

Comments
 (0)