1use super::types::{
2 DilithiumPair, DilithiumPublic, DilithiumSignatureScheme, DilithiumSigner, Error,
3 WrappedPublicBytes, WrappedSignatureBytes,
4};
5
6use crate::{DilithiumSignature, DilithiumSignatureWithPublic};
7use alloc::vec::Vec;
8use qp_poseidon::PoseidonHasher;
9use sp_core::{
10 crypto::{Derive, Public, PublicBytes, Signature, SignatureBytes},
11 ByteArray, Hasher, H256,
12};
13use sp_runtime::{
14 traits::{IdentifyAccount, Verify},
15 AccountId32, CryptoType,
16};
17
18pub fn verify(pub_key: &[u8], msg: &[u8], sig: &[u8]) -> bool {
42 use qp_rusty_crystals_dilithium::ml_dsa_87::PublicKey;
43 match PublicKey::from_bytes(pub_key) {
44 Ok(pk) => pk.verify(msg, sig, None),
45 Err(e) => {
46 log::warn!("public key failed to deserialize {:?}", e);
47 false
48 },
49 }
50}
51
52impl<const N: usize, SubTag> Derive for WrappedPublicBytes<N, SubTag> {}
57impl<const N: usize, SubTag> AsMut<[u8]> for WrappedPublicBytes<N, SubTag> {
58 fn as_mut(&mut self) -> &mut [u8] {
59 self.0.as_mut()
60 }
61}
62impl<const N: usize, SubTag> AsRef<[u8]> for WrappedPublicBytes<N, SubTag> {
63 fn as_ref(&self) -> &[u8] {
64 self.0.as_slice()
65 }
66}
67impl<const N: usize, SubTag> TryFrom<&[u8]> for WrappedPublicBytes<N, SubTag> {
68 type Error = ();
69 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
70 PublicBytes::from_slice(data)
71 .map(|bytes| WrappedPublicBytes(bytes))
72 .map_err(|_| ())
73 }
74}
75impl<const N: usize, SubTag> ByteArray for WrappedPublicBytes<N, SubTag> {
76 fn as_slice(&self) -> &[u8] {
77 self.0.as_slice()
78 }
79 const LEN: usize = N;
80 fn from_slice(data: &[u8]) -> Result<Self, ()> {
81 PublicBytes::from_slice(data)
82 .map(|bytes| WrappedPublicBytes(bytes))
83 .map_err(|_| ())
84 }
85 fn to_raw_vec(&self) -> Vec<u8> {
86 self.0.as_slice().to_vec()
87 }
88}
89impl<const N: usize, SubTag> CryptoType for WrappedPublicBytes<N, SubTag> {
90 type Pair = DilithiumPair;
91}
92impl<const N: usize, SubTag: Clone + Eq> Public for WrappedPublicBytes<N, SubTag> {}
93
94impl<const N: usize, SubTag> Default for WrappedPublicBytes<N, SubTag> {
95 fn default() -> Self {
96 WrappedPublicBytes(PublicBytes::default())
97 }
98}
99impl<const N: usize, SubTag> alloc::fmt::Debug for WrappedPublicBytes<N, SubTag> {
100 #[cfg(feature = "std")]
101 fn fmt(&self, f: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
102 write!(f, "{}", sp_core::hexdisplay::HexDisplay::from(&self.0.as_ref()))
103 }
104
105 #[cfg(not(feature = "std"))]
106 fn fmt(&self, _: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
107 Ok(())
108 }
109}
110
111impl IdentifyAccount for DilithiumPublic {
112 type AccountId = AccountId32;
113 fn into_account(self) -> Self::AccountId {
114 AccountId32::new(PoseidonHasher::hash(self.0.as_slice()).0)
115 }
116}
117
118pub struct WormholeAddress(pub H256);
119
120impl IdentifyAccount for WormholeAddress {
122 type AccountId = AccountId32;
123 fn into_account(self) -> Self::AccountId {
124 AccountId32::new(self.0.as_bytes().try_into().unwrap())
125 }
126}
127
128impl<const N: usize, SubTag> Derive for WrappedSignatureBytes<N, SubTag> {}
132impl<const N: usize, SubTag> AsMut<[u8]> for WrappedSignatureBytes<N, SubTag> {
133 fn as_mut(&mut self) -> &mut [u8] {
134 self.0.as_mut()
135 }
136}
137impl<const N: usize, SubTag> AsRef<[u8]> for WrappedSignatureBytes<N, SubTag> {
138 fn as_ref(&self) -> &[u8] {
139 self.0.as_slice()
140 }
141}
142impl<const N: usize, SubTag> TryFrom<&[u8]> for WrappedSignatureBytes<N, SubTag> {
143 type Error = ();
144 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
145 SignatureBytes::from_slice(data)
146 .map(|bytes| WrappedSignatureBytes(bytes))
147 .map_err(|_| ())
148 }
149}
150impl<const N: usize, SubTag> ByteArray for WrappedSignatureBytes<N, SubTag> {
151 fn as_slice(&self) -> &[u8] {
152 self.0.as_slice()
153 }
154 const LEN: usize = N;
155 fn from_slice(data: &[u8]) -> Result<Self, ()> {
156 SignatureBytes::from_slice(data)
157 .map(|bytes| WrappedSignatureBytes(bytes))
158 .map_err(|_| ())
159 }
160 fn to_raw_vec(&self) -> Vec<u8> {
161 self.0.as_slice().to_vec()
162 }
163}
164impl<const N: usize, SubTag> CryptoType for WrappedSignatureBytes<N, SubTag> {
165 type Pair = DilithiumPair;
166}
167impl<const N: usize, SubTag: Clone + Eq> Signature for WrappedSignatureBytes<N, SubTag> {}
168
169impl<const N: usize, SubTag> Default for WrappedSignatureBytes<N, SubTag> {
170 fn default() -> Self {
171 WrappedSignatureBytes(SignatureBytes::default())
172 }
173}
174
175impl<const N: usize, SubTag> alloc::fmt::Debug for WrappedSignatureBytes<N, SubTag> {
176 #[cfg(feature = "std")]
177 fn fmt(&self, f: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
178 write!(f, "{}", sp_core::hexdisplay::HexDisplay::from(&self.0.as_ref()))
179 }
180
181 #[cfg(not(feature = "std"))]
182 fn fmt(&self, _: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
183 Ok(())
184 }
185}
186
187impl CryptoType for DilithiumPair {
192 type Pair = Self;
193}
194
195impl Verify for DilithiumSignatureScheme {
200 type Signer = DilithiumSigner;
201
202 fn verify<L: sp_runtime::traits::Lazy<[u8]>>(
203 &self,
204 mut msg: L,
205 signer: &<Self::Signer as IdentifyAccount>::AccountId,
206 ) -> bool {
207 let Self::Dilithium(sig_public) = self;
208 let account = sig_public.public().clone().into_account();
209 if account != *signer {
210 return false;
211 }
212 let result =
213 verify(sig_public.public().as_ref(), msg.get(), sig_public.signature().as_ref());
214 result
215 }
216}
217
218impl From<DilithiumPublic> for DilithiumSigner {
222 fn from(x: DilithiumPublic) -> Self {
223 Self::Dilithium(x)
224 }
225}
226
227impl IdentifyAccount for DilithiumSigner {
228 type AccountId = AccountId32;
229
230 fn into_account(self) -> AccountId32 {
231 let Self::Dilithium(who) = self;
232 PoseidonHasher::hash(who.as_ref()).0.into()
233 }
234}
235
236impl From<DilithiumPublic> for AccountId32 {
237 fn from(public: DilithiumPublic) -> Self {
238 public.into_account()
239 }
240}
241
242impl DilithiumPair {
247 pub fn from_seed(seed: &[u8]) -> Result<Self, Error> {
248 let keypair = crate::pair::generate(Some(seed))?;
249 Ok(DilithiumPair { secret: keypair.secret.to_bytes(), public: keypair.public.to_bytes() })
250 }
251 pub fn public(&self) -> DilithiumPublic {
252 DilithiumPublic::from_slice(&self.public).expect("Valid public key bytes")
253 }
254}
255
256impl alloc::fmt::Debug for DilithiumSignatureWithPublic {
257 #[cfg(feature = "std")]
258 fn fmt(&self, f: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
259 write!(
260 f,
261 "ResonanceSignatureWithPublic {{ signature: {:?}, public: {:?} }}",
262 self.signature(),
263 self.public()
264 )
265 }
266
267 #[cfg(not(feature = "std"))]
268 fn fmt(&self, f: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
269 write!(f, "ResonanceSignatureWithPublic")
270 }
271}
272
273impl From<DilithiumSignatureWithPublic> for DilithiumSignatureScheme {
274 fn from(x: DilithiumSignatureWithPublic) -> Self {
275 Self::Dilithium(x)
276 }
277}
278
279impl TryFrom<DilithiumSignatureScheme> for DilithiumSignatureWithPublic {
280 type Error = ();
281 fn try_from(m: DilithiumSignatureScheme) -> Result<Self, Self::Error> {
282 let DilithiumSignatureScheme::Dilithium(sig_with_public) = m;
283 Ok(sig_with_public)
284 }
285}
286
287impl AsMut<[u8]> for DilithiumSignatureWithPublic {
288 fn as_mut(&mut self) -> &mut [u8] {
289 self.bytes.as_mut()
290 }
291}
292impl TryFrom<&[u8]> for DilithiumSignatureWithPublic {
293 type Error = ();
294 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
295 if data.len() != Self::TOTAL_LEN {
296 return Err(());
297 }
298 let (sig_bytes, pub_bytes) = data.split_at(<DilithiumSignature as ByteArray>::LEN);
299 let signature = DilithiumSignature::from_slice(sig_bytes).map_err(|_| ())?;
300 let public = DilithiumPublic::from_slice(pub_bytes).map_err(|_| ())?;
301 Ok(Self::new(signature, public))
302 }
303}
304
305impl ByteArray for DilithiumSignatureWithPublic {
306 const LEN: usize = Self::TOTAL_LEN;
307
308 fn to_raw_vec(&self) -> Vec<u8> {
309 self.to_bytes().to_vec()
310 }
311
312 fn from_slice(data: &[u8]) -> Result<Self, ()> {
313 if data.len() != Self::LEN {
314 return Err(());
315 }
316 let bytes = <[u8; Self::LEN]>::try_from(data).map_err(|_| ())?;
317 Self::from_bytes(&bytes).map_err(|_| ())
318 }
319
320 fn as_slice(&self) -> &[u8] {
321 self.bytes.as_slice()
322 }
323}
324impl AsRef<[u8; Self::LEN]> for DilithiumSignatureWithPublic {
325 fn as_ref(&self) -> &[u8; Self::LEN] {
326 &self.bytes
327 }
328}
329
330impl AsRef<[u8]> for DilithiumSignatureWithPublic {
331 fn as_ref(&self) -> &[u8] {
332 &self.bytes
333 }
334}
335impl Signature for DilithiumSignatureWithPublic {}
336
337impl CryptoType for DilithiumSignatureWithPublic {
338 type Pair = DilithiumPair;
339}