Compute digital signatures

RecipeCratesCategories
ed25519ed25519-websitecat-cryptography
ed25519-daleked25519-dalek-websitecat-cryptography
ecdsaecdsacat-cryptography
dsadsacat-cryptography

A cryptographic signature, or digital signature, is a mathematical scheme used to validate the authenticity and integrity of a message, software, or digital document. It is like a tamper-evident seal that assures the recipient that the message hasn't been altered and confirms the sender's identity.

  • First, a key pair is generated: a private key and a public key. The private key is kept secret, while the public key is shared.
  • When the sender wants to sign a message, they create a hash (a fixed-size string of characters) of the message using a hash function. This hash is then encrypted with the sender's private key, creating the digital signature.
  • The recipient decrypts the digital signature using the sender's public key to obtain the original hash.
  • The recipient also generates their own hash of the received message using the same hash function.
  • If both hashes match, the recipient can be confident that the message has not been altered and that it was indeed signed by the sender.

ed25519

ed25519-website ed25519 ed25519-crates.io ed25519-github ed25519-lib.rs cat-cryptography cat-no-std

The ed25519 crate is a support library for Edwards Digital Signature Algorithm (EdDSA) over Curve25519 (as specified in RFC 8032), providing signature type definitions and PKCS#8 private key decoding/encoding support.

It doesn't contain an implementation of Ed25519, but instead contains an ed25519::Signature type which other crates can use in conjunction with the signature::Signer and signature::Verifier traits.

// // COMING SOON

ed25519-dalek

ed25519-dalek-website ed25519-dalek ed25519-dalek-crates.io ed25519-dalek-github ed25519-dalek-lib.rs cat-cryptography cat-no-std

ed25519-dalek contains ed25519 EdDSA key generation, signing, and verification algorithms in pure Rust.

A key pair, consisting of a private key and a public key, is generated. The private key is kept secret, while the public key is shared with others. To sign a message, a hash of the message is created. This hash is then signed using the private key, producing the digital signature. The recipient uses the sender's public key to verify the signature. If the signature is valid, it confirms that the message is authentic and has not been altered.

ed25519-dalek is compatible with no_std environments, making it suitable for embedded systems or situations where the standard library is not available.

use ed25519_dalek::Signature;
use ed25519_dalek::Signer;
use ed25519_dalek::SigningKey;
use ed25519_dalek::Verifier;
use ed25519_dalek::VerifyingKey;
use rand::rngs::OsRng;

// `ed25519` key generation, signing, and verification.

fn main() -> anyhow::Result<()> {
    // First, we need to generate a Keypair, which includes both public and
    // secret halves of an asymmetric key. To do so, we need a
    // cryptographically secure pseudorandom number generator (CSPRNG).
    // For this example, we'll use the operating system's builtin PRNG:

    let mut csprng = OsRng;
    let signing_key: SigningKey = SigningKey::generate(&mut csprng);

    // Message to be signed
    let message = b"Hello, world!";

    // Sign the message
    let signature: Signature = signing_key.sign(message);

    // Verify the signature
    assert!(signing_key.verify(message, &signature).is_ok());

    // Anyone else, given the public half of the signing_key can also easily
    // verify this signature:

    let verifying_key: VerifyingKey = signing_key.verifying_key();
    assert!(verifying_key.verify(message, &signature).is_ok());

    // VerifyingKeys, SecretKeys, SigningKeys, and Signatures can be
    // serialised into byte-arrays by calling `to_bytes`.

    Ok(())
}

ecdsa

ecdsa-website ecdsa ecdsa-crates.io ecdsa-github ecdsa-lib.rs cat-cryptography cat-no-std

ECDSA (Elliptic Curve Digital Signature Algorithm) is a widely used digital signature scheme that leverages the properties of elliptic curve cryptography. It is a variant of the Digital Signature Algorithm (DSA) that offers the same level of security with smaller key sizes, compared to DSA and RSA.

ecdsa contains a pure Rust implementation of ECDSA, as specified in FIPS 186-4 (Digital Signature Standard), providing RFC6979 deterministic signatures as well as support for added entropy.

