pq-mayo
A Rust implementation of the MAYO post-quantum signature scheme, submitted to the NIST PQC standardization process.
Supported Parameter Sets
| Parameter Set | Security Level | Signature Size | Public Key Size | Private Key Size |
|---|---|---|---|---|
| Mayo1 | 1 | 454 B | 1420 B | 24 B |
| Mayo2 | 1 | 186 B | 4912 B | 24 B |
| Mayo3 | 3 | 681 B | 2986 B | 32 B |
| Mayo5 | 5 | 964 B | 5554 B | 40 B |
Performance
Benchmarked on Apple M1 (aarch64) with -C target-cpu=native:
| Operation | Time |
|---|---|
| Mayo1/keygen | 269.19 µs |
| Mayo1/sign | 698.57 µs |
| Mayo1/verify | 192.85 µs |
| Mayo2/keygen | 331.42 µs |
| Mayo2/sign | 477.97 µs |
| Mayo2/verify | 87.92 µs |
| Mayo3/keygen | 765.33 µs |
| Mayo3/sign | 1.899 ms |
| Mayo3/verify | 434.75 µs |
| Mayo5/keygen | 1.713 ms |
| Mayo5/sign | 4.406 ms |
| Mayo5/verify | 665.64 µs |
Run your own benchmarks:
Usage
Basic Sign and Verify
use ;
use ;
let mut rng = rng;
let keypair = generate.expect;
let msg = b"hello world";
let sig = keypair.signing_key.try_sign.expect;
keypair.verifying_key.verify.expect;
Using Different Parameter Sets
use ;
use ;
let mut rng = rng;
// NIST security level 2
let kp2 = generate.expect;
let sig2 = kp2.signing_key.try_sign.expect;
kp2.verifying_key.verify.expect;
// NIST security level 3
let kp3 = generate.expect;
// NIST security level 5
let kp5 = generate.expect;
Key Serialization
Keys and signatures implement AsRef<[u8]> and TryFrom<&[u8]> for raw byte serialization:
use ;
use ;
let mut rng = rng;
let keypair = generate.expect;
// Export keys as raw bytes
let sk_bytes: & = keypair.signing_key.as_ref;
let vk_bytes: & = keypair.verifying_key.as_ref;
// Reconstruct keys from bytes
let sk = try_from.expect;
let vk = try_from.expect;
// Sign with reconstructed key, verify with reconstructed key
let sig = sk.try_sign.expect;
vk.verify.expect;
// Signatures can also be serialized/deserialized
let sig_bytes: & = sig.as_ref;
let sig2 = try_from.expect;
Deriving a Verifying Key from a Signing Key
use ;
use ;
let mut rng = rng;
let keypair = generate.expect;
// Derive the verifying (public) key from the signing (secret) key
let vk = from;
let sig = keypair.signing_key.try_sign.expect;
vk.verify.expect;
Serde Support
Enable the serde feature for JSON/binary serialization:
[]
= { = "0.1", = ["serde"] }
use ;
let mut rng = rng;
let keypair = generate.expect;
// Serialize to JSON
let json = to_string.expect;
let restored: = from_str.expect;
PKCS#8 and SPKI Support
Enable the pkcs8 feature for DER-encoded key serialization compatible with X.509 and PKCS#8 standards:
[]
= { = "0.1", = ["pkcs8"] }
This implements the standard RustCrypto key encoding traits:
EncodePrivateKey/DecodePrivateKeyforKeyPair(PKCS#8 DER)DecodePrivateKeyforSigningKey(PKCS#8 DER)EncodePublicKey/DecodePublicKeyforVerifyingKey(SPKI DER)
use ;
use DecodePrivateKey;
use EncodePrivateKey;
use ;
use ;
let mut rng = rng;
let keypair = generate.expect;
// Encode private key to PKCS#8 DER
let sk_der = keypair.to_pkcs8_der.expect;
// Decode private key from PKCS#8 DER
let restored = from_pkcs8_der.expect;
// Encode public key to SPKI DER
let vk_der = keypair.verifying_key.to_public_key_der.expect;
// Decode public key from SPKI DER
let restored_vk = from_public_key_der.expect;
// Sign and verify with round-tripped keys
let sig = restored.signing_key.try_sign.expect;
restored_vk.verify.expect;
Since MAYO has not yet been standardized by NIST, experimental OIDs from the
Open Quantum Safe project are used (1.3.9999.8.{1,2,3,5}.3).
These will be replaced with official NIST OIDs upon standardization.
WebAssembly Support
This crate compiles to wasm32-unknown-unknown using pure Rust implementations
for all cryptographic primitives. Enable the js feature to use the browser's
crypto.getRandomValues for randomness:
[]
= { = "0.1", = ["js"] }
Serialization
This crate has been tested against the following serde compatible formats:
- serde_bare
- bincode
- postcard
- serde_cbor
- serde_json
- serde_yaml
- toml
Mitigations
There is a known fault injection attack against MAYO described in MAYO Key Recovery by Fixing Vinegar Seeds. This code contains mitigations to these attacks.
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.