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::{
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("other signing error")]
153 SigningError,
154}
155
156impl PublicKey {
157 pub fn key_type(&self) -> &str {
159 match self {
160 Self::Ed25519(_) => "ed25519",
161 Self::Secp256k1(_) => "secp256k1",
162 Self::Secp256r1(_) => "secp256r1",
163 Self::Secp384r1(_) => "secp384r1",
164 Self::Sr25519(_) => "sr25519",
165 }
166 }
167
168 pub fn as_bytes(&self) -> &[u8] {
170 match self {
171 PublicKey::Ed25519(pk) => pk.as_bytes(),
172 PublicKey::Secp256k1(pk) => pk.as_bytes(),
173 PublicKey::Secp256r1(pk) => pk.as_bytes(),
174 PublicKey::Secp384r1(pk) => pk.as_bytes(),
175 PublicKey::Sr25519(pk) => pk.as_bytes(),
176 }
177 }
178
179 pub fn from_bytes(sig_type: SignatureType, bytes: &[u8]) -> Result<Self, Error> {
181 match sig_type {
182 SignatureType::Ed25519_Oasis
183 | SignatureType::Ed25519_Pure
184 | SignatureType::Ed25519_PrehashedSha512 => {
185 Ok(Self::Ed25519(ed25519::PublicKey::from_bytes(bytes)?))
186 }
187 SignatureType::Secp256k1_Oasis
188 | SignatureType::Secp256k1_PrehashedKeccak256
189 | SignatureType::Secp256k1_PrehashedSha256 => {
190 Ok(Self::Secp256k1(secp256k1::PublicKey::from_bytes(bytes)?))
191 }
192 SignatureType::Secp256r1_PrehashedSha256 => {
193 Ok(Self::Secp256r1(secp256r1::PublicKey::from_bytes(bytes)?))
194 }
195 SignatureType::Secp384r1_PrehashedSha384 => {
196 Ok(Self::Secp384r1(secp384r1::PublicKey::from_bytes(bytes)?))
197 }
198 SignatureType::Sr25519_Pure => {
199 Ok(Self::Sr25519(sr25519::PublicKey::from_bytes(bytes)?))
200 }
201 }
202 }
203
204 pub fn verify(
206 &self,
207 context: &[u8],
208 message: &[u8],
209 signature: &Signature,
210 ) -> Result<(), Error> {
211 match self {
212 PublicKey::Ed25519(pk) => pk.verify(context, message, signature),
213 PublicKey::Secp256k1(pk) => pk.verify(context, message, signature),
214 PublicKey::Secp256r1(pk) => pk.verify(context, message, signature),
215 PublicKey::Secp384r1(pk) => pk.verify(context, message, signature),
216 PublicKey::Sr25519(pk) => pk.verify(context, message, signature),
217 }
218 }
219
220 pub fn verify_raw(&self, message: &[u8], signature: &Signature) -> Result<(), Error> {
223 match self {
224 PublicKey::Ed25519(pk) => pk.verify_raw(message, signature),
225 PublicKey::Secp256k1(pk) => pk.verify_raw(message, signature),
226 PublicKey::Secp256r1(pk) => pk.verify_raw(message, signature),
227 PublicKey::Secp384r1(pk) => pk.verify_raw(message, signature),
228 PublicKey::Sr25519(_) => Err(Error::InvalidArgument),
229 }
230 }
231
232 pub fn verify_by_type(
234 &self,
235 signature_type: SignatureType,
236 context_or_hash: &[u8],
237 message: &[u8],
238 signature: &Signature,
239 ) -> Result<(), Error> {
240 match self {
241 Self::Ed25519(pk) => match signature_type {
242 SignatureType::Ed25519_Oasis => pk.verify(context_or_hash, message, signature),
243 SignatureType::Ed25519_Pure => pk.verify_raw(message, signature),
244 SignatureType::Ed25519_PrehashedSha512 => {
245 if context_or_hash.len()
246 != <sha2::Sha512 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
247 {
248 return Err(Error::InvalidArgument);
249 }
250 let digest =
251 digests::DummyDigest::<sha2::Sha512>::new_precomputed(context_or_hash);
252 pk.verify_digest(digest, signature)
253 }
254 _ => Err(Error::InvalidArgument),
255 },
256 Self::Secp256k1(pk) => match signature_type {
257 SignatureType::Secp256k1_Oasis => pk.verify(context_or_hash, message, signature),
258 SignatureType::Secp256k1_PrehashedKeccak256 => {
259 if context_or_hash.len()
260 != <sha3::Keccak256 as sha3::digest::OutputSizeUser>::OutputSize::USIZE
261 {
262 return Err(Error::InvalidArgument);
263 }
264 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
266 context_or_hash,
267 );
268 pk.verify_digest(digest, signature)
269 }
270 SignatureType::Secp256k1_PrehashedSha256 => {
271 if context_or_hash.len()
272 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
273 {
274 return Err(Error::InvalidArgument);
275 }
276 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
277 context_or_hash,
278 );
279 pk.verify_digest(digest, signature)
280 }
281 _ => Err(Error::InvalidArgument),
282 },
283 Self::Secp256r1(pk) => match signature_type {
284 SignatureType::Secp256r1_PrehashedSha256 => {
285 if context_or_hash.len()
286 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
287 {
288 return Err(Error::InvalidArgument);
289 }
290 let digest =
291 digests::DummyDigest::<sha2::Sha256>::new_precomputed(context_or_hash);
292 pk.verify_digest(digest, signature)
293 }
294 _ => Err(Error::InvalidArgument),
295 },
296 Self::Secp384r1(pk) => match signature_type {
297 SignatureType::Secp384r1_PrehashedSha384 => {
298 if context_or_hash.len()
299 != <sha2::Sha384 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
300 {
301 return Err(Error::InvalidArgument);
302 }
303 let digest =
304 digests::DummyDigest::<sha2::Sha384>::new_precomputed(context_or_hash);
305 pk.verify_digest(digest, signature)
306 }
307 _ => Err(Error::InvalidArgument),
308 },
309 Self::Sr25519(pk) => match signature_type {
310 SignatureType::Sr25519_Pure => pk.verify_raw(context_or_hash, message, signature),
311 _ => Err(Error::InvalidArgument),
312 },
313 }
314 }
315
316 pub fn verify_batch_multisig(
318 context: &[u8],
319 message: &[u8],
320 public_keys: &[PublicKey],
321 signatures: &[Signature],
322 ) -> Result<(), Error> {
323 if public_keys.len() != signatures.len() {
324 return Err(Error::InvalidArgument);
325 }
326
327 for (pk, sig) in public_keys.iter().zip(signatures.iter()) {
329 pk.verify(context, message, sig)?;
330 }
331 Ok(())
332 }
333}
334
335impl AsRef<[u8]> for PublicKey {
336 fn as_ref(&self) -> &[u8] {
337 self.as_bytes()
338 }
339}
340
341impl PartialEq<CorePublicKey> for PublicKey {
342 fn eq(&self, other: &CorePublicKey) -> bool {
343 match self {
344 PublicKey::Ed25519(pk) => pk.as_bytes() == other.as_ref(),
345 _ => false,
346 }
347 }
348}
349
350impl TryFrom<PublicKey> for CorePublicKey {
351 type Error = &'static str;
352
353 fn try_from(pk: PublicKey) -> Result<Self, Self::Error> {
354 match pk {
355 PublicKey::Ed25519(pk) => Ok(pk.into()),
356 _ => Err("not an Ed25519 public key"),
357 }
358 }
359}
360
361impl From<CorePublicKey> for PublicKey {
362 fn from(pk: CorePublicKey) -> Self {
363 Self::Ed25519(pk.into())
364 }
365}
366
367#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
369#[cbor(transparent)]
370pub struct Signature(Vec<u8>);
371
372impl AsRef<[u8]> for Signature {
373 fn as_ref(&self) -> &[u8] {
374 &self.0
375 }
376}
377
378impl From<Vec<u8>> for Signature {
379 fn from(v: Vec<u8>) -> Signature {
380 Signature(v)
381 }
382}
383
384impl From<Signature> for Vec<u8> {
385 fn from(s: Signature) -> Vec<u8> {
386 s.0
387 }
388}
389
390impl From<Signature> for CoreSignature {
391 fn from(s: Signature) -> Self {
392 s.as_ref().into()
393 }
394}
395
396pub trait Signer: Send + Sync {
398 fn random(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
400 where
401 Self: Sized;
402
403 fn new_from_seed(seed: &[u8]) -> Result<Self, Error>
405 where
406 Self: Sized;
407
408 fn from_bytes(bytes: &[u8]) -> Result<Self, Error>
410 where
411 Self: Sized;
412
413 fn to_bytes(&self) -> Vec<u8>;
415
416 fn public_key(&self) -> PublicKey;
418
419 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error>;
421
422 fn sign_raw(&self, message: &[u8]) -> Result<Signature, Error>;
424}
425
426impl<T: Signer + ?Sized> Signer for std::sync::Arc<T> {
427 fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
428 where
429 Self: Sized,
430 {
431 Err(Error::InvalidArgument)
432 }
433
434 fn new_from_seed(_seed: &[u8]) -> Result<Self, Error>
435 where
436 Self: Sized,
437 {
438 Err(Error::InvalidArgument)
439 }
440
441 fn from_bytes(_bytes: &[u8]) -> Result<Self, Error>
442 where
443 Self: Sized,
444 {
445 Err(Error::InvalidArgument)
446 }
447
448 fn to_bytes(&self) -> Vec<u8> {
449 T::to_bytes(self)
450 }
451
452 fn public_key(&self) -> PublicKey {
453 T::public_key(self)
454 }
455
456 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
457 T::sign(self, context, message)
458 }
459
460 fn sign_raw(&self, message: &[u8]) -> Result<Signature, Error> {
461 T::sign_raw(self, message)
462 }
463}
464
465impl<T: CoreSigner> Signer for &T {
466 fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
467 where
468 Self: Sized,
469 {
470 Err(Error::InvalidArgument)
471 }
472
473 fn new_from_seed(_seed: &[u8]) -> Result<Self, Error>
474 where
475 Self: Sized,
476 {
477 Err(Error::InvalidArgument)
478 }
479
480 fn from_bytes(_bytes: &[u8]) -> Result<Self, Error>
481 where
482 Self: Sized,
483 {
484 Err(Error::InvalidArgument)
485 }
486
487 fn to_bytes(&self) -> Vec<u8> {
488 vec![]
489 }
490
491 fn public_key(&self) -> PublicKey {
492 PublicKey::Ed25519(self.public().into())
493 }
494
495 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
496 let raw_sig = CoreSigner::sign(*self, context, message).map_err(|_| Error::SigningError)?;
497 Ok(Signature(raw_sig.as_ref().into()))
498 }
499
500 fn sign_raw(&self, _message: &[u8]) -> Result<Signature, Error> {
501 Err(Error::InvalidArgument)
502 }
503}
504
505impl Signer for crate::core::identity::Identity {
506 fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
507 where
508 Self: Sized,
509 {
510 Err(Error::InvalidArgument)
511 }
512
513 fn new_from_seed(_seed: &[u8]) -> Result<Self, Error>
514 where
515 Self: Sized,
516 {
517 Err(Error::InvalidArgument)
518 }
519
520 fn from_bytes(_bytes: &[u8]) -> Result<Self, Error>
521 where
522 Self: Sized,
523 {
524 Err(Error::InvalidArgument)
525 }
526
527 fn to_bytes(&self) -> Vec<u8> {
528 vec![]
529 }
530
531 fn public_key(&self) -> PublicKey {
532 PublicKey::Ed25519(self.public().into())
533 }
534
535 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
536 let raw_sig = CoreSigner::sign(self, context, message).map_err(|_| Error::SigningError)?;
537 Ok(Signature(raw_sig.as_ref().into()))
538 }
539
540 fn sign_raw(&self, _message: &[u8]) -> Result<Signature, Error> {
541 Err(Error::InvalidArgument)
542 }
543}
544
545pub enum MemorySigner {
547 Ed25519(ed25519::MemorySigner),
548 Secp256k1(secp256k1::MemorySigner),
549 Secp256r1(secp256r1::MemorySigner),
550 Secp384r1(secp384r1::MemorySigner),
551 Sr25519(sr25519::MemorySigner),
552}
553
554impl MemorySigner {
555 pub fn new_from_seed(sig_type: SignatureType, seed: &[u8]) -> Result<Self, Error> {
557 if sig_type.is_ed25519_variant() {
558 Ok(Self::Ed25519(ed25519::MemorySigner::new_from_seed(seed)?))
559 } else if sig_type.is_secp256k1_variant() {
560 Ok(Self::Secp256k1(secp256k1::MemorySigner::new_from_seed(
561 seed,
562 )?))
563 } else if sig_type.is_secp256r1_variant() {
564 Ok(Self::Secp256r1(secp256r1::MemorySigner::new_from_seed(
565 seed,
566 )?))
567 } else if sig_type.is_secp384r1_variant() {
568 Ok(Self::Secp384r1(secp384r1::MemorySigner::new_from_seed(
569 seed,
570 )?))
571 } else if sig_type.is_sr25519_variant() {
572 Ok(Self::Sr25519(sr25519::MemorySigner::new_from_seed(seed)?))
573 } else {
574 Err(Error::InvalidArgument)
575 }
576 }
577
578 pub fn new_test(sig_type: SignatureType, name: &str) -> Self {
580 if sig_type.is_secp384r1_variant() {
581 Self::new_from_seed(sig_type, &sha2::Sha384::digest(name)).unwrap()
582 } else {
583 Self::new_from_seed(sig_type, &sha2::Sha512_256::digest(name)).unwrap()
584 }
585 }
586
587 pub fn from_bytes(sig_type: SignatureType, bytes: &[u8]) -> Result<Self, Error> {
589 if sig_type.is_ed25519_variant() {
590 Ok(Self::Ed25519(ed25519::MemorySigner::from_bytes(bytes)?))
591 } else if sig_type.is_secp256k1_variant() {
592 Ok(Self::Secp256k1(secp256k1::MemorySigner::from_bytes(bytes)?))
593 } else if sig_type.is_secp256r1_variant() {
594 Ok(Self::Secp256r1(secp256r1::MemorySigner::from_bytes(bytes)?))
595 } else if sig_type.is_secp384r1_variant() {
596 Ok(Self::Secp384r1(secp384r1::MemorySigner::from_bytes(bytes)?))
597 } else if sig_type.is_sr25519_variant() {
598 Ok(Self::Sr25519(sr25519::MemorySigner::from_bytes(bytes)?))
599 } else {
600 Err(Error::InvalidArgument)
601 }
602 }
603
604 pub fn to_bytes(&self) -> Vec<u8> {
606 match self {
607 Self::Ed25519(signer) => signer.to_bytes(),
608 Self::Secp256k1(signer) => signer.to_bytes(),
609 Self::Secp256r1(signer) => signer.to_bytes(),
610 Self::Secp384r1(signer) => signer.to_bytes(),
611 Self::Sr25519(signer) => signer.to_bytes(),
612 }
613 }
614
615 pub fn public_key(&self) -> PublicKey {
617 match self {
618 Self::Ed25519(signer) => signer.public_key(),
619 Self::Secp256k1(signer) => signer.public_key(),
620 Self::Secp256r1(signer) => signer.public_key(),
621 Self::Secp384r1(signer) => signer.public_key(),
622 Self::Sr25519(signer) => signer.public_key(),
623 }
624 }
625
626 pub fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
628 match self {
629 Self::Ed25519(signer) => signer.sign(context, message),
630 Self::Secp256k1(signer) => signer.sign(context, message),
631 Self::Secp256r1(signer) => signer.sign(context, message),
632 Self::Secp384r1(signer) => signer.sign(context, message),
633 Self::Sr25519(signer) => signer.sign(context, message),
634 }
635 }
636
637 pub fn sign_raw(&self, message: &[u8]) -> Result<Signature, Error> {
639 match self {
640 Self::Ed25519(signer) => signer.sign_raw(message),
641 Self::Secp256k1(signer) => signer.sign_raw(message),
642 Self::Secp256r1(signer) => signer.sign_raw(message),
643 Self::Secp384r1(signer) => signer.sign_raw(message),
644 Self::Sr25519(signer) => signer.sign_raw(message),
645 }
646 }
647
648 pub fn sign_by_type(
650 &self,
651 signature_type: SignatureType,
652 context_or_hash: &[u8],
653 message: &[u8],
654 ) -> Result<Signature, Error> {
655 match self {
656 Self::Ed25519(signer) => match signature_type {
657 SignatureType::Ed25519_Oasis => signer.sign(context_or_hash, message),
658 SignatureType::Ed25519_Pure => signer.sign_raw(message),
659 SignatureType::Ed25519_PrehashedSha512 => {
660 if context_or_hash.len()
661 != <sha2::Sha512 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
662 {
663 return Err(Error::InvalidArgument);
664 }
665 let digest =
666 digests::DummyDigest::<sha2::Sha512>::new_precomputed(context_or_hash);
667 signer.sign_digest(digest)
668 }
669 _ => Err(Error::InvalidArgument),
670 },
671 Self::Secp256k1(signer) => match signature_type {
672 SignatureType::Secp256k1_Oasis => signer.sign(context_or_hash, message),
673 SignatureType::Secp256k1_PrehashedKeccak256 => {
674 if context_or_hash.len()
675 != <sha3::Keccak256 as sha3::digest::OutputSizeUser>::OutputSize::USIZE
676 {
677 return Err(Error::InvalidArgument);
678 }
679 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
681 context_or_hash,
682 );
683 signer.sign_digest(digest)
684 }
685 SignatureType::Secp256k1_PrehashedSha256 => {
686 if context_or_hash.len()
687 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
688 {
689 return Err(Error::InvalidArgument);
690 }
691 let digest = digests::DummyDigest::<k256::sha2::Sha256>::new_precomputed(
692 context_or_hash,
693 );
694 signer.sign_digest(digest)
695 }
696 _ => Err(Error::InvalidArgument),
697 },
698 Self::Secp256r1(signer) => match signature_type {
699 SignatureType::Secp256r1_PrehashedSha256 => {
700 if context_or_hash.len()
701 != <sha2::Sha256 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
702 {
703 return Err(Error::InvalidArgument);
704 }
705 let digest =
706 digests::DummyDigest::<sha2::Sha256>::new_precomputed(context_or_hash);
707 signer.sign_digest(digest)
708 }
709 _ => Err(Error::InvalidArgument),
710 },
711 Self::Secp384r1(signer) => match signature_type {
712 SignatureType::Secp384r1_PrehashedSha384 => {
713 if context_or_hash.len()
714 != <sha2::Sha384 as sha2::digest::OutputSizeUser>::OutputSize::USIZE
715 {
716 return Err(Error::InvalidArgument);
717 }
718 let digest =
719 digests::DummyDigest::<sha2::Sha384>::new_precomputed(context_or_hash);
720 signer.sign_digest(digest)
721 }
722 _ => Err(Error::InvalidArgument),
723 },
724 Self::Sr25519(signer) => match signature_type {
725 SignatureType::Sr25519_Pure => signer.sign(context_or_hash, message),
726 _ => Err(Error::InvalidArgument),
727 },
728 }
729 }
730}
731
732#[cfg(test)]
733mod test {
734 use super::*;
735
736 #[test]
737 fn test_signature_conversion() {
738 let raw = vec![0x00, 0x01, 0x02, 0x03];
739 let sig = Signature::from(raw.clone());
740 let v: Vec<u8> = sig.clone().into();
741 assert_eq!(v, raw);
742
743 let vref: &[u8] = v.as_ref();
744 assert_eq!(vref, sig.as_ref());
745 }
746
747 #[test]
748 fn test_memory_signer() {
749 let ctx = b"oasis-core/test: context";
750 let corrupt_ctx = b"oasis-core/test: wrong context";
751 let message = b"this is a message";
752 let corrupt_message = b"this isn't a message";
753
754 for sig_type in [
755 SignatureType::Ed25519_Oasis,
756 SignatureType::Ed25519_Pure,
757 SignatureType::Secp256k1_Oasis,
758 SignatureType::Sr25519_Pure,
759 ] {
760 let signer = MemorySigner::new_test(sig_type, "memory signer test");
761 let pk = signer.public_key();
762
763 let signature = signer
764 .sign_by_type(sig_type, ctx, message)
765 .expect("signing should succeed");
766
767 pk.verify_by_type(sig_type, ctx, message, &signature)
768 .expect("signature should verify");
769 pk.verify_by_type(sig_type, ctx, corrupt_message, &signature)
770 .expect_err("signature should fail verification");
771 if matches!(sig_type, SignatureType::Ed25519_Oasis)
772 || matches!(sig_type, SignatureType::Secp256k1_Oasis)
773 {
774 pk.verify_by_type(sig_type, corrupt_ctx, message, &signature)
775 .expect_err("signature should fail verification");
776 pk.verify_by_type(sig_type, corrupt_ctx, corrupt_message, &signature)
777 .expect_err("signature should fail verification");
778 }
779 }
780 }
781
782 #[test]
783 fn test_memory_signer_prehashed() {
784 let message = b"this is a message";
785 let corrupt_message = b"this isn't a message";
786
787 let sig_types: &[(SignatureType, Box<dyn Fn(&[u8]) -> Vec<u8>>)] = &[
788 (
789 SignatureType::Ed25519_PrehashedSha512,
790 Box::new(|message| sha2::Sha512::digest(message).to_vec()),
791 ),
792 (
793 SignatureType::Secp256k1_PrehashedKeccak256,
794 Box::new(|message| sha3::Keccak256::digest(message).to_vec()),
795 ),
796 (
797 SignatureType::Secp256k1_PrehashedSha256,
798 Box::new(|message| sha2::Sha256::digest(message).to_vec()),
799 ),
800 (
801 SignatureType::Secp256r1_PrehashedSha256,
802 Box::new(|message| sha2::Sha256::digest(message).to_vec()),
803 ),
804 (
805 SignatureType::Secp384r1_PrehashedSha384,
806 Box::new(|message| sha2::Sha384::digest(message).to_vec()),
807 ),
808 ];
809
810 for (sig_type, hasher) in sig_types {
811 let hash = hasher(message);
812 let corrupt_hash = hasher(corrupt_message);
813
814 let signer = MemorySigner::new_test(*sig_type, "memory signer test");
815 let pk = signer.public_key();
816
817 let signature = signer
818 .sign_by_type(*sig_type, &hash, b"")
819 .expect("signing should succeed");
820 pk.verify_by_type(*sig_type, &hash, b"", &signature)
821 .expect("signature should verify");
822 pk.verify_by_type(*sig_type, &corrupt_hash, b"", &signature)
823 .expect_err("corrupt hash shouldn't verify");
824 }
825 }
826}