Skip to content

Commit 80f5c69

Browse files
committed
Adapt single signature so that it does not containg key and stake
1 parent f85f10d commit 80f5c69

File tree

3 files changed

+94
-72
lines changed

3 files changed

+94
-72
lines changed

mithril-stm/src/merkle_tree.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
//! Creation and verification of Merkle Trees
22
use crate::error::MerkleTreeError;
33
use crate::multi_sig::VerificationKey;
4-
use crate::stm::Stake;
5-
use blake2::digest::{Digest, FixedOutput};
4+
use crate::stm::{Stake, StmVerificationKey};
5+
use blake2::digest::{consts::U32, Digest, FixedOutput};
6+
use blake2::Blake2b;
67
use serde::{Deserialize, Serialize};
78
use std::cmp::Ordering;
89
use std::convert::TryFrom;
@@ -74,6 +75,14 @@ pub struct MerkleTree<D: Digest> {
7475
}
7576

7677
impl MTLeaf {
78+
pub(crate) fn from_bytes(bytes: &[u8]) -> Result<Self, MerkleTreeError<Blake2b<U32>>> {
79+
let pk = StmVerificationKey::from_bytes(bytes)
80+
.map_err(|_| MerkleTreeError::SerializationError)?;
81+
let mut u64_bytes = [0u8; 8];
82+
u64_bytes.copy_from_slice(&bytes[96..]);
83+
let stake = Stake::from_be_bytes(u64_bytes);
84+
Ok(MTLeaf(pk, stake))
85+
}
7786
pub(crate) fn to_bytes(self) -> [u8; 104] {
7887
let mut result = [0u8; 104];
7988
result[..96].copy_from_slice(&self.0.to_bytes());

mithril-stm/src/stm.rs

Lines changed: 73 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ use crate::dense_mapping::ev_lt_phi;
110110
use crate::error::{
111111
AggregationError, RegisterError, StmAggregateSignatureError, StmSignatureError,
112112
};
113-
use crate::key_reg::ClosedKeyReg;
113+
use crate::key_reg::{ClosedKeyReg, RegParty};
114114
use crate::merkle_tree::{BatchPath, MTLeaf, MerkleTreeCommitmentBatchCompat};
115115
use crate::multi_sig::{Signature, SigningKey, VerificationKey, VerificationKeyPoP};
116116
use blake2::digest::{Digest, FixedOutput};
@@ -169,6 +169,7 @@ pub struct StmInitializer {
169169
/// Participant in the protocol can sign messages.
170170
/// This instance can only be generated out of an `StmInitializer` and a `ClosedKeyReg`.
171171
/// This ensures that a `MerkleTree` root is not computed before all participants have registered.
172+
#[allow(dead_code)]
172173
#[derive(Debug, Clone)]
173174
pub struct StmSigner<D: Digest> {
174175
mt_index: u64,
@@ -193,10 +194,6 @@ pub struct StmClerk<D: Clone + Digest> {
193194
pub struct StmSig {
194195
/// The signature from the underlying MSP scheme.
195196
pub sigma: Signature,
196-
/// The Stm verification Key.
197-
pub pk: StmVerificationKey,
198-
/// The stake of the party that made this signature.
199-
pub stake: Stake,
200197
/// The index(es) for which the signature is valid
201198
pub indexes: Vec<Index>,
202199
/// Merkle tree index of the signer.
@@ -224,7 +221,7 @@ pub struct StmAggrVerificationKey<D: Clone + Digest + FixedOutput> {
224221
deserialize = "BatchPath<D>: Deserialize<'de>"
225222
))]
226223
pub struct StmAggrSig<D: Clone + Digest + FixedOutput> {
227-
pub(crate) signatures: Vec<StmSig>,
224+
pub(crate) signatures: Vec<(StmSig, RegParty)>,
228225
/// The list of unique merkle tree nodes that covers path for all signatures.
229226
pub batch_proof: BatchPath<D>,
230227
}
@@ -384,8 +381,6 @@ impl<D: Clone + Digest + FixedOutput> StmSigner<D> {
384381
if !indexes.is_empty() {
385382
Some(StmSig {
386383
sigma,
387-
pk: self.vk,
388-
stake: self.stake,
389384
indexes,
390385
signer_index: self.mt_index,
391386
})
@@ -436,6 +431,15 @@ impl<D: Digest + Clone + FixedOutput> StmClerk<D> {
436431
) -> Result<StmAggrSig<D>, AggregationError> {
437432
let mut unique_sigs = self.dedup_sigs_for_indices(msg, sigs)?;
438433
unique_sigs.sort_unstable();
434+
let signatures = unique_sigs
435+
.iter()
436+
.map(|sig| {
437+
(
438+
sig.clone(),
439+
self.closed_reg.reg_parties[sig.signer_index as usize],
440+
)
441+
})
442+
.collect(); // todo: look into this conversion
439443

440444
let mt_index_list = unique_sigs
441445
.iter()
@@ -445,7 +449,7 @@ impl<D: Digest + Clone + FixedOutput> StmClerk<D> {
445449
let batch_proof = self.closed_reg.merkle_tree.get_batched_path(mt_index_list);
446450

447451
Ok(StmAggrSig {
448-
signatures: unique_sigs,
452+
signatures,
449453
batch_proof,
450454
})
451455
}
@@ -466,9 +470,16 @@ impl<D: Digest + Clone + FixedOutput> StmClerk<D> {
466470
let avk = StmAggrVerificationKey::from(&self.closed_reg);
467471
let mut sig_by_index: BTreeMap<Index, &StmSig> = BTreeMap::new();
468472
let mut removal_idx_by_vk: HashMap<&StmSig, Vec<Index>> = HashMap::new();
469-
470-
for sig in sigs.iter() {
471-
if sig.verify(&self.params, &avk, msg).is_err() {
473+
let reg_parties = sigs
474+
.iter()
475+
.map(|sig| self.closed_reg.reg_parties[sig.signer_index as usize])
476+
.collect::<Vec<RegParty>>(); // todo: look into this
477+
478+
for (sig, reg_party) in sigs.iter().zip(reg_parties.iter()) {
479+
if sig
480+
.verify(&self.params, &reg_party.0, &reg_party.1, &avk, msg)
481+
.is_err()
482+
{
472483
continue;
473484
}
474485

@@ -543,12 +554,14 @@ impl StmSig {
543554
pub fn verify<D: Clone + Digest + FixedOutput>(
544555
&self,
545556
params: &StmParameters,
557+
pk: &StmVerificationKey,
558+
stake: &Stake,
546559
avk: &StmAggrVerificationKey<D>,
547560
msg: &[u8],
548561
) -> Result<(), StmSignatureError> {
549562
let msgp = avk.mt_commitment.concat_with_msg(msg);
550-
self.sigma.verify(&msgp, &self.pk)?;
551-
self.check_indices(params, &msgp, avk)?;
563+
self.sigma.verify(&msgp, pk)?;
564+
self.check_indices(params, stake, &msgp, avk)?;
552565

553566
Ok(())
554567
}
@@ -557,6 +570,7 @@ impl StmSig {
557570
pub(crate) fn check_indices<D: Clone + Digest + FixedOutput>(
558571
&self,
559572
params: &StmParameters,
573+
stake: &Stake,
560574
msgp: &[u8],
561575
avk: &StmAggrVerificationKey<D>,
562576
) -> Result<(), StmSignatureError> {
@@ -567,7 +581,7 @@ impl StmSig {
567581

568582
let ev = self.sigma.eval(msgp, index);
569583

570-
if !ev_lt_phi(params.phi_f, ev, self.stake, avk.total_stake) {
584+
if !ev_lt_phi(params.phi_f, ev, *stake, avk.total_stake) {
571585
return Err(StmSignatureError::LotteryLost);
572586
}
573587
}
@@ -586,14 +600,12 @@ impl StmSig {
586600
/// * Merkle index of the signer.
587601
pub fn to_bytes(&self) -> Vec<u8> {
588602
let mut output = Vec::new();
589-
output.extend_from_slice(&self.stake.to_be_bytes());
590603
output.extend_from_slice(&(self.indexes.len() as u64).to_be_bytes());
591604

592605
for index in &self.indexes {
593606
output.extend_from_slice(&index.to_be_bytes());
594607
}
595608

596-
output.extend_from_slice(&self.pk.to_bytes());
597609
output.extend_from_slice(&self.sigma.to_bytes());
598610

599611
output.extend_from_slice(&self.signer_index.to_be_bytes());
@@ -606,29 +618,23 @@ impl StmSig {
606618
) -> Result<StmSig, StmSignatureError> {
607619
let mut u64_bytes = [0u8; 8];
608620

609-
u64_bytes.copy_from_slice(&bytes[..8]);
610-
let stake = u64::from_be_bytes(u64_bytes);
611-
612-
u64_bytes.copy_from_slice(&bytes[8..16]);
621+
u64_bytes.copy_from_slice(&bytes[0..8]);
613622
let nr_indexes = u64::from_be_bytes(u64_bytes) as usize;
614623

615624
let mut indexes = Vec::new();
616625
for i in 0..nr_indexes {
617-
u64_bytes.copy_from_slice(&bytes[16 + i * 8..24 + i * 8]);
626+
u64_bytes.copy_from_slice(&bytes[8 + i * 8..16 + i * 8]);
618627
indexes.push(u64::from_be_bytes(u64_bytes));
619628
}
620629

621-
let offset = 16 + nr_indexes * 8;
622-
let pk = StmVerificationKey::from_bytes(&bytes[offset..offset + 96])?;
623-
let sigma = Signature::from_bytes(&bytes[offset + 96..offset + 144])?;
630+
let offset = 8 + nr_indexes * 8;
631+
let sigma = Signature::from_bytes(&bytes[offset..offset + 48])?;
624632

625-
u64_bytes.copy_from_slice(&bytes[offset + 144..offset + 152]);
633+
u64_bytes.copy_from_slice(&bytes[offset + 48..offset + 56]);
626634
let signer_index = u64::from_be_bytes(u64_bytes);
627635

628636
Ok(StmSig {
629637
sigma,
630-
pk,
631-
stake,
632638
indexes,
633639
signer_index,
634640
})
@@ -692,17 +698,16 @@ impl<D: Clone + Digest + FixedOutput> StmAggrSig<D> {
692698
let mut unique_indices = HashSet::new();
693699
let mut leaves = Vec::new();
694700

695-
for sig in &self.signatures {
701+
for (sig, reg_party) in &self.signatures {
696702
let msgp = avk.mt_commitment.concat_with_msg(msg);
697-
sig.check_indices(parameters, &msgp, avk)?;
703+
sig.check_indices(parameters, &reg_party.1, &msgp, avk)?;
698704

699705
for &index in &sig.indexes {
700706
unique_indices.insert(index);
701707
nr_indices += 1;
702708
}
703709

704-
let mt_leaf = MTLeaf(sig.pk, sig.stake);
705-
leaves.push(mt_leaf);
710+
leaves.push(*reg_party);
706711
}
707712

708713
if nr_indices != unique_indices.len() {
@@ -720,12 +725,12 @@ impl<D: Clone + Digest + FixedOutput> StmAggrSig<D> {
720725
let signatures = self
721726
.signatures
722727
.iter()
723-
.map(|sig| sig.sigma)
728+
.map(|(sig, _)| sig.sigma)
724729
.collect::<Vec<Signature>>();
725730
let vks = self
726731
.signatures
727732
.iter()
728-
.map(|sig| sig.pk)
733+
.map(|(_, reg_party)| reg_party.0)
729734
.collect::<Vec<VerificationKey>>();
730735

731736
Signature::verify_aggregate(msg.as_slice(), &vks, &signatures)?;
@@ -736,18 +741,19 @@ impl<D: Clone + Digest + FixedOutput> StmAggrSig<D> {
736741
/// # Layout
737742
/// * Number of signatures (as u64)
738743
/// * Size of a signature
739-
/// * Signatures
744+
/// * Pairs of Signatures and Registered Parties
740745
/// * Batch proof
741746
pub fn to_bytes(&self) -> Vec<u8> {
742747
let mut out = Vec::new();
743748
out.extend_from_slice(&u64::try_from(self.signatures.len()).unwrap().to_be_bytes());
744749
out.extend_from_slice(
745-
&u64::try_from(self.signatures[0].to_bytes().len())
750+
&u64::try_from(self.signatures[0].0.to_bytes().len())
746751
.unwrap()
747752
.to_be_bytes(),
748753
);
749-
for sig in &self.signatures {
750-
out.extend_from_slice(&sig.to_bytes())
754+
for (sig, reg_party) in &self.signatures {
755+
out.extend_from_slice(&sig.to_bytes());
756+
out.extend_from_slice(&reg_party.to_bytes());
751757
}
752758
let proof = &self.batch_proof;
753759
out.extend_from_slice(&proof.to_bytes());
@@ -769,12 +775,18 @@ impl<D: Clone + Digest + FixedOutput> StmAggrSig<D> {
769775

770776
let mut signatures = Vec::with_capacity(size);
771777
for i in 0..size {
772-
signatures.push(StmSig::from_bytes::<D>(
773-
&bytes[16 + i * sig_size..16 + (i + 1) * sig_size],
774-
)?);
778+
signatures.push((
779+
StmSig::from_bytes::<D>(
780+
&bytes[16 + i * (sig_size + 104)..16 + sig_size + i * (sig_size + 104)],
781+
)?,
782+
MTLeaf::from_bytes(
783+
&bytes[16 + sig_size + i * (sig_size + 104)..16 + (i + 1) * (sig_size + 104)],
784+
)
785+
.map_err(|_| StmAggregateSignatureError::SerializationError)?,
786+
));
775787
}
776788

777-
let offset = 16 + sig_size * size;
789+
let offset = 16 + (sig_size + 104) * size;
778790
let batch_proof = BatchPath::from_bytes(&bytes[offset..])?;
779791

780792
Ok(StmAggrSig {
@@ -903,28 +915,26 @@ mod tests {
903915
#[test]
904916
/// Test that `dedup_sigs_for_indices` only takes valid signatures.
905917
fn test_dedup(msg in any::<[u8; 16]>()) {
906-
let nparties = 10usize;
907918
let false_msg = [1u8; 20];
908-
let params = StmParameters { m: (nparties as u64), k: 1, phi_f: 1.0 };
909-
let ps = setup_equal_parties(params, nparties);
910-
let p = &ps[0];
911-
let clerk = StmClerk::from_signer(p);
919+
let params = StmParameters { m: 1, k: 1, phi_f: 1.0 };
920+
let ps = setup_equal_parties(params, 1);
921+
let clerk = StmClerk::from_signer(&ps[0]);
912922
let avk = clerk.compute_avk();
913-
let mut sigs = Vec::with_capacity(nparties);
923+
let mut sigs = Vec::with_capacity(2);
914924

915925

916-
if let Some(sig) = p.sign(&false_msg) {
926+
if let Some(sig) = ps[0].sign(&false_msg) {
917927
sigs.push(sig);
918928
}
919929

920-
if let Some(sig) = p.sign(&msg) {
930+
if let Some(sig) = ps[0].sign(&msg) {
921931
sigs.push(sig);
922932
}
923933

924934
let dedup_result = clerk.dedup_sigs_for_indices(&msg, &sigs);
925935
assert!(dedup_result.is_ok(), "dedup failure {:?}", dedup_result);
926936
for passed_sigs in dedup_result.unwrap() {
927-
let verify_result = passed_sigs.verify(&params, &avk, &msg);
937+
let verify_result = passed_sigs.verify(&params, &ps[0].vk, &ps[0].stake, &avk, &msg);
928938
assert!(verify_result.is_ok(), "verify {:?}", verify_result);
929939
}
930940
}
@@ -934,15 +944,13 @@ mod tests {
934944
#[test]
935945
/// Test that when a party creates a signature it can be verified
936946
fn test_sig(msg in any::<[u8;16]>()) {
937-
let nparties = 2;
938-
let params = StmParameters { m: (nparties as u64), k: 1, phi_f: 0.2 };
939-
let ps = setup_equal_parties(params, nparties);
940-
let p = &ps[0];
941-
let clerk = StmClerk::from_signer(p);
947+
let params = StmParameters { m: 1, k: 1, phi_f: 0.2 };
948+
let ps = setup_equal_parties(params, 1);
949+
let clerk = StmClerk::from_signer(&ps[0]);
942950
let avk = clerk.compute_avk();
943951

944-
if let Some(sig) = p.sign(&msg) {
945-
assert!(sig.verify(&params, &avk, &msg).is_ok());
952+
if let Some(sig) = ps[0].sign(&msg) {
953+
assert!(sig.verify(&params, &ps[0].vk, &ps[0].stake, &avk, &msg).is_ok());
946954
}
947955
}
948956
}
@@ -1005,21 +1013,19 @@ mod tests {
10051013

10061014
#[test]
10071015
fn test_sig_serialize_deserialize(msg in any::<[u8;16]>()) {
1008-
let nparties = 2;
1009-
let params = StmParameters { m: (nparties as u64), k: 1, phi_f: 0.2 };
1010-
let ps = setup_equal_parties(params, nparties);
1011-
let p = &ps[0];
1012-
let clerk = StmClerk::from_signer(p);
1016+
let params = StmParameters { m: 1, k: 1, phi_f: 0.2 };
1017+
let ps = setup_equal_parties(params, 1);
1018+
let clerk = StmClerk::from_signer(&ps[0]);
10131019
let avk = clerk.compute_avk();
10141020

1015-
if let Some(sig) = p.sign(&msg) {
1021+
if let Some(sig) = ps[0].sign(&msg) {
10161022
let bytes = sig.to_bytes();
10171023
let sig_deser = StmSig::from_bytes::<D>(&bytes).unwrap();
1018-
assert!(sig_deser.verify(&params, &avk, &msg).is_ok());
1024+
assert!(sig_deser.verify(&params, &ps[0].vk, &ps[0].stake, &avk, &msg).is_ok());
10191025

10201026
let encoded = bincode::serialize(&sig).unwrap();
10211027
let decoded: StmSig = bincode::deserialize(&encoded).unwrap();
1022-
assert!(decoded.verify(&params, &avk, &msg).is_ok());
1028+
assert!(decoded.verify(&params, &ps[0].vk, &ps[0].stake, &avk, &msg).is_ok());
10231029
}
10241030
}
10251031

@@ -1164,7 +1170,7 @@ mod tests {
11641170
fn test_invalid_proof_index_unique(tc in arb_proof_setup(10)) {
11651171
with_proof_mod(tc, |aggr, clerk, _msg| {
11661172
for sig in aggr.signatures.iter_mut() {
1167-
for index in sig.indexes.iter_mut() {
1173+
for index in sig.0.indexes.iter_mut() {
11681174
*index %= clerk.params.k - 1
11691175
}
11701176
}

0 commit comments

Comments
 (0)