1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use lamport_sigs::{PrivateKey, PublicKey};
use merkle::{Hashable, MerkleTree, Proof};
use ring::digest::{Algorithm, Context};
use std::io;
use std::io::{Error, ErrorKind};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MerklePublicKey {
pub key: PublicKey,
}
impl MerklePublicKey {
pub fn new(pk: PublicKey) -> MerklePublicKey {
MerklePublicKey { key: pk }
}
}
impl Hashable for MerklePublicKey {
fn update_context(&self, context: &mut Context) {
context.update(&self.key.to_bytes());
}
}
impl Into<Vec<u8>> for MerklePublicKey {
fn into(self) -> Vec<u8> {
self.key.to_bytes()
}
}
pub type MerkleSignature = (Vec<Vec<u8>>, Proof<MerklePublicKey>);
pub type MerkleSignedData<T> = (Vec<T>, MerkleSignature);
fn signing_error(reason: &str) -> Error {
Error::new(
ErrorKind::Other,
format!("A signature could not be produced because {}", reason),
)
}
pub fn sign_data_vec<T>(
data: &[T],
algorithm: &'static Algorithm,
) -> io::Result<Vec<MerkleSignature>>
where
T: AsRef<[u8]>,
{
let mut leaf_keys = (0..data.len())
.map(|_| PrivateKey::new(algorithm))
.collect::<Vec<_>>();
debug_assert!(data.len() == leaf_keys.len());
let leaf_pub_keys = leaf_keys
.iter()
.map(|priv_key| priv_key.public_key())
.collect::<Vec<_>>();
let wrapped_leafs = leaf_pub_keys
.clone()
.into_iter()
.map(MerklePublicKey::new)
.collect::<Vec<_>>();
let tree = MerkleTree::from_vec(algorithm, wrapped_leafs);
let proofs_opt = leaf_pub_keys
.into_iter()
.map(|pub_key| tree.gen_proof(MerklePublicKey::new(pub_key)))
.collect::<Option<Vec<_>>>();
let signatures_opt = leaf_keys
.iter_mut()
.zip(data.iter())
.map(|(priv_key, data)| priv_key.sign(data.as_ref()))
.collect::<Result<Vec<_>, _>>();
match (signatures_opt, proofs_opt) {
(_, None) => Err(signing_error(
"an issue occured while generating the inclusion proofs.",
)),
(Err(err), _) => Err(signing_error(&format!(
"an issue occured while signing the data: {}",
err
))),
(Ok(signatures), Some(proofs)) => Ok(signatures.into_iter().zip(proofs).collect()),
}
}
fn verif_error(reason: &str) -> Error {
Error::new(ErrorKind::Other, reason)
}
pub fn verify_data_vec_signature<T>(
data: T,
signature: &MerkleSignature,
root_hash: &[u8],
) -> io::Result<()>
where
T: Into<Vec<u8>>,
{
let (ref sig, ref proof) = *signature;
let valid_root = proof.validate(root_hash);
let data_vec = data.into();
let valid_sig = proof.value.key.verify_signature(sig, data_vec.as_slice());
if !valid_root {
return Err(verif_error("The inclusion proof failed to validate."));
}
if !valid_sig {
return Err(verif_error("The signature could not be properly verified."));
}
Ok(())
}