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