### Install lms-signature Crate Source: https://github.com/rustcrypto/signatures/blob/master/lms/README.md Use cargo to install the lms-signature crate. ```terminal cargo install ``` -------------------------------- ### Generate and Sign with LMS Key Source: https://context7.com/rustcrypto/signatures/llms.txt Demonstrates generating a new LMS signing key, retrieving the verifying key, and signing a message. Note that LMS keys are stateful and signing mutates the key's internal state. Ensure proper persistence of key state after each signature. ```rust use lms_signature::{ lms::{SigningKey, VerifyingKey, Signature, LmsSha256M32H10}, ots::LmsOtsSha256N32W4, }; use signature::{RandomizedSignerMut, Verifier}; use getrandom::{SysRng, rand_core::UnwrapErr}; // Generate a fresh LMS keypair let mut rng = UnwrapErr(SysRng); let mut signing_key = SigningKey::>::new(&mut rng); // Get the public (verifying) key let verifying_key = signing_key.public(); // Sign a message (IMPORTANT: mutates key state!) let message = b"important document"; let signature = signing_key.try_sign_with_rng(&mut rng, message) .expect("signing failed - key may be exhausted"); // Verify the signature assert!(verifying_key.verify(message, &signature).is_ok()); // WARNING: LMS keys are stateful! // - Never sign more than one message with the same internal OTS key // - Persist key state after EVERY signature before releasing the signature // - Never load the same private key from storage twice // - Key exhaustion occurs after 2^H signatures (H = tree height) // Available modes: // LmsSha256M32H5: 2^5 = 32 signatures // LmsSha256M32H10: 2^10 = 1024 signatures // LmsSha256M32H15: 2^15 = 32768 signatures // LmsSha256M32H20: 2^20 = ~1M signatures // LmsSha256M32H25: 2^25 = ~33M signatures ``` -------------------------------- ### Perform XMSS Signature Operations Source: https://github.com/rustcrypto/signatures/blob/master/xmss/README.md Demonstrates key pair generation, signing, and verification using the XMSS scheme. Note that this implementation is stateful and requires careful management of key material. ```rust use xmss::{KeyPair, XmssSha2_10_256}; // Generate a key pair let mut kp = KeyPair::::generate(&mut rand::rng()).unwrap(); // Sign a message let message = b"test message"; let signature = kp.signing_key().sign(message).unwrap(); // Verify the signature and recover the message let recovered = kp.verifying_key().verify(&signature).unwrap(); assert_eq!(recovered, message); // Detached signatures are also supported let signature = kp.signing_key().sign_detached(message).unwrap(); kp.verifying_key().verify_detached(&signature, message).unwrap(); ``` -------------------------------- ### Generate and Verify DSA Signatures Source: https://context7.com/rustcrypto/signatures/llms.txt Demonstrates key generation, signing, verification, and PKCS#8 serialization for the DSA algorithm. ```rust use dsa::{Components, KeySize, SigningKey, VerifyingKey, Signature}; use signature::{RandomizedDigestSigner, Verifier, SignatureEncoding}; use sha2::Sha256; use getrandom::{SysRng, rand_core::UnwrapErr}; // Generate DSA components (p, q, g parameters) let mut rng = UnwrapErr(SysRng); let components = Components::generate(&mut rng, KeySize::DSA_2048_256); // Generate signing key from components let signing_key = SigningKey::generate(&mut rng, components); // Get verifying (public) key let verifying_key = signing_key.verifying_key(); // Sign a message with digest let signature = signing_key.sign_digest_with_rng( &mut rng, |digest: &mut Sha256| digest.update(b"message to sign") ); // Verify signature let is_valid = verifying_key.verify(b"message to sign", &signature); // Serialize/deserialize keys using PKCS#8 use pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding}; let private_pem = signing_key.to_pkcs8_pem(LineEnding::LF).unwrap(); let public_pem = verifying_key.to_public_key_pem(LineEnding::LF).unwrap(); // Serialize signature to DER let sig_bytes = signature.to_bytes(); ``` -------------------------------- ### Generate and Verify LMS Signature Source: https://github.com/rustcrypto/signatures/blob/master/lms/README.md Demonstrates generating a new LMS private key, deriving its public key, signing a message, and verifying the signature. Ensure the random number generator is properly seeded. ```rust let mut rng = thread_rng(); let mut seckey = lms::lms::PrivateKey::new:: > ( & mut rng); let pubkey = seckey.public(); // of type lms::lms::PublicKey let sig = seckey.try_sign_with_rng( & mut rng, "example".as_bytes()).unwrap(); let sig_valid = pubkey.verify("example".as_bytes(), & sig).is_ok(); ``` -------------------------------- ### Handle ECDSA Signatures Source: https://context7.com/rustcrypto/signatures/llms.txt Demonstrates parsing, serializing, and normalizing ECDSA signatures using the ecdsa crate. ```rust use ecdsa::{Signature, SignatureSize, EcdsaCurve}; use elliptic_curve::array::ArraySize; // Parse signature from fixed-width bytes (64 bytes for P-256) let sig_bytes: [u8; 64] = [/* r || s components */]; let signature = Signature::::from_slice(&sig_bytes) .expect("invalid signature"); // Parse signature from ASN.1 DER encoding let der_bytes: &[u8] = &[/* DER-encoded signature */]; let signature = Signature::::from_der(der_bytes) .expect("invalid DER signature"); // Create signature from r and s scalar components let r_bytes: [u8; 32] = [/* r component */]; let s_bytes: [u8; 32] = [/* s component */]; let signature = Signature::::from_scalars(r_bytes, s_bytes) .expect("invalid scalars"); // Serialize signature let fixed_bytes = signature.to_bytes(); // Fixed-width format let der_sig = signature.to_der(); // ASN.1 DER format // Split signature into components let (r, s) = signature.split_bytes(); // Normalize to low-S form (BIP-0062) let normalized = signature.normalize_s(); ``` -------------------------------- ### Manage ECDSA SigningKeys Source: https://context7.com/rustcrypto/signatures/llms.txt Shows key generation, signing, and key management using the SigningKey struct. ```rust use ecdsa::SigningKey; use p256::NistP256; use signature::{Signer, RandomizedSigner}; use rand_core::OsRng; // Generate a new random signing key let signing_key = SigningKey::::generate_from_rng(&mut OsRng); // Create from raw scalar bytes let secret_bytes: [u8; 32] = [/* 32-byte secret scalar */]; let signing_key = SigningKey::::from_bytes(&secret_bytes.into()) .expect("invalid secret key"); // Create from byte slice let signing_key = SigningKey::::from_slice(&secret_bytes) .expect("invalid secret key"); // Sign a message (deterministic via RFC6979) let message = b"Hello, world!"; let signature: ecdsa::Signature = signing_key.sign(message); // Sign with additional randomness (hedged signing) let signature = signing_key.sign_with_rng(&mut OsRng, message); // Get the verifying (public) key let verifying_key = signing_key.verifying_key(); // Serialize the signing key let key_bytes = signing_key.to_bytes(); // Access the underlying non-zero scalar let scalar = signing_key.as_nonzero_scalar(); ``` -------------------------------- ### Generate and Verify ML-DSA Signatures Source: https://context7.com/rustcrypto/signatures/llms.txt Covers key generation, deterministic signing, context-aware signing, and encoding for ML-DSA (CRYSTALS-Dilithium). ```rust use ml_dsa::{ signature::{Keypair, Signer, Verifier}, MlDsa44, MlDsa65, MlDsa87, KeyGen, Signature, SigningKey, VerifyingKey, }; use getrandom::{SysRng, rand_core::UnwrapErr}; // Generate key pair (security category 3) let mut rng = UnwrapErr(SysRng); let keypair = MlDsa65::key_gen(&mut rng); // Deterministic key generation from seed let seed = [0u8; 32]; let keypair = MlDsa65::from_seed(&seed.into()); // Access keys let signing_key: &SigningKey = &keypair; let verifying_key: VerifyingKey = keypair.verifying_key(); // Sign a message (deterministic) let message = b"Hello, quantum-resistant world!"; let signature: Signature = signing_key.sign(message); // Sign with context string let ctx = b"application context"; let signature = signing_key.signing_key() .sign_deterministic(message, ctx) .expect("signing failed"); // Verify signature assert!(verifying_key.verify(message, &signature).is_ok()); // Verify with context assert!(verifying_key.verify_with_context(message, ctx, &signature)); // Encode/decode keys and signatures let vk_bytes = verifying_key.encode(); let vk_restored = VerifyingKey::::decode(&vk_bytes); let sig_bytes = signature.encode(); let sig_restored = Signature::::decode(&sig_bytes).unwrap(); // Available parameter sets: // - MlDsa44: Security category 2 (2420-byte signatures) // - MlDsa65: Security category 3 (3309-byte signatures) // - MlDsa87: Security category 5 (4627-byte signatures) ``` -------------------------------- ### Implement Ed25519 Signatures Source: https://context7.com/rustcrypto/signatures/llms.txt Covers Ed25519 signature creation, component access, and generic signing patterns. ```rust use ed25519::{Signature, SignatureBytes, ComponentBytes}; // Create signature from 64-byte array let sig_bytes: SignatureBytes = [0u8; 64]; let signature = Signature::from_bytes(&sig_bytes); // Create from byte slice let slice: &[u8] = &[0u8; 64]; let signature = Signature::from_slice(slice) .expect("invalid signature length"); // Create from R and s components let R: ComponentBytes = [0u8; 32]; // R component let s: ComponentBytes = [0u8; 32]; // s component let signature = Signature::from_components(R, s); // Access signature components let r_bytes: &ComponentBytes = signature.r_bytes(); let s_bytes: &ComponentBytes = signature.s_bytes(); // Serialize signature let bytes: SignatureBytes = signature.to_bytes(); let vec = signature.to_vec(); // requires "alloc" feature // Generic signing with ed25519-dalek backend use ed25519::signature::{Signer, Verifier}; pub struct MessageSigner> { pub signing_key: S } impl> MessageSigner { pub fn sign(&self, msg: &[u8]) -> ed25519::Signature { self.signing_key.sign(msg) } } ``` -------------------------------- ### Signature Encoding and Serialization Source: https://context7.com/rustcrypto/signatures/llms.txt Provides methods for encoding and serializing signatures using `SignatureEncoding`. Supports fixed-size byte arrays, `Vec`, ASN.1 DER encoding, and integrates with `serde` for JSON serialization and `pkcs8` for private key encoding via feature flags. ```rust use signature::SignatureEncoding; // Fixed-size encoding (IEEE P1363 for ECDSA) let sig_bytes = signature.to_bytes(); // Returns fixed-size array let sig_vec = signature.to_vec(); // Returns Vec // ASN.1 DER encoding (for ECDSA) let der_sig = signature.to_der(); let signature = Signature::from_der(&der_bytes)?; // Serde support (requires "serde" feature) #[cfg(feature = "serde")] { let json = serde_json::to_string(&signature)?; let sig: Signature<_> = serde_json::from_str(&json)?; } // PKCS#8 key encoding (requires "pkcs8" feature) use pkcs8::{EncodePrivateKey, DecodePrivateKey, LineEnding}; let pem = signing_key.to_pkcs8_pem(LineEnding::LF)?; let der = signing_key.to_pkcs8_der()?; let restored = SigningKey::from_pkcs8_pem(&pem)?; ``` -------------------------------- ### Generate and Verify SLH-DSA Signatures Source: https://context7.com/rustcrypto/signatures/llms.txt Demonstrates stateless hash-based signing, including randomized and context-aware variants for SLH-DSA (SPHINCS+). ```rust use slh_dsa::{ SigningKey, VerifyingKey, Signature, Shake128f, Shake128s, Shake256f, Shake256s, Sha2_128f, Sha2_128s, Sha2_256f, Sha2_256s, }; use signature::{Signer, Verifier, RandomizedSigner}; // Generate a signing key using SHAKE128f parameter set let mut rng = rand::rng(); let signing_key = SigningKey::::new(&mut rng); // Get the corresponding verifying key let verifying_key = signing_key.verifying_key(); // Serialize the verifying key let vk_bytes = verifying_key.to_bytes(); // Sign a message (deterministic) let message = b"Hello, stateless signatures!"; let signature = signing_key.sign(message); // Sign with randomness let signature = signing_key.sign_with_rng(&mut rng, message); // Sign with context let ctx = b"my application"; let signature = signing_key.try_sign_with_context(message, ctx, None) .expect("signing failed"); // Verify signature assert!(verifying_key.verify(message, &signature).is_ok()); // Verify with context verifying_key.try_verify_with_context(message, ctx, &signature) .expect("verification failed"); // Deserialize a verifying key let vk_restored: VerifyingKey = vk_bytes.try_into().unwrap(); // Available parameter sets (FIPS-205): // SHAKE-based: Shake128f, Shake128s, Shake256f, Shake256s // SHA2-based: Sha2_128f, Sha2_128s, Sha2_256f, Sha2_256s // 'f' = fast (larger signatures), 's' = small (slower) // Signature sizes range from ~7KB to ~49KB depending on parameter set ``` -------------------------------- ### Generate Deterministic k for ECDSA/DSA Source: https://context7.com/rustcrypto/signatures/llms.txt Implements deterministic generation of the ephemeral scalar 'k' for DSA and ECDSA signatures using RFC 6979. This avoids the need for a random number generator for 'k', ensuring reproducible signatures. Requires the secret key, the field modulus, and the message hash. ```rust use rfc6979::{generate_k, consts::U32, HmacDrbg}; use sha2::{Sha256, Digest}; use hex_literal::hex; // NIST P-256 field modulus const NIST_P256_MODULUS: [u8; 32] = hex!( "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551" ); // Secret key (32 bytes for P-256) let secret_key: [u8; 32] = hex!( "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721" ); // Hash the message let message = b"sample"; let hash = Sha256::digest(message); // Generate deterministic k let additional_data = b""; // Optional additional authenticated data let k = generate_k::( &secret_key.into(), &NIST_P256_MODULUS.into(), &hash.into(), additional_data ); // For dynamic-sized inputs, use generate_k_mut let mut k_output = [0u8; 32]; rfc6979::generate_k_mut::( &secret_key, &NIST_P256_MODULUS, &hash, additional_data, &mut k_output ); // Low-level HMAC_DRBG access let mut drbg = HmacDrbg::::new( &secret_key, // entropy_input &hash, // nonce additional_data // personalization_string ); let mut random_bytes = [0u8; 32]; drbg.fill_bytes(&mut random_bytes); ``` -------------------------------- ### ECDSA Recovery ID for Public Key Recovery Source: https://context7.com/rustcrypto/signatures/llms.txt Utilizes the `RecoveryId` from the `ecdsa` crate to recover the public key from an ECDSA signature. This is particularly useful in blockchain applications where the public key is not explicitly transmitted with the signature. Demonstrates creating, checking properties, and converting `RecoveryId`. ```rust use ecdsa::{RecoveryId, Signature, SigningKey, VerifyingKey}; use p256::NistP256; use signature::hazmat::PrehashSigner; // RecoveryId encodes which of the possible public keys // was used to create the signature let recovery_id = RecoveryId::new(false, false); // (is_y_odd, is_x_reduced) // Check recovery ID properties let is_y_odd: bool = recovery_id.is_y_odd(); let is_x_reduced: bool = recovery_id.is_x_reduced(); // Convert to/from u8 let id_byte: u8 = recovery_id.into(); let recovery_id = RecoveryId::try_from(id_byte).expect("invalid recovery ID"); // In signing with recovery (using hazmat module) use ecdsa::hazmat::sign_prehashed_rfc6979; let signing_key = SigningKey::::generate_from_rng(&mut rand_core::OsRng); let prehash = [0u8; 32]; // SHA-256 hash of message // sign_prehashed_rfc6979 returns (signature, recovery_id) // This allows recovering the public key from the signature ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.