// // Elliptic Curve Digital Signature Algorithm (ECDSA) as specified in FIPS
// 186-4 // (Digital Signature Standard). https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
// // - A pair of private and public keys are created: data encrypted with
// either //   key can only be decrypted with the other.
// // - A signing entity that published their public key can generate an
// encrypted //   signature
// //  using their private key, and a verifier can assert the source if it is
// // decrypted correctly using the declared public key.

// // The `ecdsa` crate crate provides generic ECDSA support, which can be used
// // with the `k256`, `p256`, `p384` crates. For this example, add to your
// // `Cargo.toml`:
// // p256 = { version = "0.13.2" } # or latest

// use p256::SecretKey;
// use p256::ecdsa::Signature;
// use p256::ecdsa::SigningKey;
// use p256::ecdsa::VerifyingKey;
// use p256::ecdsa::signature::Signer;
// use p256::ecdsa::signature::Verifier;
// // An interface over the operating-system's random data source
// use p256::elliptic_curve::rand_core::OsRng;

// // Serialize a private key object to a PKCS#8 encoded document.
// // (Public-Key Cryptography Standards (PKCS) #8)
// use p256::pkcs8::EncodePrivateKey;

// fn main() {
//     // 1. Generate a random secret key
//     let secret_key = SecretKey::random(&mut OsRng);

//     // 2. Derive public key
//     let public_key = PublicKey::from(&secret_key);

//     // 3. Encode the secret key to PKCS#8 format (for storage/transmission)
//     // PKCS#8 is a format for cryptographic private keys, often containing
// pairs of private and public keys.     let private_key_der =
// secret_key.to_pkcs8()?;     // Get it in PEM format. The PEM text encoding is
// a Base64 representation.     let private_key_pem = private_key_der.to_pem()?;
//     // In a real world application, never print or store private keys in
// plain     // text!
//     println!("Private Key (PEM):\n{}\n", private_key_pem);

//     // 4. Create a message to sign
//     let message = b"Hello, world!";

//     // 5. Sign the message using the secret key
//     let signature: Signature = secret_key.ecdsa_sign(message);
//     // Print the signature in hex format
//     println!("Signature: {:x?}", signature);

//     // 6. Verify the signature using the public key
//     assert!(public_key.verify(message, &signature).is_ok());
//     println!("Message signature verified successfully");
// }

dsa

dsa-website dsa dsa-crates.io dsa-github dsa-lib.rs cat-cryptography cat-no-std

DSA (Digital Signature Algorithm) is a Federal Information Processing Standard (FIPS) for digital signatures. It's a public-key cryptosystem used for creating digital signatures, which provide authentication and integrity for digital data. While once widely used, DSA has been superseded by algorithms like ECDSA and Ed25519 due to factors like key size and performance.

dsa is a pure Rust implementation of the Digital Signature Algorithm (DSA) as specified in FIPS 186-4 (Digital Signature Standard), providing RFC6979 deterministic signatures as well as support for added entropy.

use p256::ecdsa::Signature;
use p256::ecdsa::SigningKey;
use p256::ecdsa::VerifyingKey;
use p256::ecdsa::signature::Signer;
use p256::ecdsa::signature::Verifier;
use p256::elliptic_curve::rand_core::OsRng;

fn main() {
    // Generate a signing key
    let signing_key = SigningKey::random(&mut OsRng);

    // Create a verifying key from the signing key
    let verifying_key = VerifyingKey::from(&signing_key);

    // Message to be signed
    let message = b"Hello, world!";

    // Sign the message
    let signature: Signature = signing_key.sign(message);

    // Verify the signature
    assert!(verifying_key.verify(message, &signature).is_ok());
    println!("Message signature verified successfully");

    // Print the signature in hex format
    println!("Signature: {:x?}", signature);
}

For more algorithms, see Rust Crypto Signatures:

  • ed25519. Use in conjunction with the ed25519-dalek crate.
  • ecdsa
  • dsa