Public-key signatures
Example (combined mode)
const string MESSAGE = "test";
var keyPair = PublicKeyAuth.GenerateKeyPair(); //64 byte private key | 32 byte public key
//sign the message
var signedMessage = PublicKeyAuth.Sign(MESSAGE, keyPair.PrivateKey);
//get the unsigned message again
var unsigendMessage = PublicKeyAuth.Verify(signedMessage, keyPair.PublicKey);
Example (detached mode)
const string MESSAGE = "test";
var keyPair = PublicKeyAuth.GenerateKeyPair(); //64 byte private key | 32 byte public key
//get a signature for the message
var signature = PublicKeyAuth.SignDetached(MESSAGE, keyPair.PrivateKey);
//check the signature for the message
if (PublicKeyAuth.VerifyDetached(signature, MESSAGE, keyPair.PublicKey))
{
//message ok
}
Purpose
In this system, a signer generates a key pair:
- a secret key, that will be used to append a seal to any number of messages
- a public key, that anybody can use to verify that the seal appended to a message was actually issued by the creator of the public key.
Verifiers need to already know and ultimately trust a public key before messages sealed using it can be verified.
Warning: this is different from authenticated encryption. Appending a seal does not change the representation of the message itself.
Random Helpers
public static KeyPair GenerateKeyPair()
Namespace: Sodium.PublicKeyAuth
Uses Sodium.SodiumCore.GetRandomBytes() to generate a key pair based on a random seed.
public static KeyPair GenerateKeyPair(byte[] privateKey)
Namespace: Sodium.PublicKeyAuth
Uses Sodium.SodiumCore.GetRandomBytes() to generate a key pair based on the provided private key.
The privateKey seed must be 32 bytes, otherwise the function throws a SeedOutOfRangeException.
libsodium-net KeyPair
Combined mode
In combined mode, the signature is stored with a copy of the original message to it.
Sign
public static byte[] Sign(byte[] message, byte[] key)
//there exists an overloaded version:
public static byte[] Sign(string message, byte[] key)
This is the .NET equivalent of crypto_sign.
Namespace: Sodium.PublicKeyAuth
The Sign() function prepends a seal to a message using the secret key key.
The key must be 64 bytes, otherwise the function throws a KeyOutOfRangeException.
The function returns a byte array (signed message).
Verify
public static byte[] Verify(byte[] signedMessage, byte[] key)
This is the .NET equivalent of crypto_sign_open.
Namespace: Sodium.PublicKeyAuth
The Verify() function checks that the signedMessage has a valid seal for the public key key.
The key must be 32 bytes, otherwise the function throws a KeyOutOfRangeException.
The function returns a byte array (message without signature) on success, otherwise it throws a CryptographicException.
Detached mode
In detached mode, the signature is stored without attaching a copy of the original message to it.
Sign
public static byte[] SignDetached(byte[] message, byte[] key)
//there exists an overloaded version:
public static byte[] SignDetached(string message, byte[] key)
This is the .NET equivalent of crypto_sign_detached.
Namespace: Sodium.PublicKeyAuth
The SignDetached() function prepends a seal to a message using the secret key key.
The key must be 64 bytes, otherwise the function throws a KeyOutOfRangeException.
The function returns a byte array (signature without message).
Verify
public static bool VerifyDetached(byte[] signature, byte[] message, byte[] key)
This is the .NET equivalent of crypto_sign_verify_detached.
Namespace: Sodium.PublicKeyAuth
The VerifyDetached() function checks that the message has a valid seal signature for the public key key.
The key must be 32 bytes, otherwise the function throws a KeyOutOfRangeException.
The signature must be 64 bytes, otherwise the function throws a SignatureOutOfRangeException.
The function returns true on success, otherwise false.
Extracting from the secret key
The secret key actually includes the seed (either a random seed or the one given to GenerateKeyPair(byte[] privateKey)) as well as the public key.
While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.
If required, Sodium provides two functions to extract the seed and the public key from the secret key:
Extracting the seed from the secret key
public static byte[] ExtractEd25519SeedFromEd25519SecretKey(byte[] ed25519SecretKey)
This is the .NET equivalent of crypto_sign_ed25519_sk_to_seed.
Namespace: Sodium.PublicKeyAuth
Extracting the public key from the secret key
public static byte[] ExtractEd25519PublicKeyFromEd25519SecretKey(byte[] ed25519SecretKey)
This is the .NET equivalent of crypto_sign_ed25519_sk_to_pk.
Namespace: Sodium.PublicKeyAuth
Algorithm details
- Signature: Ed25519