mithril_stm/bls_multi_signature/
verification_key.rs1use crate::bls_multi_signature::helper::unsafe_helpers::verify_pairing;
2use crate::bls_multi_signature::proof_of_possession::ProofOfPossession;
3use crate::bls_multi_signature::signing_key::SigningKey;
4use crate::bls_multi_signature::POP;
5use crate::error::{blst_err_to_mithril, MultiSignatureError};
6use blst::min_sig::{AggregatePublicKey, PublicKey as BlstVk};
7use blst::BLST_ERROR;
8use serde::{Deserialize, Serialize};
9use std::{
10 cmp::Ordering,
11 fmt::{Display, Formatter},
12 hash::{Hash, Hasher},
13 iter::Sum,
14};
15
16#[derive(Debug, Clone, Copy, Default)]
19pub struct VerificationKey(pub BlstVk);
20
21impl VerificationKey {
22 pub fn to_bytes(self) -> [u8; 96] {
24 self.0.to_bytes()
25 }
26
27 pub fn from_bytes(bytes: &[u8]) -> Result<Self, MultiSignatureError> {
33 match BlstVk::key_validate(&bytes[..96]) {
34 Ok(vk) => Ok(Self(vk)),
35 Err(e) => Err(blst_err_to_mithril(e, None, None)
36 .expect_err("If deserialization is not successful, blst returns and error different to SUCCESS."))
37 }
38 }
39
40 fn cmp_msp_mvk(&self, other: &VerificationKey) -> Ordering {
43 let self_bytes = self.to_bytes();
44 let other_bytes = other.to_bytes();
45 let mut result = Ordering::Equal;
46
47 for (i, j) in self_bytes.iter().zip(other_bytes.iter()) {
48 result = i.cmp(j);
49 if result != Ordering::Equal {
50 return result;
51 }
52 }
53
54 result
55 }
56
57 pub(crate) fn to_blst_vk(self) -> BlstVk {
58 self.0
59 }
60}
61
62impl Display for VerificationKey {
63 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
64 write!(f, "{:?}", self.to_bytes())
65 }
66}
67
68impl Hash for VerificationKey {
69 fn hash<H: Hasher>(&self, state: &mut H) {
70 Hash::hash_slice(&self.to_bytes(), state)
71 }
72}
73
74impl PartialEq for VerificationKey {
75 fn eq(&self, other: &Self) -> bool {
76 self.0 == other.0
77 }
78}
79
80impl Eq for VerificationKey {}
81
82impl PartialOrd for VerificationKey {
83 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
84 Some(std::cmp::Ord::cmp(self, other))
85 }
86}
87
88impl Ord for VerificationKey {
89 fn cmp(&self, other: &Self) -> Ordering {
90 self.cmp_msp_mvk(other)
91 }
92}
93
94impl<'a> Sum<&'a Self> for VerificationKey {
95 fn sum<I>(iter: I) -> Self
96 where
97 I: Iterator<Item = &'a Self>,
98 {
99 let keys: Vec<&BlstVk> = iter.map(|x| &x.0).collect();
100
101 assert!(!keys.is_empty(), "One cannot add an empty vector");
102 let aggregate_key = AggregatePublicKey::aggregate(&keys, false)
103 .expect("An MspMvk is always a valid key. This function only fails if keys is empty or if the keys are invalid, none of which can happen.")
104 .to_public_key();
105
106 Self(aggregate_key)
107 }
108}
109
110impl From<&SigningKey> for VerificationKey {
111 fn from(sk: &SigningKey) -> Self {
115 VerificationKey(sk.to_blst_sk().sk_to_pk())
116 }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
121pub struct VerificationKeyPoP {
122 pub vk: VerificationKey,
124 pub pop: ProofOfPossession,
126}
127
128impl VerificationKeyPoP {
129 pub fn check(&self) -> Result<(), MultiSignatureError> {
136 match self.vk.to_blst_vk().validate() {
137 Ok(_) => {
138 let result = verify_pairing(&self.vk, &self.pop);
139 if !(self
140 .pop
141 .to_k1()
142 .verify(false, POP, &[], &[], &self.vk.to_blst_vk(), false)
143 == BLST_ERROR::BLST_SUCCESS
144 && result)
145 {
146 return Err(MultiSignatureError::KeyInvalid(Box::new(*self)));
147 }
148 Ok(())
149 }
150 Err(e) => blst_err_to_mithril(e, None, Some(self.vk)),
151 }
152 }
153
154 pub fn to_bytes(self) -> [u8; 192] {
161 let mut vkpop_bytes = [0u8; 192];
162 vkpop_bytes[..96].copy_from_slice(&self.vk.to_bytes());
163 vkpop_bytes[96..].copy_from_slice(&self.pop.to_bytes());
164 vkpop_bytes
165 }
166
167 pub fn from_bytes(bytes: &[u8]) -> Result<Self, MultiSignatureError> {
169 let mvk = VerificationKey::from_bytes(&bytes[..96])?;
170
171 let pop = ProofOfPossession::from_bytes(&bytes[96..])?;
172
173 Ok(Self { vk: mvk, pop })
174 }
175}
176
177impl From<&SigningKey> for VerificationKeyPoP {
178 fn from(sk: &SigningKey) -> Self {
181 Self {
182 vk: sk.into(),
183 pop: sk.into(),
184 }
185 }
186}