1use std::convert::TryFrom;
3
4use digest::{typenum::Unsigned as _, Digest as _};
5use rand_core::{CryptoRng, RngCore};
6use thiserror::Error;
7
8use crate::core::common::crypto::signature::{PublicKey as CorePublicKey, Signer as CoreSigner};
9
10pub mod context;
11mod digests;
12pub mod ed25519;
13pub mod secp256k1;
14pub mod secp256r1;
15pub mod secp384r1;
16pub mod sr25519;
17
18#[allow(non_camel_case_types)]
20#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, cbor::Encode, cbor::Decode)]
21pub enum SignatureType {
22 #[cbor(rename = "ed25519_oasis")]
23 Ed25519_Oasis,
24 #[cbor(rename = "ed25519_pure")]
25 Ed25519_Pure,
26 #[cbor(rename = "ed25519_prehashed_sha512")]
27 Ed25519_PrehashedSha512,
28 #[cbor(rename = "secp256k1_oasis")]
29 Secp256k1_Oasis,
30 #[cbor(rename = "secp256k1_prehashed_keccak256")]
31 Secp256k1_PrehashedKeccak256,
32 #[cbor(rename = "secp256k1_prehashed_sha256")]
33 Secp256k1_PrehashedSha256,
34 #[cbor(rename = "sr25519_pure")]
35 Sr25519_Pure,
36 #[cbor(rename = "secp256r1_prehashed_sha256")]
37 Secp256r1_PrehashedSha256,
38 #[cbor(rename = "secp384r1_prehashed_sha384")]
39 Secp384r1_PrehashedSha384,
40}
41
42impl SignatureType {
43 pub fn as_int(&self) -> u8 {
44 match self {
45 Self::Ed25519_Oasis => 0,
46 Self::Ed25519_Pure => 1,
47 Self::Ed25519_PrehashedSha512 => 2,
48 Self::Secp256k1_Oasis => 3,
49 Self::Secp256k1_PrehashedKeccak256 => 4,
50 Self::Secp256k1_PrehashedSha256 => 5,
51 Self::Sr25519_Pure => 6,
52 Self::Secp256r1_PrehashedSha256 => 7,
53 Self::Secp384r1_PrehashedSha384 => 8,
54 }
55 }
56
57 pub fn is_prehashed(&self) -> bool {
58 matches!(
59 self,
60 Self::Ed25519_PrehashedSha512
61 | Self::Secp256k1_PrehashedKeccak256
62 | Self::Secp256k1_PrehashedSha256
63 | Self::Secp256r1_PrehashedSha256
64 | Self::Secp384r1_PrehashedSha384
65 )
66 }
67
68 pub fn is_ed25519_variant(&self) -> bool {
69 matches!(
70 self,
71 Self::Ed25519_Oasis | Self::Ed25519_Pure | Self::Ed25519_PrehashedSha512
72 )
73 }
74
75 pub fn is_secp256k1_variant(&self) -> bool {
76 matches!(
77 self,
78 Self::Secp256k1_Oasis
79 | Self::Secp256k1_PrehashedKeccak256
80 | Self::Secp256k1_PrehashedSha256
81 )
82 }
83
84 pub fn is_secp256r1_variant(&self) -> bool {
85 matches!(self, Self::Secp256r1_PrehashedSha256)
86 }
87
88 pub fn is_secp384r1_variant(&self) -> bool {
89 matches!(self, Self::Secp384r1_PrehashedSha384)
90 }
91
92 pub fn is_sr25519_variant(&self) -> bool {
93 matches!(self, Self::Sr25519_Pure)
94 }
95}
96
97impl TryFrom<u8> for SignatureType {
98 type Error = Error;
99
100 fn try_from(value: u8) -> Result<Self, Self::Error> {
101 match value {
102 0 => Ok(Self::Ed25519_Oasis),
103 1 => Ok(Self::Ed25519_Pure),
104 2 => Ok(Self::Ed25519_PrehashedSha512),
105 3 => Ok(Self::Secp256k1_Oasis),
106 4 => Ok(Self::Secp256k1_PrehashedKeccak256),
107 5 => Ok(Self::Secp256k1_PrehashedSha256),
108 6 => Ok(Self::Sr25519_Pure),
109 7 => Ok(Self::Secp256r1_PrehashedSha256),
110 8 => Ok(Self::Secp384r1_PrehashedSha384),
111 _ => Err(Error::InvalidArgument),
112 }
113 }
114}
115
116#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, cbor::Encode, cbor::Decode)]
118pub enum PublicKey {
119 #[cbor(rename = "ed25519")]
120 Ed25519(ed25519::PublicKey),
121
122 #[cbor(rename = "secp256k1")]
123 Secp256k1(secp256k1::PublicKey),
124
125 #[cbor(rename = "secp256r1")]
126 Secp256r1(secp256r1::PublicKey),
127
128 #[cbor(rename = "secp384r1")]
129 Secp384r1(secp384r1::PublicKey),
130
131 #[cbor(rename = "sr25519")]
132 Sr25519(sr25519::PublicKey),
133}
134
135#[derive(Error, Debug)]
137pub enum Error {
138 #[error("malformed public key")]
139 MalformedPublicKey,
140 #[error("malformed private key")]
141 MalformedPrivateKey,
142 #[error("malformed signature")]
143 MalformedSignature,
144 #[error("signature verification failed")]
145 VerificationFailed,
146 #[error("invalid argument")]
147 InvalidArgument,
148 #[error("invalid digest length")]
149 InvalidDigestLength,
150 #[error("other signing error")]
151 SigningError,
152}
153
154impl PublicKey {
155 pub fn key_type(&self) -> &str {
157 match self {
158 Self::Ed25519(_) => "ed25519",
159 Self::Secp256k1(_) => "secp256k1",
160 Self::Secp256r1(_) => "secp256r1",
161 Self::Secp384r1(_) => "secp384r1",
162 Self::Sr25519(_) => "sr25519",
163 }
164 }
165
166 pub fn as_bytes(&self) -> &[u8] {
168 match self {
169 PublicKey::Ed25519(pk) => pk.as_bytes(),
170 PublicKey::Secp256k1(pk) => pk.as_bytes(),
171 PublicKey::Secp256r1(pk) => pk.as_bytes(),
172 PublicKey::Secp384r1(pk) => pk.as_bytes(),
173 PublicKey::Sr25519(pk) => pk.as_bytes(),
174 }
175 }
176
177 pub fn from_bytes(sig_type: SignatureType, bytes: &[u8]) -> Result<Self, Error> {
179 match sig_type {
180 SignatureType::Ed25519_Oasis
181 | SignatureType::Ed25519_Pure
182 | SignatureType::Ed25519_PrehashedSha512 => {
183 Ok(Self::Ed25519(ed25519::PublicKey::from_bytes(bytes)?))
184 }
185 SignatureType::Secp256k1_Oasis
186 | SignatureType::Secp256k1_PrehashedKeccak256
187 | SignatureType::Secp256k1_PrehashedSha256 => {
188 Ok(Self::Secp256k1(secp256k1::PublicKey::from_bytes(bytes)?))
189 }
190 SignatureType::Secp256r1_PrehashedSha256 => {
191 Ok(Self::Secp256r1(secp256r1::PublicKey::from_bytes(bytes)?))
192 }
193 SignatureType::Secp384r1_PrehashedSha384 => {
194 Ok(Self::Secp384r1(secp384r1::PublicKey::from_bytes(bytes)?))
195 }
196 SignatureType::Sr25519_Pure => {
197 Ok(Self::Sr25519(sr25519::PublicKey::from_bytes(bytes)?))
198 }
199 }
200 }
201
202 pub fn verify(
204 &self,
205 context: &[u8],
206 message: &[u8],
207 signature: &Signature,
208 ) -> Result<(), Error> {
209 match self {
210 PublicKey::Ed25519(pk) => pk.verify(context, message, signature),
211 PublicKey::Secp256k1(pk) => pk.verify(context, message, signature),
212 PublicKey::Secp256r1(pk) => pk.verify(context, message, signature),
213 PublicKey::Secp384r1(pk) => pk.verify(context, message, signature),
214 PublicKey::Sr25519(pk) => pk.verify(context, message, signature),
215 }
216 }
217
218 pub fn verify_raw(&self, message: &[u8], signature: &Signature) -> Result<(), Error> {
221 match self {
222 PublicKey::Ed25519(pk) => pk.verify_raw(message, signature),
223 PublicKey::Secp256k1(pk) => pk.verify_raw(message, signature),
224 PublicKey::Secp256r1(pk) => pk.verify_raw(message, signature),
225 PublicKey::Secp384r1(pk) => pk.verify_raw(message, signature),
226 PublicKey::Sr25519(_) => Err(Error::InvalidArgument),
227 }
228 }
229
230 pub fn verify_by_type(
232 &self,
233 signature_type: SignatureType,
234 context_or_hash: &[u8],
235 message: &[u8],
236 signature: &Signature,
237 ) -> Result<(), Error> {
238 match self {
239 Self::Ed25519(pk) => match signature_type {
240 SignatureType::Ed25519_Oasis => pk.verify(context_or_hash, message, signature),
241 SignatureType::Ed25519_Pure => pk.verify_raw(message, signature),
242 SignatureType::Ed25519_PrehashedSha512 => {
243 if context_or_hash.len()
244 != <sha2::Sha512 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
245 {
246 return Err(Error::InvalidArgument);
247 }
248 let digest =
249 digests::DummyDigest::<sha2::Sha512>::new_precomputed(context_or_hash);
250 pk.verify_digest(digest, signature)
251 }
252 _ => Err(Error::InvalidArgument),
253 },
254 Self::Secp256k1(pk) => match signature_type {
255 SignatureType::Secp256k1_Oasis => pk.verify(context_or_hash, message, signature),
256 SignatureType::Secp256k1_PrehashedKeccak256 => {
257 if context_or_hash.len()
258 != <sha3::Keccak256 as sha3::digest::OutputSizeUser>::OutputSize::USIZE
259 {
260 return Err(Error::InvalidArgument);
261 }
262 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
264 context_or_hash,
265 );
266 pk.verify_digest(digest, signature)
267 }
268 SignatureType::Secp256k1_PrehashedSha256 => {
269 if context_or_hash.len()
270 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
271 {
272 return Err(Error::InvalidArgument);
273 }
274 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
275 context_or_hash,
276 );
277 pk.verify_digest(digest, signature)
278 }
279 _ => Err(Error::InvalidArgument),
280 },
281 Self::Secp256r1(pk) => match signature_type {
282 SignatureType::Secp256r1_PrehashedSha256 => {
283 if context_or_hash.len()
284 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
285 {
286 return Err(Error::InvalidArgument);
287 }
288 let digest =
289 digests::DummyDigest::<sha2::Sha256>::new_precomputed(context_or_hash);
290 pk.verify_digest(digest, signature)
291 }
292 _ => Err(Error::InvalidArgument),
293 },
294 Self::Secp384r1(pk) => match signature_type {
295 SignatureType::Secp384r1_PrehashedSha384 => {
296 if context_or_hash.len()
297 != <sha2::Sha384 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
298 {
299 return Err(Error::InvalidArgument);
300 }
301 let digest =
302 digests::DummyDigest::<sha2::Sha384>::new_precomputed(context_or_hash);
303 pk.verify_digest(digest, signature)
304 }
305 _ => Err(Error::InvalidArgument),
306 },
307 Self::Sr25519(pk) => match signature_type {
308 SignatureType::Sr25519_Pure => pk.verify_raw(context_or_hash, message, signature),
309 _ => Err(Error::InvalidArgument),
310 },
311 }
312 }
313
314 pub fn verify_batch_multisig(
316 context: &[u8],
317 message: &[u8],
318 public_keys: &[PublicKey],
319 signatures: &[Signature],
320 ) -> Result<(), Error> {
321 if public_keys.len() != signatures.len() {
322 return Err(Error::InvalidArgument);
323 }
324
325 for (pk, sig) in public_keys.iter().zip(signatures.iter()) {
327 pk.verify(context, message, sig)?;
328 }
329 Ok(())
330 }
331}
332
333impl AsRef<[u8]> for PublicKey {
334 fn as_ref(&self) -> &[u8] {
335 self.as_bytes()
336 }
337}
338
339impl PartialEq<CorePublicKey> for PublicKey {
340 fn eq(&self, other: &CorePublicKey) -> bool {
341 match self {
342 PublicKey::Ed25519(pk) => pk.as_bytes() == other.as_ref(),
343 _ => false,
344 }
345 }
346}
347
348impl TryFrom<PublicKey> for CorePublicKey {
349 type Error = &'static str;
350
351 fn try_from(pk: PublicKey) -> Result<Self, Self::Error> {
352 match pk {
353 PublicKey::Ed25519(pk) => Ok(pk.into()),
354 _ => Err("not an Ed25519 public key"),
355 }
356 }
357}
358
359impl From<CorePublicKey> for PublicKey {
360 fn from(pk: CorePublicKey) -> Self {
361 Self::Ed25519(pk.into())
362 }
363}
364
365#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
367#[cbor(transparent)]
368pub struct Signature(Vec<u8>);
369
370impl AsRef<[u8]> for Signature {
371 fn as_ref(&self) -> &[u8] {
372 &self.0
373 }
374}
375
376impl From<Vec<u8>> for Signature {
377 fn from(v: Vec<u8>) -> Signature {
378 Signature(v)
379 }
380}
381
382impl From<Signature> for Vec<u8> {
383 fn from(s: Signature) -> Vec<u8> {
384 s.0
385 }
386}
387
388pub trait Signer: Send + Sync {
390 fn random(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
392 where
393 Self: Sized;
394
395 fn new_from_seed(seed: &[u8]) -> Result<Self, Error>
397 where
398 Self: Sized;
399
400 fn from_bytes(bytes: &[u8]) -> Result<Self, Error>
402 where
403 Self: Sized;
404
405 fn to_bytes(&self) -> Vec<u8>;
407
408 fn public_key(&self) -> PublicKey;
410
411 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error>;
413
414 fn sign_raw(&self, message: &[u8]) -> Result<Signature, Error>;
416}
417
418impl<T: Signer + ?Sized> Signer for std::sync::Arc<T> {
419 fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
420 where
421 Self: Sized,
422 {
423 Err(Error::InvalidArgument)
424 }
425
426 fn new_from_seed(_seed: &[u8]) -> Result<Self, Error>
427 where
428 Self: Sized,
429 {
430 Err(Error::InvalidArgument)
431 }
432
433 fn from_bytes(_bytes: &[u8]) -> Result<Self, Error>
434 where
435 Self: Sized,
436 {
437 Err(Error::InvalidArgument)
438 }
439
440 fn to_bytes(&self) -> Vec<u8> {
441 T::to_bytes(self)
442 }
443
444 fn public_key(&self) -> PublicKey {
445 T::public_key(self)
446 }
447
448 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
449 T::sign(self, context, message)
450 }
451
452 fn sign_raw(&self, message: &[u8]) -> Result<Signature, Error> {
453 T::sign_raw(self, message)
454 }
455}
456
457impl<T: CoreSigner> Signer for &T {
458 fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
459 where
460 Self: Sized,
461 {
462 Err(Error::InvalidArgument)
463 }
464
465 fn new_from_seed(_seed: &[u8]) -> Result<Self, Error>
466 where
467 Self: Sized,
468 {
469 Err(Error::InvalidArgument)
470 }
471
472 fn from_bytes(_bytes: &[u8]) -> Result<Self, Error>
473 where
474 Self: Sized,
475 {
476 Err(Error::InvalidArgument)
477 }
478
479 fn to_bytes(&self) -> Vec<u8> {
480 vec![]
481 }
482
483 fn public_key(&self) -> PublicKey {
484 PublicKey::Ed25519(self.public().into())
485 }
486
487 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
488 let raw_sig = CoreSigner::sign(*self, context, message).map_err(|_| Error::SigningError)?;
489 Ok(Signature(raw_sig.as_ref().into()))
490 }
491
492 fn sign_raw(&self, _message: &[u8]) -> Result<Signature, Error> {
493 Err(Error::InvalidArgument)
494 }
495}
496
497impl Signer for crate::core::identity::Identity {
498 fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
499 where
500 Self: Sized,
501 {
502 Err(Error::InvalidArgument)
503 }
504
505 fn new_from_seed(_seed: &[u8]) -> Result<Self, Error>
506 where
507 Self: Sized,
508 {
509 Err(Error::InvalidArgument)
510 }
511
512 fn from_bytes(_bytes: &[u8]) -> Result<Self, Error>
513 where
514 Self: Sized,
515 {
516 Err(Error::InvalidArgument)
517 }
518
519 fn to_bytes(&self) -> Vec<u8> {
520 vec![]
521 }
522
523 fn public_key(&self) -> PublicKey {
524 PublicKey::Ed25519(self.public().into())
525 }
526
527 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
528 let raw_sig = CoreSigner::sign(self, context, message).map_err(|_| Error::SigningError)?;
529 Ok(Signature(raw_sig.as_ref().into()))
530 }
531
532 fn sign_raw(&self, _message: &[u8]) -> Result<Signature, Error> {
533 Err(Error::InvalidArgument)
534 }
535}
536
537pub enum MemorySigner {
539 Ed25519(ed25519::MemorySigner),
540 Secp256k1(secp256k1::MemorySigner),
541 Secp256r1(secp256r1::MemorySigner),
542 Secp384r1(secp384r1::MemorySigner),
543 Sr25519(sr25519::MemorySigner),
544}
545
546impl MemorySigner {
547 pub fn new_from_seed(sig_type: SignatureType, seed: &[u8]) -> Result<Self, Error> {
549 if sig_type.is_ed25519_variant() {
550 Ok(Self::Ed25519(ed25519::MemorySigner::new_from_seed(seed)?))
551 } else if sig_type.is_secp256k1_variant() {
552 Ok(Self::Secp256k1(secp256k1::MemorySigner::new_from_seed(
553 seed,
554 )?))
555 } else if sig_type.is_secp256r1_variant() {
556 Ok(Self::Secp256r1(secp256r1::MemorySigner::new_from_seed(
557 seed,
558 )?))
559 } else if sig_type.is_secp384r1_variant() {
560 Ok(Self::Secp384r1(secp384r1::MemorySigner::new_from_seed(
561 seed,
562 )?))
563 } else if sig_type.is_sr25519_variant() {
564 Ok(Self::Sr25519(sr25519::MemorySigner::new_from_seed(seed)?))
565 } else {
566 Err(Error::InvalidArgument)
567 }
568 }
569
570 pub fn new_test(sig_type: SignatureType, name: &str) -> Self {
572 if sig_type.is_secp384r1_variant() {
573 Self::new_from_seed(sig_type, &sha2::Sha384::digest(name)).unwrap()
574 } else {
575 Self::new_from_seed(sig_type, &sha2::Sha512_256::digest(name)).unwrap()
576 }
577 }
578
579 pub fn from_bytes(sig_type: SignatureType, bytes: &[u8]) -> Result<Self, Error> {
581 if sig_type.is_ed25519_variant() {
582 Ok(Self::Ed25519(ed25519::MemorySigner::from_bytes(bytes)?))
583 } else if sig_type.is_secp256k1_variant() {
584 Ok(Self::Secp256k1(secp256k1::MemorySigner::from_bytes(bytes)?))
585 } else if sig_type.is_secp256r1_variant() {
586 Ok(Self::Secp256r1(secp256r1::MemorySigner::from_bytes(bytes)?))
587 } else if sig_type.is_secp384r1_variant() {
588 Ok(Self::Secp384r1(secp384r1::MemorySigner::from_bytes(bytes)?))
589 } else if sig_type.is_sr25519_variant() {
590 Ok(Self::Sr25519(sr25519::MemorySigner::from_bytes(bytes)?))
591 } else {
592 Err(Error::InvalidArgument)
593 }
594 }
595
596 pub fn to_bytes(&self) -> Vec<u8> {
598 match self {
599 Self::Ed25519(signer) => signer.to_bytes(),
600 Self::Secp256k1(signer) => signer.to_bytes(),
601 Self::Secp256r1(signer) => signer.to_bytes(),
602 Self::Secp384r1(signer) => signer.to_bytes(),
603 Self::Sr25519(signer) => signer.to_bytes(),
604 }
605 }
606
607 pub fn public_key(&self) -> PublicKey {
609 match self {
610 Self::Ed25519(signer) => signer.public_key(),
611 Self::Secp256k1(signer) => signer.public_key(),
612 Self::Secp256r1(signer) => signer.public_key(),
613 Self::Secp384r1(signer) => signer.public_key(),
614 Self::Sr25519(signer) => signer.public_key(),
615 }
616 }
617
618 pub fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
620 match self {
621 Self::Ed25519(signer) => signer.sign(context, message),
622 Self::Secp256k1(signer) => signer.sign(context, message),
623 Self::Secp256r1(signer) => signer.sign(context, message),
624 Self::Secp384r1(signer) => signer.sign(context, message),
625 Self::Sr25519(signer) => signer.sign(context, message),
626 }
627 }
628
629 pub fn sign_raw(&self, message: &[u8]) -> Result<Signature, Error> {
631 match self {
632 Self::Ed25519(signer) => signer.sign_raw(message),
633 Self::Secp256k1(signer) => signer.sign_raw(message),
634 Self::Secp256r1(signer) => signer.sign_raw(message),
635 Self::Secp384r1(signer) => signer.sign_raw(message),
636 Self::Sr25519(signer) => signer.sign_raw(message),
637 }
638 }
639
640 pub fn sign_by_type(
642 &self,
643 signature_type: SignatureType,
644 context_or_hash: &[u8],
645 message: &[u8],
646 ) -> Result<Signature, Error> {
647 match self {
648 Self::Ed25519(signer) => match signature_type {
649 SignatureType::Ed25519_Oasis => signer.sign(context_or_hash, message),
650 SignatureType::Ed25519_Pure => signer.sign_raw(message),
651 SignatureType::Ed25519_PrehashedSha512 => {
652 if context_or_hash.len()
653 != <sha2::Sha512 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
654 {
655 return Err(Error::InvalidArgument);
656 }
657 let digest =
658 digests::DummyDigest::<sha2::Sha512>::new_precomputed(context_or_hash);
659 signer.sign_digest(digest)
660 }
661 _ => Err(Error::InvalidArgument),
662 },
663 Self::Secp256k1(signer) => match signature_type {
664 SignatureType::Secp256k1_Oasis => signer.sign(context_or_hash, message),
665 SignatureType::Secp256k1_PrehashedKeccak256 => {
666 if context_or_hash.len()
667 != <sha3::Keccak256 as sha3::digest::OutputSizeUser>::OutputSize::USIZE
668 {
669 return Err(Error::InvalidArgument);
670 }
671 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
673 context_or_hash,
674 );
675 signer.sign_digest(digest)
676 }
677 SignatureType::Secp256k1_PrehashedSha256 => {
678 if context_or_hash.len()
679 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
680 {
681 return Err(Error::InvalidArgument);
682 }
683 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
684 context_or_hash,
685 );
686 signer.sign_digest(digest)
687 }
688 _ => Err(Error::InvalidArgument),
689 },
690 Self::Secp256r1(signer) => match signature_type {
691 SignatureType::Secp256r1_PrehashedSha256 => {
692 if context_or_hash.len()
693 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
694 {
695 return Err(Error::InvalidArgument);
696 }
697 let digest =
698 digests::DummyDigest::<sha2::Sha256>::new_precomputed(context_or_hash);
699 signer.sign_digest(digest)
700 }
701 _ => Err(Error::InvalidArgument),
702 },
703 Self::Secp384r1(signer) => match signature_type {
704 SignatureType::Secp384r1_PrehashedSha384 => {
705 if context_or_hash.len()
706 != <sha2::Sha384 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
707 {
708 return Err(Error::InvalidArgument);
709 }
710 let digest =
711 digests::DummyDigest::<sha2::Sha384>::new_precomputed(context_or_hash);
712 signer.sign_digest(digest)
713 }
714 _ => Err(Error::InvalidArgument),
715 },
716 Self::Sr25519(signer) => match signature_type {
717 SignatureType::Sr25519_Pure => signer.sign(context_or_hash, message),
718 _ => Err(Error::InvalidArgument),
719 },
720 }
721 }
722}
723
724#[cfg(test)]
725mod test {
726 use super::*;
727
728 #[test]
729 fn test_signature_conversion() {
730 let raw = vec![0x00, 0x01, 0x02, 0x03];
731 let sig = Signature::from(raw.clone());
732 let v: Vec<u8> = sig.clone().into();
733 assert_eq!(v, raw);
734
735 let vref: &[u8] = v.as_ref();
736 assert_eq!(vref, sig.as_ref());
737 }
738
739 #[test]
740 fn test_memory_signer() {
741 let ctx = b"oasis-core/test: context";
742 let corrupt_ctx = b"oasis-core/test: wrong context";
743 let message = b"this is a message";
744 let corrupt_message = b"this isn't a message";
745
746 for sig_type in [
747 SignatureType::Ed25519_Oasis,
748 SignatureType::Ed25519_Pure,
749 SignatureType::Secp256k1_Oasis,
750 SignatureType::Sr25519_Pure,
751 ] {
752 let signer = MemorySigner::new_test(sig_type, "memory signer test");
753 let pk = signer.public_key();
754
755 let signature = signer
756 .sign_by_type(sig_type, ctx, message)
757 .expect("signing should succeed");
758
759 pk.verify_by_type(sig_type, ctx, message, &signature)
760 .expect("signature should verify");
761 pk.verify_by_type(sig_type, ctx, corrupt_message, &signature)
762 .expect_err("signature should fail verification");
763 if matches!(sig_type, SignatureType::Ed25519_Oasis)
764 || matches!(sig_type, SignatureType::Secp256k1_Oasis)
765 {
766 pk.verify_by_type(sig_type, corrupt_ctx, message, &signature)
767 .expect_err("signature should fail verification");
768 pk.verify_by_type(sig_type, corrupt_ctx, corrupt_message, &signature)
769 .expect_err("signature should fail verification");
770 }
771 }
772 }
773
774 #[test]
775 fn test_memory_signer_prehashed() {
776 let message = b"this is a message";
777 let corrupt_message = b"this isn't a message";
778
779 let sig_types: &[(SignatureType, Box<dyn Fn(&[u8]) -> Vec<u8>>)] = &[
780 (
781 SignatureType::Ed25519_PrehashedSha512,
782 Box::new(|message| sha2::Sha512::digest(message).to_vec()),
783 ),
784 (
785 SignatureType::Secp256k1_PrehashedKeccak256,
786 Box::new(|message| sha3::Keccak256::digest(message).to_vec()),
787 ),
788 (
789 SignatureType::Secp256k1_PrehashedSha256,
790 Box::new(|message| sha2::Sha256::digest(message).to_vec()),
791 ),
792 (
793 SignatureType::Secp256r1_PrehashedSha256,
794 Box::new(|message| sha2::Sha256::digest(message).to_vec()),
795 ),
796 (
797 SignatureType::Secp384r1_PrehashedSha384,
798 Box::new(|message| sha2::Sha384::digest(message).to_vec()),
799 ),
800 ];
801
802 for (sig_type, hasher) in sig_types {
803 let hash = hasher(message);
804 let corrupt_hash = hasher(corrupt_message);
805
806 let signer = MemorySigner::new_test(*sig_type, "memory signer test");
807 let pk = signer.public_key();
808
809 let signature = signer
810 .sign_by_type(*sig_type, &hash, b"")
811 .expect("signing should succeed");
812 pk.verify_by_type(*sig_type, &hash, b"", &signature)
813 .expect("signature should verify");
814 pk.verify_by_type(*sig_type, &corrupt_hash, b"", &signature)
815 .expect_err("corrupt hash shouldn't verify");
816 }
817 }
818}