Geralt
  • Introduction
  • Random data
  • Constant time
  • Secure memory
  • Encoding
  • Padding
  • Hashing
  • Message authentication
  • Password hashing
  • Key derivation
  • Authenticated encryption
    • Stream and file encryption
    • AEGIS-128L
    • AEGIS-256
    • ChaCha20-Poly1305
    • XChaCha20-Poly1305
  • Key exchange
  • Digital signatures
  • Advanced
    • Validation
    • Concat
    • ChaCha20
    • XChaCha20
    • HChaCha20
    • Poly1305
    • Ed25519 to X25519
Powered by GitBook
On this page
  • Purpose
  • Usage
  • GenerateKeyPair
  • GenerateKeyPair
  • ComputePublicKey
  • Sign
  • Verify
  • IncrementalEd25519ph
  • Constants
  • Notes

Digital signatures

Last updated 6 months ago

Purpose

A digital signature verifies the authenticity of a message and provides non-repudiation. This means any change to the message causes signature verification to fail, you know who signed the message, and someone cannot deny having signed a message.

Signing is done using a private key. The associated public key can then be publicly shared to allow others to verify signatures.

Private keys MUST NOT be shared. They MUST remain secret.

Generally, avoid using signatures with encryption and instead rely on authenticated . You can find out more .

Usage

GenerateKeyPair

Fills a span with a randomly generated private key and another span with the associated public key.

Ed25519.GenerateKeyPair(Span<byte> publicKey, Span<byte> privateKey)

Exceptions

publicKey has a length not equal to PublicKeySize.

privateKey has a length not equal to PrivateKeySize.

Unable to generate key pair.

GenerateKeyPair

Ed25519.GenerateKeyPair(Span<byte> publicKey, Span<byte> privateKey, ReadOnlySpan<byte> seed)

Exceptions

publicKey has a length not equal to PublicKeySize.

privateKey has a length not equal to PrivateKeySize.

seed has a length not equal to SeedSize.

Unable to generate key pair from seed.

ComputePublicKey

Fills a span with the public key computed from a private key.

Ed25519.ComputePublicKey(Span<byte> publicKey, ReadOnlySpan<byte> privateKey)

Exceptions

publicKey has a length not equal to PublicKeySize.

privateKey has a length not equal to PrivateKeySize.

Unable to compute public key from private key.

Sign

Fills a span with the signature for a message signed using a private key.

Ed25519.Sign(Span<byte> signature, ReadOnlySpan<byte> message, ReadOnlySpan<byte> privateKey)

Exceptions

signature has a length not equal to SignatureSize.

privateKey has a length not equal to PrivateKeySize.

Unable to compute signature.

Verify

Determines if a signature is valid for a message and public key. It returns true if the signature is valid and false otherwise.

Ed25519.Verify(ReadOnlySpan<byte> signature, ReadOnlySpan<byte> message, ReadOnlySpan<byte> publicKey)

Exceptions

signature has a length not equal to SignatureSize.

publicKey has a length not equal to PublicKeySize.

IncrementalEd25519ph

IncrementalEd25519ph.Finalize() fills a span with the signature for a chunked message signed using a private key.

IncrementalEd25519ph.FinalizeAndVerify() determines if a signature is valid for a chunked message and public key. It returns true if the signature is valid and false otherwise.

using var ed25519ph = new IncrementalEd25519ph();
ed25519ph.Update(ReadOnlySpan<byte> message1);
ed25519ph.Update(ReadOnlySpan<byte> message2);
// Sign
ed25519ph.Finalize(Span<byte> signature, ReadOnlySpan<byte> privateKey);
// Or verify
bool valid = ed25519ph.FinalizeAndVerify(ReadOnlySpan<byte> signature, ReadOnlySpan<byte> publicKey)

// Avoid another using statement
ed25519ph.Reinitialize();
ed25519ph.Update(ReadOnlySpan<byte> message3);
ed25519ph.Finalize(Span<byte> signature, ReadOnlySpan<byte> privateKey);

Exceptions

signature has a length not equal to SignatureSize.

privateKey has a length not equal to PrivateKeySize.

publicKey has a length not equal to PublicKeySize.

The signature could not be computed.

Cannot update after finalizing or finalize twice (without reinitializing).

The object has been disposed.

Constants

These are used for validation and/or save you defining your own constants.

public const int PublicKeySize = 32;
public const int PrivateKeySize = 64;
public const int SignatureSize = 64;
public const int SeedSize = 32;

Notes

Fills a span with a private key generated using a seed and another span with the associated public key.

Provides support for computing/verifying a signature from a sequence of messages using .

This should only be used when the message is too large to fit into memory because prehashing is than regular signing.

If you want to use for prehashing instead of Ed25519ph, which uses SHA-512 internally, you can hash a domain separation constant (e.g. the protocol name) concatenated with the message and sign the 512-bit hash.

If you want to support prehashing as well as non-prehashed Ed25519 like in /, you MUST sign some data indicating whether prehashing was used or not. Otherwise, it may be to create a forgery.

Ed25519 is vulnerable to . Techniques like causing on a chip (e.g. on an Arduino) can be used to recover the secret key and create valid signatures.

This should generally not concern you as it's mostly relevant for embedded devices and requires physical or remote access to the device. Furthermore, most countermeasures are ineffective. Prehashing or can help but will not prevent all attacks.

key exchange
here
ArgumentOutOfRangeException
ArgumentOutOfRangeException
CryptographicException
random
ArgumentOutOfRangeException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
CryptographicException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
CryptographicException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
CryptographicException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
Ed25519ph
theoretically weaker
ArgumentOutOfRangeException
ArgumentOutOfRangeException
ArgumentOutOfRangeException
CryptographicException
InvalidOperationException
ObjectDisposedException
BLAKE2b
Kryptor
Minisign
possible
fault attacks
voltage glitches
hedged signatures