safe_nd/keys/
proof.rs

1// Copyright 2020 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
4// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
5// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
6// KIND, either express or implied. Please review the Licences for the specific language governing
7// permissions and limitations relating to use of the SAFE Network Software.
8
9use crate::{utils, PublicKey, Signature, SignatureShare};
10use serde::{Deserialize, Serialize};
11use std::{
12    fmt::{self, Debug, Formatter},
13    hash::{Hash, Hasher},
14};
15
16///
17#[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)]
18pub enum Proof {
19    ///
20    Bls(BlsProof),
21    ///
22    BlsShare(BlsProofShare),
23    ///
24    Ed25519(Ed25519Proof),
25}
26
27impl Proof {
28    ///
29    pub fn id(&self) -> PublicKey {
30        use Proof::*;
31        match self {
32            Bls(proof) => proof.id(),
33            BlsShare(proof) => proof.id(),
34            Ed25519(proof) => proof.id(),
35        }
36    }
37
38    ///
39    pub fn signature(&self) -> Signature {
40        use Proof::*;
41        match self {
42            Bls(proof) => proof.signature(),
43            BlsShare(proof) => proof.signature(),
44            Ed25519(proof) => proof.signature(),
45        }
46    }
47
48    ///
49    pub fn verify(&self, payload: &[u8]) -> bool {
50        use Proof::*;
51        match self {
52            Bls(proof) => proof.verify(payload),
53            BlsShare(proof) => proof.verify(payload),
54            Ed25519(proof) => proof.verify(payload),
55        }
56    }
57}
58
59///
60#[derive(Clone, Debug, Serialize, Deserialize)]
61pub struct Ed25519Proof {
62    /// The public key.
63    pub public_key: ed25519_dalek::PublicKey,
64    /// The signature corresponding to the public key.
65    pub signature: ed25519_dalek::Signature,
66}
67
68impl Ed25519Proof {
69    ///
70    pub fn id(&self) -> PublicKey {
71        PublicKey::Ed25519(self.public_key)
72    }
73
74    ///
75    pub fn signature(&self) -> Signature {
76        Signature::Ed25519(self.signature)
77    }
78
79    /// Verifies this proof against the payload.
80    pub fn verify(&self, payload: &[u8]) -> bool {
81        self.id().verify(&self.signature(), payload).is_ok()
82    }
83}
84
85// Need to manually implement this due to a missing impl in `Ed25519::Keypair`.
86impl PartialEq for Ed25519Proof {
87    fn eq(&self, other: &Self) -> bool {
88        // TODO: After const generics land, remove the `to_vec()` calls.
89        self.public_key.to_bytes().to_vec() == other.public_key.to_bytes().to_vec()
90            && self.signature.to_bytes().to_vec() == other.signature.to_bytes().to_vec()
91    }
92}
93
94// Need to manually implement this due to a missing impl in `Ed25519::Keypair`.
95impl Eq for Ed25519Proof {}
96
97#[allow(clippy::derive_hash_xor_eq)]
98impl Hash for Ed25519Proof {
99    fn hash<H: Hasher>(&self, state: &mut H) {
100        utils::serialise(&self).hash(state)
101    }
102}
103
104/// Proof that a quorum of the section elders has agreed on something.
105#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)]
106pub struct BlsProof {
107    /// The public key.
108    pub public_key: threshold_crypto::PublicKey,
109    /// The signature corresponding to the public key.
110    pub signature: threshold_crypto::Signature,
111}
112
113impl BlsProof {
114    /// Verifies this proof against the payload.
115    pub fn verify(&self, payload: &[u8]) -> bool {
116        self.public_key.verify(&self.signature, payload)
117    }
118
119    ///
120    pub fn id(&self) -> PublicKey {
121        PublicKey::Bls(self.public_key)
122    }
123
124    ///
125    pub fn signature(&self) -> Signature {
126        Signature::Bls(self.signature.clone())
127    }
128}
129
130/// Single share of `Proof`.
131#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
132pub struct BlsProofShare {
133    /// BLS public key set.
134    pub public_key_set: threshold_crypto::PublicKeySet,
135    /// Index of the node that created this proof share.
136    pub index: usize,
137    /// BLS signature share corresponding to the `index`-th public key share of the public key set.
138    pub signature_share: threshold_crypto::SignatureShare,
139}
140
141impl BlsProofShare {
142    /// Creates new proof share.
143    pub fn new(
144        public_key_set: threshold_crypto::PublicKeySet,
145        index: usize,
146        secret_key_share: &threshold_crypto::SecretKeyShare,
147        payload: &[u8],
148    ) -> Self {
149        Self {
150            public_key_set,
151            index,
152            signature_share: secret_key_share.sign(payload),
153        }
154    }
155
156    ///
157    pub fn id(&self) -> PublicKey {
158        PublicKey::BlsShare(self.public_key_set.public_key_share(self.index))
159    }
160
161    ///
162    pub fn signature(&self) -> Signature {
163        Signature::BlsShare(SignatureShare {
164            index: self.index,
165            share: self.signature_share.clone(),
166        })
167    }
168
169    /// Verifies this proof share against the payload.
170    pub fn verify(&self, payload: &[u8]) -> bool {
171        self.public_key_set
172            .public_key_share(self.index)
173            .verify(&self.signature_share, payload)
174    }
175}
176
177impl Debug for BlsProofShare {
178    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
179        write!(
180            formatter,
181            "ProofShare {{ public_key: {:?}, index: {}, .. }}",
182            self.public_key_set.public_key(),
183            self.index
184        )
185    }
186}
187
188/// A value together with the proof that it was agreed on by the quorum of the section elders.
189#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
190pub struct Proven<T> {
191    ///
192    pub value: T,
193    ///
194    pub proof: BlsProof,
195}
196
197impl<T> Proven<T> {
198    ///
199    pub fn new(value: T, proof: BlsProof) -> Self {
200        Self { value, proof }
201    }
202}