# Public Key Signatures

Public key signatures with EdDSA.

## Synopsis

```
#include <monocypher.h>
void crypto_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 the introduction 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.

`signature`

and `message`

may overlap.

`crypto_sign_public_key()`

computes the public key of the specified
secret key.

`crypto_sign()`

signs a message with `secret_key`

. The public key is
optional, and will be recomputed if not provided. This recomputation
doubles the execution time.

`crypto_check()`

checks that a given signature is genuine. Meaning,
only someone who had the private key could have signed the message.
**It does not run in constant time**. It does not have to in most
threat models, because nothing is secret: everyone knows the public key,
and the signature and message are rarely secret. If the message needs
to be secret, use key exchange instead.

An incremental interface is available.

## Return values

`crypto_sign_public_key()`

and `crypto_sign()`

return nothing.

`crypto_check()`

returns 0 for legitimate messages and -1 for forgeries.

## Examples

Generate a public key from a random secret key:

```
const uint8_t sk[32]; /* Random secret key */
uint8_t pk[32]; /* Matching public key */
crypto_sign_public_key(pk, sk);
/* Wipe the secret key if it is no longer needed */
crypto_wipe(sk, 32);
```

Sign a message:

```
const uint8_t sk [ 32]; /* Your secret key */
const uint8_t pk [ 32]; /* Matching public key */
const uint8_t message [500]; /* Message to sign */
uint8_t signature[ 64];
crypto_sign(signature, sk, pk, message, 500);
/* Wipe the secret key if it is no longer needed */
crypto_wipe(sk, 32);
```

Check the above:

```
const uint8_t pk [ 32]; /* Their public key */
const uint8_t message [500]; /* Signed message */
const uint8_t signature[ 64]; /* Signature to check */
if (crypto_check(signature, pk, message, 500)) {
/* Message is corrupted, abort processing */
} else {
/* Message is genuine */
}
```

## Standards

These functions implement EdDSA with Curve25519 and Blake2b. This is the same as Ed25519, with Blake2b instead of SHA-512. Ed25519 is described in RFC 7748.

## Security considerations

### Signature malleability

EdDSA signatures are not unique like cryptographic hashes. For any given public key and message, there are many possible valid signatures. Some of them require knowledge of the private key. Others only require knowledge of an existing signature. Observing a valid signature only proves that someone with knowledge of the private key signed the document at some point. Do not rely on any other security property.

### Fault injection

Fault injection (also known as glitching) 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 the relevant equipment, use `crypto_check()`

to verify the signature
before sending it away. This verification reduces the speed of the
whole operation by a factor of 3, and only provides an incomplete
protection.