mithril_stm/bls_multi_signature/
verification_key.rs1use std::{
2 cmp::Ordering,
3 fmt::{Display, Formatter},
4 hash::{Hash, Hasher},
5 iter::Sum,
6};
7
8use blst::{
9 BLST_ERROR,
10 min_sig::{AggregatePublicKey, PublicKey as BlstVk},
11};
12use serde::{Deserialize, Serialize};
13
14use crate::bls_multi_signature::{
15 BlsProofOfPossession, BlsSigningKey, POP, helper::unsafe_helpers::verify_pairing,
16};
17use crate::error::{MultiSignatureError, blst_err_to_mithril};
18
19#[derive(Debug, Clone, Copy, Default)]
22pub struct BlsVerificationKey(pub BlstVk);
23
24impl BlsVerificationKey {
25 pub fn to_bytes(self) -> [u8; 96] {
27 self.0.to_bytes()
28 }
29
30 pub fn from_bytes(bytes: &[u8]) -> Result<Self, MultiSignatureError> {
36 let bytes = bytes.get(..96).ok_or(MultiSignatureError::SerializationError)?;
37 match BlstVk::key_validate(bytes) {
38 Ok(vk) => Ok(Self(vk)),
39 Err(e) => Err(blst_err_to_mithril(e, None, None)
40 .expect_err("If deserialization is not successful, blst returns and error different to SUCCESS."))
41 }
42 }
43
44 fn compare_verification_keys(&self, other: &BlsVerificationKey) -> Ordering {
47 let self_bytes = self.to_bytes();
48 let other_bytes = other.to_bytes();
49 let mut result = Ordering::Equal;
50
51 for (i, j) in self_bytes.iter().zip(other_bytes.iter()) {
52 result = i.cmp(j);
53 if result != Ordering::Equal {
54 return result;
55 }
56 }
57
58 result
59 }
60
61 pub(crate) fn to_blst_verification_key(self) -> BlstVk {
62 self.0
63 }
64}
65
66impl Display for BlsVerificationKey {
67 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68 write!(f, "{:?}", self.to_bytes())
69 }
70}
71
72impl Hash for BlsVerificationKey {
73 fn hash<H: Hasher>(&self, state: &mut H) {
74 Hash::hash_slice(&self.to_bytes(), state)
75 }
76}
77
78impl PartialEq for BlsVerificationKey {
79 fn eq(&self, other: &Self) -> bool {
80 self.0 == other.0
81 }
82}
83
84impl Eq for BlsVerificationKey {}
85
86impl PartialOrd for BlsVerificationKey {
87 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
88 Some(std::cmp::Ord::cmp(self, other))
89 }
90}
91
92impl Ord for BlsVerificationKey {
93 fn cmp(&self, other: &Self) -> Ordering {
94 self.compare_verification_keys(other)
95 }
96}
97
98impl<'a> Sum<&'a Self> for BlsVerificationKey {
99 fn sum<I>(iter: I) -> Self
100 where
101 I: Iterator<Item = &'a Self>,
102 {
103 let keys: Vec<&BlstVk> = iter.map(|x| &x.0).collect();
104
105 assert!(!keys.is_empty(), "One cannot add an empty vector");
106 let aggregate_key = AggregatePublicKey::aggregate(&keys, false)
107 .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.")
108 .to_public_key();
109
110 Self(aggregate_key)
111 }
112}
113
114impl From<&BlsSigningKey> for BlsVerificationKey {
115 fn from(sk: &BlsSigningKey) -> Self {
119 BlsVerificationKey(sk.to_blst_secret_key().sk_to_pk())
120 }
121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
125pub struct BlsVerificationKeyProofOfPossession {
126 pub vk: BlsVerificationKey,
128 pub pop: BlsProofOfPossession,
130}
131
132impl BlsVerificationKeyProofOfPossession {
133 pub(crate) fn verify_proof_of_possesion(&self) -> Result<(), MultiSignatureError> {
140 match self.vk.to_blst_verification_key().validate() {
141 Ok(_) => {
142 let result = verify_pairing(&self.vk, &self.pop);
143 if !(self.pop.get_k1().verify(
144 false,
145 POP,
146 &[],
147 &[],
148 &self.vk.to_blst_verification_key(),
149 false,
150 ) == BLST_ERROR::BLST_SUCCESS
151 && result)
152 {
153 return Err(MultiSignatureError::KeyInvalid(Box::new(*self)));
154 }
155 Ok(())
156 }
157 Err(e) => blst_err_to_mithril(e, None, Some(self.vk)),
158 }
159 }
160
161 #[deprecated(since = "0.4.9", note = "Use `verify_proof_of_possesion` instead")]
168 pub fn check(&self) -> Result<(), MultiSignatureError> {
169 Self::verify_proof_of_possesion(self)
170 }
171
172 pub fn to_bytes(self) -> [u8; 192] {
179 let mut vkpop_bytes = [0u8; 192];
180 vkpop_bytes[..96].copy_from_slice(&self.vk.to_bytes());
181 vkpop_bytes[96..].copy_from_slice(&self.pop.to_bytes());
182 vkpop_bytes
183 }
184
185 pub fn from_bytes(bytes: &[u8]) -> Result<Self, MultiSignatureError> {
187 let mvk = BlsVerificationKey::from_bytes(
188 bytes.get(..96).ok_or(MultiSignatureError::SerializationError)?,
189 )?;
190
191 let pop = BlsProofOfPossession::from_bytes(
192 bytes.get(96..).ok_or(MultiSignatureError::SerializationError)?,
193 )?;
194
195 Ok(Self { vk: mvk, pop })
196 }
197}
198
199impl From<&BlsSigningKey> for BlsVerificationKeyProofOfPossession {
200 fn from(sk: &BlsSigningKey) -> Self {
203 Self {
204 vk: sk.into(),
205 pop: sk.into(),
206 }
207 }
208}