1#[cfg(feature = "alloc")]
13mod blinded_signing_key;
14mod generic_signing_key;
15mod signature;
16#[cfg(feature = "alloc")]
17mod signing_key;
18mod verifying_key;
19
20pub use self::generic_signing_key::GenericSigningKey;
21#[cfg(feature = "alloc")]
22pub use self::{blinded_signing_key::BlindedSigningKey, signing_key::SigningKey};
23
24#[cfg(feature = "alloc")]
25pub use self::{signature::Signature, verifying_key::VerifyingKey};
26pub use self::{
27 signature::{GenericSignature, SignatureBytes},
28 verifying_key::GenericVerifyingKey,
29};
30
31#[cfg(feature = "alloc")]
32use alloc::{vec, vec::Vec};
33use core::fmt::{self, Debug};
34#[cfg(feature = "alloc")]
35use crypto_bigint::BoxedUint;
36
37use digest::{Digest, FixedOutputReset};
38use rand_core::TryCryptoRng;
39
40#[cfg(feature = "alloc")]
41use crate::algorithms::pad::{uint_to_be_pad, uint_to_be_pad_into, uint_to_zeroizing_be_pad};
42use crate::algorithms::pss::*;
43#[cfg(feature = "alloc")]
44use crate::algorithms::rsa::rsa_decrypt_and_check;
45#[cfg(feature = "alloc")]
46use crate::algorithms::rsa::rsa_encrypt;
47use crate::errors::{Error, Result};
48use crate::traits::{PublicKeyParts, SignatureScheme, UnsignedModularInt};
49#[cfg(feature = "alloc")]
50use crate::RsaPrivateKey;
51#[cfg(feature = "alloc")]
52use crate::RsaPublicKey;
53
54#[cfg(feature = "encoding")]
55use {
56 crate::encoding::ID_RSASSA_PSS,
57 const_oid::AssociatedOid,
58 pkcs1::RsaPssParams,
59 spki::{der::Any, AlgorithmIdentifierOwned},
60};
61
62pub struct Pss<D> {
64 pub blinded: bool,
66
67 pub digest: D,
69
70 pub salt_len: Option<usize>,
73}
74
75impl<D> Default for Pss<D>
76where
77 D: Digest,
78{
79 fn default() -> Self {
80 Self::new()
81 }
82}
83
84impl<D> Pss<D>
85where
86 D: Digest,
87{
88 pub fn new() -> Self {
91 Self::new_with_salt(<D as Digest>::output_size())
92 }
93
94 pub fn new_with_salt(len: usize) -> Self {
96 Self {
97 blinded: false,
98 digest: D::new(),
99 salt_len: Some(len),
100 }
101 }
102
103 pub fn new_blinded() -> Self {
106 Self::new_blinded_with_salt(<D as Digest>::output_size())
107 }
108
109 pub fn new_blinded_with_salt(len: usize) -> Self {
112 Self {
113 blinded: true,
114 digest: D::new(),
115 salt_len: Some(len),
116 }
117 }
118}
119
120#[cfg(feature = "alloc")]
121impl<D> SignatureScheme for Pss<D>
122where
123 D: Digest + FixedOutputReset,
124{
125 #[cfg(feature = "alloc")]
126 fn sign<Rng: TryCryptoRng + ?Sized>(
127 mut self,
128 rng: Option<&mut Rng>,
129 priv_key: &RsaPrivateKey,
130 hashed: &[u8],
131 ) -> Result<Vec<u8>> {
132 sign(
133 rng.ok_or(Error::InvalidPaddingScheme)?,
134 self.blinded,
135 priv_key,
136 hashed,
137 self.salt_len.expect("salt_len to be Some"),
138 &mut self.digest,
139 )
140 }
141
142 fn verify<K, T>(mut self, pub_key: &K, hashed: &[u8], sig: &[u8]) -> Result<()>
143 where
144 T: UnsignedModularInt,
145 K: PublicKeyParts<T>,
146 {
147 if sig.len() != pub_key.size() {
148 return Err(Error::Verification);
149 }
150 let sig = T::try_from_be_bytes_vartime(sig).map_err(|_| Error::Verification)?;
151 if sig >= *pub_key.n().as_ref() || sig.bits_precision() != pub_key.n_bits_precision() {
152 return Err(Error::Verification);
153 }
154
155 let mut em = vec![0u8; pub_key.size()];
156 let em_len =
157 uint_to_be_pad_into(rsa_encrypt(pub_key, &sig)?, pub_key.size(), &mut em)?.len();
158
159 emsa_pss_verify(
160 hashed,
161 &mut em[..em_len],
162 self.salt_len,
163 &mut self.digest,
164 pub_key.n().bits() as _,
165 )
166 }
167}
168
169impl<D> Debug for Pss<D> {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 f.debug_struct("PSS")
172 .field("blinded", &self.blinded)
173 .field("digest", &"...")
174 .field("salt_len", &self.salt_len)
175 .finish()
176 }
177}
178
179#[cfg(feature = "alloc")]
180#[allow(dead_code)]
181pub(crate) fn verify<D>(
182 pub_key: &RsaPublicKey,
183 hashed: &[u8],
184 sig: &BoxedUint,
185 sig_len: usize,
186 digest: &mut D,
187 salt_len: Option<usize>,
188) -> Result<()>
189where
190 D: Digest + FixedOutputReset,
191{
192 if sig_len != pub_key.size() {
193 return Err(Error::Verification);
194 }
195 let raw = rsa_encrypt(pub_key, sig)?;
196 let mut em = uint_to_be_pad(raw, pub_key.size())?;
197
198 emsa_pss_verify(hashed, &mut em, salt_len, digest, pub_key.n().bits() as _)
199}
200
201#[cfg(feature = "alloc")]
202#[allow(dead_code)]
203pub(crate) fn verify_digest<D>(
204 pub_key: &RsaPublicKey,
205 hashed: &[u8],
206 sig: &BoxedUint,
207 salt_len: Option<usize>,
208) -> Result<()>
209where
210 D: Digest + FixedOutputReset,
211{
212 let mut storage = vec![0u8; pub_key.size()];
213 verify_digest_into::<D, _, BoxedUint>(pub_key, hashed, sig, salt_len, &mut storage)
214}
215
216pub fn verify_digest_into<D, K, T>(
218 pub_key: &K,
219 hashed: &[u8],
220 sig: &T,
221 salt_len: Option<usize>,
222 storage: &mut [u8],
223) -> crate::Result<()>
224where
225 D: digest::Digest + digest::FixedOutputReset,
226 K: crate::traits::PublicKeyParts<T>,
227 T: crate::traits::UnsignedModularInt,
228{
229 if sig >= pub_key.n().as_ref() || sig.bits_precision() != pub_key.n_bits_precision() {
230 return Err(crate::Error::Verification);
231 }
232 let padded_len = pub_key.size();
233 let em = crate::algorithms::pad::uint_to_be_pad_into(
234 crate::algorithms::rsa::rsa_encrypt(pub_key, sig)?,
235 padded_len,
236 storage,
237 )?;
238 let em_len = em.len();
241 emsa_pss_verify_digest::<D>(
242 hashed,
243 &mut storage[..em_len],
244 salt_len,
245 pub_key.n().bits() as _,
246 )
247}
248
249#[cfg(feature = "alloc")]
255pub(crate) fn sign<T, D>(
256 rng: &mut T,
257 blind: bool,
258 priv_key: &RsaPrivateKey,
259 hashed: &[u8],
260 salt_len: usize,
261 digest: &mut D,
262) -> Result<Vec<u8>>
263where
264 T: TryCryptoRng + ?Sized,
265 D: Digest + FixedOutputReset,
266{
267 let mut salt = vec![0; salt_len];
268 rng.try_fill_bytes(&mut salt[..]).map_err(|_| Error::Rng)?;
269
270 sign_pss_with_salt(blind.then_some(rng), priv_key, hashed, &salt, digest)
271}
272
273#[cfg(feature = "alloc")]
274pub(crate) fn sign_digest<T, D>(
275 rng: &mut T,
276 blind: bool,
277 priv_key: &RsaPrivateKey,
278 hashed: &[u8],
279 salt_len: usize,
280) -> Result<Vec<u8>>
281where
282 T: TryCryptoRng + ?Sized,
283 D: Digest + FixedOutputReset,
284{
285 let mut salt = vec![0; salt_len];
286 rng.try_fill_bytes(&mut salt[..]).map_err(|_| Error::Rng)?;
287
288 sign_pss_with_salt_digest::<_, D>(blind.then_some(rng), priv_key, hashed, &salt)
289}
290
291#[cfg(feature = "alloc")]
297fn sign_pss_with_salt<T, D>(
298 blind_rng: Option<&mut T>,
299 priv_key: &RsaPrivateKey,
300 hashed: &[u8],
301 salt: &[u8],
302 digest: &mut D,
303) -> Result<Vec<u8>>
304where
305 T: TryCryptoRng + ?Sized,
306 D: Digest + FixedOutputReset,
307{
308 let em_bits = priv_key.n().bits() - 1;
309
310 let em = emsa_pss_encode(hashed, em_bits as _, salt, digest)?;
311
312 let em = BoxedUint::from_be_slice(&em, priv_key.n_bits_precision())?;
313 let raw = rsa_decrypt_and_check(priv_key, blind_rng, &em)?;
314 uint_to_zeroizing_be_pad(raw, priv_key.size())
315}
316
317#[cfg(feature = "alloc")]
318fn sign_pss_with_salt_digest<T, D>(
319 blind_rng: Option<&mut T>,
320 priv_key: &RsaPrivateKey,
321 hashed: &[u8],
322 salt: &[u8],
323) -> Result<Vec<u8>>
324where
325 T: TryCryptoRng + ?Sized,
326 D: Digest + FixedOutputReset,
327{
328 let em_bits = priv_key.n().bits() - 1;
329 let em = emsa_pss_encode_digest::<D>(hashed, em_bits as _, salt)?;
330
331 let em = BoxedUint::from_be_slice(&em, priv_key.n_bits_precision())?;
332 uint_to_zeroizing_be_pad(
333 rsa_decrypt_and_check(priv_key, blind_rng, &em)?,
334 priv_key.size(),
335 )
336}
337
338#[cfg(feature = "encoding")]
340pub fn get_default_pss_signature_algo_id<D>() -> spki::Result<AlgorithmIdentifierOwned>
341where
342 D: Digest + AssociatedOid,
343{
344 let salt_len: u8 = <D as Digest>::output_size() as u8;
345 get_pss_signature_algo_id::<D>(salt_len)
346}
347
348#[cfg(feature = "encoding")]
349fn get_pss_signature_algo_id<D>(salt_len: u8) -> spki::Result<AlgorithmIdentifierOwned>
350where
351 D: Digest + AssociatedOid,
352{
353 let pss_params = RsaPssParams::new::<D>(salt_len);
354
355 Ok(AlgorithmIdentifierOwned {
356 oid: ID_RSASSA_PSS,
357 parameters: Some(Any::encode_from(&pss_params)?),
358 })
359}
360
361#[cfg(all(test, feature = "encoding"))]
362mod test {
363 use crate::pss::{BlindedSigningKey, Pss, Signature, SigningKey, VerifyingKey};
364 use crate::{RsaPrivateKey, RsaPublicKey};
365
366 use crate::traits::PublicKeyParts;
367 use hex_literal::hex;
368 use pkcs1::DecodeRsaPrivateKey;
369 use rand::rngs::ChaCha8Rng;
370 use rand_core::SeedableRng;
371 use rstest::rstest;
372 use sha1::{Digest, Sha1};
373 use signature::hazmat::{PrehashVerifier, RandomizedPrehashSigner};
374 use signature::{DigestVerifier, Keypair, RandomizedDigestSigner, RandomizedSigner, Verifier};
375
376 fn get_private_key() -> RsaPrivateKey {
377 let pem = r#"
389-----BEGIN RSA PRIVATE KEY-----
390MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
391fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
392/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
393RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
394EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
395IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
396tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
397-----END RSA PRIVATE KEY-----"#;
398
399 RsaPrivateKey::from_pkcs1_pem(pem).unwrap()
400 }
401
402 #[rstest]
403 #[case(
404 "test\n",
405 hex!(
406 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
407 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f"
408 ),
409 true,
410 )]
411 #[case(
412 "test\n",
413 hex!(
414 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
415 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e"
416 ),
417 false,
418 )]
419 fn test_verify_pss(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) {
420 let priv_key = get_private_key();
421 let pub_key: RsaPublicKey = priv_key.into();
422
423 let digest = Sha1::digest(text.as_bytes()).to_vec();
424 let result = pub_key.verify(Pss::<Sha1>::new(), &digest, &sig);
425
426 match expected {
427 true => result.expect("failed to verify"),
428 false => {
429 result.expect_err("expected verifying error");
430 }
431 }
432 }
433
434 #[rstest]
435 #[case(
436 "test\n",
437 hex!(
438 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
439 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f"
440 ),
441 true,
442 )]
443 #[case(
444 "test\n",
445 hex!(
446 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
447 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e"
448 ),
449 false,
450 )]
451 fn test_verify_pss_signer(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) {
452 let priv_key = get_private_key();
453 let pub_key: RsaPublicKey = priv_key.into();
454 let verifying_key: VerifyingKey<Sha1> = VerifyingKey::new(pub_key);
455
456 let result = verifying_key.verify(
457 text.as_bytes(),
458 &Signature::try_from(sig.as_slice()).unwrap(),
459 );
460 match expected {
461 true => result.expect("failed to verify"),
462 false => {
463 result.expect_err("expected verifying error");
464 }
465 }
466 }
467
468 #[rstest]
469 #[case(
470 "test\n",
471 hex!(
472 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
473 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f"
474 ),
475 true,
476 )]
477 #[case(
478 "test\n",
479 hex!(
480 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
481 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e"
482 ),
483 false,
484 )]
485 fn test_verify_pss_digest_signer(
486 #[case] text: &str,
487 #[case] sig: [u8; 64],
488 #[case] expected: bool,
489 ) {
490 let priv_key = get_private_key();
491 let pub_key: RsaPublicKey = priv_key.into();
492 let verifying_key = VerifyingKey::new(pub_key);
493
494 let result = verifying_key.verify_digest(
495 |digest: &mut Sha1| {
496 digest.update(text.as_bytes());
497 Ok(())
498 },
499 &Signature::try_from(sig.as_slice()).unwrap(),
500 );
501 match expected {
502 true => result.expect("failed to verify"),
503 false => {
504 result.expect_err("expected verifying error");
505 }
506 }
507 }
508
509 #[rstest]
510 #[case("test\n")]
511 fn test_sign_and_verify_roundtrip(#[case] test: &str) {
512 let priv_key = get_private_key();
513
514 let mut rng = ChaCha8Rng::from_seed([42; 32]);
515
516 let digest = Sha1::digest(test.as_bytes()).to_vec();
517 let sig = priv_key
518 .sign_with_rng(&mut rng, Pss::<Sha1>::new(), &digest)
519 .expect("failed to sign");
520
521 priv_key
522 .to_public_key()
523 .verify(Pss::<Sha1>::new(), &digest, &sig)
524 .expect("failed to verify");
525 }
526
527 #[rstest]
528 #[case("test\n")]
529 fn test_sign_blinded_and_verify_roundtrip(#[case] test: &str) {
530 let priv_key = get_private_key();
531
532 let mut rng = ChaCha8Rng::from_seed([42; 32]);
533
534 let digest = Sha1::digest(test.as_bytes()).to_vec();
535 let sig = priv_key
536 .sign_with_rng(&mut rng, Pss::<Sha1>::new_blinded(), &digest)
537 .expect("failed to sign");
538
539 priv_key
540 .to_public_key()
541 .verify(Pss::<Sha1>::new(), &digest, &sig)
542 .expect("failed to verify");
543 }
544
545 #[rstest]
546 #[case("test\n")]
547 fn test_sign_and_verify_roundtrip_signer(#[case] test: &str) {
548 let priv_key = get_private_key();
549
550 let mut rng = ChaCha8Rng::from_seed([42; 32]);
551 let signing_key = SigningKey::<Sha1>::new(priv_key);
552 let verifying_key = signing_key.verifying_key();
553
554 let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes());
555 verifying_key
556 .verify(test.as_bytes(), &sig)
557 .expect("failed to verify");
558 }
559
560 #[rstest]
561 #[case("test\n")]
562 fn test_sign_and_verify_roundtrip_blinded_signer(#[case] test: &str) {
563 let priv_key = get_private_key();
564
565 let mut rng = ChaCha8Rng::from_seed([42; 32]);
566 let signing_key = BlindedSigningKey::<Sha1>::new(priv_key);
567 let verifying_key = signing_key.verifying_key();
568
569 let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes());
570 verifying_key
571 .verify(test.as_bytes(), &sig)
572 .expect("failed to verify");
573 }
574
575 #[rstest]
576 #[case("test\n")]
577 fn test_sign_and_verify_roundtrip_digest_signer(#[case] test: &str) {
578 let priv_key = get_private_key();
579
580 let mut rng = ChaCha8Rng::from_seed([42; 32]);
581 let signing_key = SigningKey::new(priv_key);
582 let verifying_key = signing_key.verifying_key();
583
584 let sig = signing_key
585 .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes()));
586
587 verifying_key
588 .verify_digest(
589 |digest: &mut Sha1| {
590 digest.update(test.as_bytes());
591 Ok(())
592 },
593 &sig,
594 )
595 .expect("failed to verify");
596 }
597
598 #[rstest]
599 #[case("test\n")]
600 fn test_sign_and_verify_roundtrip_blinded_digest_signer(#[case] test: &str) {
601 let priv_key = get_private_key();
602
603 let mut rng = ChaCha8Rng::from_seed([42; 32]);
604 let signing_key = BlindedSigningKey::<Sha1>::new(priv_key);
605 let verifying_key = signing_key.verifying_key();
606
607 let sig = signing_key
608 .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes()));
609
610 verifying_key
611 .verify_digest(
612 |digest: &mut Sha1| {
613 digest.update(test.as_bytes());
614 Ok(())
615 },
616 &sig,
617 )
618 .expect("failed to verify");
619 }
620
621 #[rstest]
622 #[case(
623 "test\n",
624 hex!(
625 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
626 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f"
627 ),
628 true
629 )]
630 #[case(
631 "test\n",
632 hex!(
633 "6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
634 "30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e"
635 ),
636 false
637 )]
638 fn test_verify_pss_hazmat(#[case] text: &str, #[case] sig: [u8; 64], #[case] expected: bool) {
639 let text = Sha1::digest(text);
640 let priv_key = get_private_key();
641
642 let pub_key: RsaPublicKey = priv_key.into();
643 let verifying_key = VerifyingKey::<Sha1>::new(pub_key);
644
645 let result = verifying_key
646 .verify_prehash(text.as_ref(), &Signature::try_from(sig.as_slice()).unwrap());
647 match expected {
648 true => result.expect("failed to verify"),
649 false => {
650 result.expect_err("expected verifying error");
651 }
652 }
653 }
654
655 #[rstest]
656 #[case("test\n")]
657 fn test_sign_and_verify_pss_hazmat(#[case] test: &str) {
658 let test = &Sha1::digest(test);
659 let priv_key = get_private_key();
660
661 let mut rng = ChaCha8Rng::from_seed([42; 32]);
662 let signing_key = SigningKey::<Sha1>::new(priv_key);
663 let verifying_key = signing_key.verifying_key();
664
665 let sig = signing_key
666 .sign_prehash_with_rng(&mut rng, test)
667 .expect("failed to sign");
668 verifying_key
669 .verify_prehash(test, &sig)
670 .expect("failed to verify");
671 }
672
673 #[rstest]
674 #[case("test\n")]
675 fn test_sign_and_verify_pss_blinded_hazmat(#[case] test: &str) {
676 let priv_key = get_private_key();
677
678 let test = &Sha1::digest(test);
679 let mut rng = ChaCha8Rng::from_seed([42; 32]);
680 let signing_key = BlindedSigningKey::<Sha1>::new(priv_key);
681 let verifying_key = signing_key.verifying_key();
682
683 let sig = signing_key
684 .sign_prehash_with_rng(&mut rng, test)
685 .expect("failed to sign");
686 verifying_key
687 .verify_prehash(test, &sig)
688 .expect("failed to verify");
689 }
690
691 #[test]
692 #[cfg(feature = "keygen")]
693 fn test_sign_and_verify_2049bit_key() {
695 let plaintext = "Hello\n";
696 let mut rng = ChaCha8Rng::from_seed([42; 32]);
697 for i in 0..10 {
698 println!("round {i}");
699 let priv_key = RsaPrivateKey::new(&mut rng, 2049).unwrap();
700
701 let digest = Sha1::digest(plaintext.as_bytes()).to_vec();
702 let sig = priv_key
703 .sign_with_rng(&mut rng, Pss::<Sha1>::new(), &digest)
704 .expect("failed to sign");
705
706 priv_key
707 .to_public_key()
708 .verify(Pss::<Sha1>::new(), &digest, &sig)
709 .expect("failed to verify");
710 }
711 }
712
713 #[rstest]
716 #[case("test\n")]
717 fn test_sign_and_verify_pss_differing_salt_len(#[case] test: &str) {
718 let priv_key = get_private_key();
719
720 let mut rng = ChaCha8Rng::from_seed([42; 32]);
721
722 let signing_keys = [
724 SigningKey::<Sha1>::new(priv_key.clone()),
726 SigningKey::<Sha1>::new_with_salt_len(
728 priv_key.clone(),
729 priv_key.size() - Sha1::output_size() - 2,
730 ),
731 SigningKey::<Sha1>::new_with_salt_len(priv_key.clone(), 0),
733 ];
734
735 let verifying_key = VerifyingKey::<Sha1>::new_with_auto_salt_len(priv_key.to_public_key());
737
738 for signing_key in &signing_keys {
739 let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes());
740 verifying_key
741 .verify(test.as_bytes(), &sig)
742 .expect("verification to succeed");
743 }
744 }
745}