CRYPTO_SIGN(3MONOCYPHER) | 3MONOCYPHER | CRYPTO_SIGN(3MONOCYPHER) |
NAME
public key signatures #include <monocypher.h> voidcrypto_sign_public_key(uint8_t public_key[32], const uint8_t secret_key[32]); void
crypto_sign(uint8_t signature[64], const uint8_t secret_key[32], const uint8_t public_key[32], const uint8_t *message, size_t message_size); int
crypto_check(const uint8_t signature[64], const uint8_t public_key[32], const uint8_t *message, size_t message_size);
DESCRIPTION
crypto_sign() and crypto_check() provide EdDSA public key signatures and verification. The arguments are:- signature
- The signature.
- secret_key
- A 32-byte random number, known only to you. See intro() about random number generation (use your operating system's random number generator). Do not use the same private key for both signatures and key exchanges. The public keys are different, and revealing both may leak information.
- public_key
- The public key, generated from secret_key with crypto_sign_public_key().
- message
- Message to sign.
- message_size
- Length of message, in bytes.
RETURN VALUES
crypto_sign_public_key() and crypto_sign() return nothing. crypto_check() returns 0 for legitimate messages and -1 for forgeries.EXAMPLES
The following examples assume the existence of arc4random_buf(), which fills the given buffer with cryptographically secure random bytes. If arc4random_buf() does not exist on your system, see intro() for advice about how to generate cryptographically secure random bytes. Generate a public key from a random secret key:uint8_t sk[32]; /* Random secret key */ uint8_t pk[32]; /* Matching public key */ arc4random_buf(sk, 32); crypto_sign_public_key(pk, sk); /* Wipe the secret key if it is no longer needed */ crypto_wipe(sk, 32);
uint8_t sk [32]; /* Secret key from above */ const uint8_t pk [32]; /* Matching public key */ const uint8_t message [11] = "Lorem ipsu"; /* Message to sign */ uint8_t signature[64]; crypto_sign(signature, sk, pk, message, 10); /* Wipe the secret key if it is no longer needed */ crypto_wipe(sk, 32);
const uint8_t pk [32]; /* Their public key */ const uint8_t message [11] = "Lorem ipsu"; /* Signed message */ const uint8_t signature[64]; /* Signature to check */ if (crypto_check(signature, pk, message, 10)) { /* Message is corrupted, abort processing */ } else { /* Message is genuine */ }
SEE ALSO
crypto_blake2b(), crypto_key_exchange(), crypto_lock(), intro()STANDARDS
These functions implement PureEdDSA with Curve25519 and Blake2b, as described in RFC 8032. This is the same as Ed25519, with Blake2b instead of SHA-512.HISTORY
The crypto_sign(), crypto_check(), and crypto_sign_public_key() functions appeared in Monocypher 0.2. Starting with Monocypher 2.0.5, modified signatures abusing the inherent signature malleability property of EdDSA now cause a non-zero return value of crypto_check(); in prior versions, such signatures would be accepted. A critical security vulnerability that caused all-zero signatures to be accepted was introduced in Monocypher 0.3; it was fixed in Monocypher 1.1.1 and 2.0.4.SECURITY CONSIDERATIONS
Signature malleability
Signature malleability is the ability of an attacker to produce a valid signature with knowledge of only an existing signature and the public key. That is, given a message, a signature and a public key, an attacker could generate a new signature for the same message that is valid under the same public key. Monocypher prevents signature malleability by only accepting signatures in canonical form. On the other hand, EdDSA signatures are not unique like cryptographic hashes. The signing procedure is deterministic by specification and crypto_sign() follows this specification. However, someone with the private key can generate arbitrarily many valid, canonical, different signatures of the same message. Because of this, never assume that signatures are unique.Fault injection and power analysis
Fault injection (also known as glitching) and power analysis may be used to manipulate the resulting signature and recover the secret key in some cases. This requires hardware access. If attackers are expected to have such access and have the relevant equipment, you may try use the incremental interface provided by crypto_sign_init_first_pass() to mitigate the side channel attacks. Note that there may still be other power-related side channels (such as if the CPU leaks information when an operation overflows a register) that must be considered.September 26, 2020 | Linux 4.15.0-46-generic |