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 use sp_core::bytes::to_hex;
103
104 write!(f, "{}", to_hex(self.0.as_ref(), false))
105 }
106
107 #[cfg(not(feature = "std"))]
108 fn fmt(&self, _: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
109 Ok(())
110 }
111}
112
113impl IdentifyAccount for DilithiumPublic {
114 type AccountId = AccountId32;
115 fn into_account(self) -> Self::AccountId {
116 AccountId32::new(PoseidonHasher::hash(self.0.as_slice()).0)
117 }
118}
119
120pub struct WormholeAddress(pub H256);
121
122impl IdentifyAccount for WormholeAddress {
124 type AccountId = AccountId32;
125 fn into_account(self) -> Self::AccountId {
126 AccountId32::new(self.0.as_bytes().try_into().unwrap())
127 }
128}
129
130impl<const N: usize, SubTag> Derive for WrappedSignatureBytes<N, SubTag> {}
134impl<const N: usize, SubTag> AsMut<[u8]> for WrappedSignatureBytes<N, SubTag> {
135 fn as_mut(&mut self) -> &mut [u8] {
136 self.0.as_mut()
137 }
138}
139impl<const N: usize, SubTag> AsRef<[u8]> for WrappedSignatureBytes<N, SubTag> {
140 fn as_ref(&self) -> &[u8] {
141 self.0.as_slice()
142 }
143}
144impl<const N: usize, SubTag> TryFrom<&[u8]> for WrappedSignatureBytes<N, SubTag> {
145 type Error = ();
146 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
147 SignatureBytes::from_slice(data)
148 .map(|bytes| WrappedSignatureBytes(bytes))
149 .map_err(|_| ())
150 }
151}
152impl<const N: usize, SubTag> ByteArray for WrappedSignatureBytes<N, SubTag> {
153 fn as_slice(&self) -> &[u8] {
154 self.0.as_slice()
155 }
156 const LEN: usize = N;
157 fn from_slice(data: &[u8]) -> Result<Self, ()> {
158 SignatureBytes::from_slice(data)
159 .map(|bytes| WrappedSignatureBytes(bytes))
160 .map_err(|_| ())
161 }
162 fn to_raw_vec(&self) -> Vec<u8> {
163 self.0.as_slice().to_vec()
164 }
165}
166impl<const N: usize, SubTag> CryptoType for WrappedSignatureBytes<N, SubTag> {
167 type Pair = DilithiumPair;
168}
169impl<const N: usize, SubTag: Clone + Eq> Signature for WrappedSignatureBytes<N, SubTag> {}
170
171impl<const N: usize, SubTag> Default for WrappedSignatureBytes<N, SubTag> {
172 fn default() -> Self {
173 WrappedSignatureBytes(SignatureBytes::default())
174 }
175}
176
177impl<const N: usize, SubTag> alloc::fmt::Debug for WrappedSignatureBytes<N, SubTag> {
178 #[cfg(feature = "std")]
179 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
180 use sp_core::bytes::to_hex;
181
182 write!(f, "{}", to_hex(self.0.as_slice(), false))
183 }
184
185 #[cfg(not(feature = "std"))]
186 fn fmt(&self, _: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
187 Ok(())
188 }
189}
190
191impl CryptoType for DilithiumPair {
196 type Pair = Self;
197}
198
199impl Verify for DilithiumSignatureScheme {
204 type Signer = DilithiumSigner;
205
206 fn verify<L: sp_runtime::traits::Lazy<[u8]>>(
207 &self,
208 mut msg: L,
209 signer: &<Self::Signer as IdentifyAccount>::AccountId,
210 ) -> bool {
211 let Self::Dilithium(sig_public) = self;
212 let account = sig_public.public().clone().into_account();
213 if account != *signer {
214 return false;
215 }
216 let result =
217 verify(sig_public.public().as_ref(), msg.get(), sig_public.signature().as_ref());
218 result
219 }
220}
221
222impl From<DilithiumPublic> for DilithiumSigner {
226 fn from(x: DilithiumPublic) -> Self {
227 Self::Dilithium(x)
228 }
229}
230
231impl IdentifyAccount for DilithiumSigner {
232 type AccountId = AccountId32;
233
234 fn into_account(self) -> AccountId32 {
235 let Self::Dilithium(who) = self;
236 PoseidonHasher::hash(who.as_ref()).0.into()
237 }
238}
239
240impl From<DilithiumPublic> for AccountId32 {
241 fn from(public: DilithiumPublic) -> Self {
242 public.into_account()
243 }
244}
245
246impl DilithiumPair {
251 pub fn from_seed(seed: &[u8]) -> Result<Self, Error> {
252 let keypair = crate::pair::generate(seed)?;
253 Ok(DilithiumPair { secret: keypair.secret.to_bytes(), public: keypair.public.to_bytes() })
254 }
255 pub fn public(&self) -> DilithiumPublic {
256 DilithiumPublic::from_slice(&self.public).expect("Valid public key bytes")
257 }
258}
259
260impl alloc::fmt::Debug for DilithiumSignatureWithPublic {
261 #[cfg(feature = "std")]
262 fn fmt(&self, f: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
263 write!(
264 f,
265 "ResonanceSignatureWithPublic {{ signature: {:?}, public: {:?} }}",
266 self.signature(),
267 self.public()
268 )
269 }
270
271 #[cfg(not(feature = "std"))]
272 fn fmt(&self, f: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
273 write!(f, "ResonanceSignatureWithPublic")
274 }
275}
276
277impl From<DilithiumSignatureWithPublic> for DilithiumSignatureScheme {
278 fn from(x: DilithiumSignatureWithPublic) -> Self {
279 Self::Dilithium(x)
280 }
281}
282
283impl TryFrom<DilithiumSignatureScheme> for DilithiumSignatureWithPublic {
284 type Error = ();
285 fn try_from(m: DilithiumSignatureScheme) -> Result<Self, Self::Error> {
286 let DilithiumSignatureScheme::Dilithium(sig_with_public) = m;
287 Ok(sig_with_public)
288 }
289}
290
291impl AsMut<[u8]> for DilithiumSignatureWithPublic {
292 fn as_mut(&mut self) -> &mut [u8] {
293 self.bytes.as_mut()
294 }
295}
296impl TryFrom<&[u8]> for DilithiumSignatureWithPublic {
297 type Error = ();
298 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
299 if data.len() != Self::TOTAL_LEN {
300 return Err(());
301 }
302 let (sig_bytes, pub_bytes) = data.split_at(<DilithiumSignature as ByteArray>::LEN);
303 let signature = DilithiumSignature::from_slice(sig_bytes).map_err(|_| ())?;
304 let public = DilithiumPublic::from_slice(pub_bytes).map_err(|_| ())?;
305 Ok(Self::new(signature, public))
306 }
307}
308
309impl ByteArray for DilithiumSignatureWithPublic {
310 const LEN: usize = Self::TOTAL_LEN;
311
312 fn to_raw_vec(&self) -> Vec<u8> {
313 self.to_bytes().to_vec()
314 }
315
316 fn from_slice(data: &[u8]) -> Result<Self, ()> {
317 if data.len() != Self::LEN {
318 return Err(());
319 }
320 let bytes = <[u8; Self::LEN]>::try_from(data).map_err(|_| ())?;
321 Self::from_bytes(&bytes).map_err(|_| ())
322 }
323
324 fn as_slice(&self) -> &[u8] {
325 self.bytes.as_slice()
326 }
327}
328impl AsRef<[u8; Self::LEN]> for DilithiumSignatureWithPublic {
329 fn as_ref(&self) -> &[u8; Self::LEN] {
330 &self.bytes
331 }
332}
333
334impl AsRef<[u8]> for DilithiumSignatureWithPublic {
335 fn as_ref(&self) -> &[u8] {
336 &self.bytes
337 }
338}
339impl Signature for DilithiumSignatureWithPublic {}
340
341impl CryptoType for DilithiumSignatureWithPublic {
342 type Pair = DilithiumPair;
343}