.Sh SYNOPSIS
.In monocypher.h
.Ft void
+.Ft void
+.Fo crypto_sign_public_key
+.Fa "uint8_t public_key[32]"
+.Fa "const uint8_t secret_key[32]"
+.Fc
.Fo crypto_sign
.Fa "uint8_t signature[64]"
.Fa "const uint8_t secret_key[32]"
.Fa "const uint8_t *message"
.Fa "size_t message_size"
.Fc
-.Ft void
-.Fo crypto_sign_public_key
-.Fa "uint8_t public_key[32]"
-.Fa "const uint8_t secret_key[32]"
-.Fc
.Ft int
.Fo crypto_check
.Fa "const uint8_t signature[64]"
.Fa "size_t message_size"
.Fc
.Sh DESCRIPTION
-Authenticated encryption with key exchange is not always enough.
-Sometimes, you want to
-.Em broadcast
-a signature, in such a way that
-.Em everybody
-can verify.
-.Pp
-When you sign a message with your private key, anybody who knows your
-public key can verify that you signed the message.
-Obviously, any attacker that gets a hold of your private key can sign
-messages in your stead.
-Protect your private key.
-.Pp
-The keys used for these functions are
-.Em not
-the same as used for
-.Xr crypto_key_exchange 3monocypher .
-There are ways to convert keys from signing keys to X25519 keys,
-but those are not covered by Monocypher.
-.Pp
The
.Fn crypto_sign_public_key
function deterministically computes a public key from the specified
secret key.
-Make sure the secret key is randomly selected.
-Refer to
+That key must be random.
+See
.Xr intro 3monocypher
-for details about random number generation (use your operating system's
-random number generator).
+about random number generation (use your operating system's random
+number generator).
+The key pairs generated here are
+.Em not
+the same as those used for
+.Xr crypto_key_exchange 3monocypher .
+Do not use the same private key for both purposes.
.Pp
The
.Fn crypto_sign
-function signs a message with your secret key
+function signs a message with
.Fa secret_key .
The public key is optional, and will be recomputed if not provided.
-However, this doubles execution time.
+This doubles execution time.
.Pp
The
.Fn crypto_check
function checks that a given signature is genuine.
-Of course, if an attacker gets a hold of the matching private key,
-no security guarantees can be made anymore.
-This function does
+Meaning, only someone who had the private key could have signed the
+message.
+.Pp
+It does
.Em 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 you want to ascertain the origin of a secret message, you may want
-to use the
+To ascertain the origin of a secret message, use
.Xr crypto_key_exchange 3monocypher
-function instead.
+instead.
.Pp
The
.Fa signature
.Fn crypto_check
function returns zero for legitimate messages and -1 for forgeries.
.Sh EXAMPLES
-This example shows how to generate a private key and a public key.
+Generate a public key from a random secret key:
.Bd -literal -offset indent
-uint8_t sk[32], pk[32];
-
-/* ...randomly generate sk here... */
+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);
+.Ed
+.Pp
+Sign a message:
+.Bd -literal -offset indent
+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);
+.Ed
+.Pp
+Check the above:
+.Bd -literal -offset indent
+const uint8_t pk [ 32]; /* their public key */
+const uint8_t message [500]; /* signed message */
+const uint8_t signature[ 64]; /* signature to check */
+crypto_check(signature, pk, message, 500);
.Ed
.Sh SEE ALSO
.Xr crypto_blake2b 3monocypher ,
.Xr crypto_key_exchange 3monocypher ,
.Xr crypto_lock 3monocypher ,
.Xr intro 3monocypher
-.Sh CAVEATS
+.Sh 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.
+.Sh SECURITY CONSIDERATIONS
Fault injection (also known as glitching) may be used to manipulate the
-resulting signature.
+resulting signature and recover the secret key in some cases.
This requires hardware access.
-If your threat model includes attackers that have the equipment for
-fault injection and access to the hardware, you will want to use the
+If attackers are expected to have such access and the relevant
+equipment, use
.Fn crypto_check
-function to verify the signature that was just generated.
-Including a verification step when signing reduces speed for the whole
-operation by a factor of 3.
-This speed penalty is generally not noticeable unless creating a high
-number of signatures per second.
-If an attacker can inject faults at will, however, this is an incomplete
-protection, albeit better than none.
-.Sh IMPLEMENTATION DETAILS
-These functions provide public key signatures with a variant of Ed25519,
-which uses Blake2b as the hash instead of SHA-512.
-SHA-512 is provided as an option for compatibility with other systems.
-.Pp
-Blake2b is the default because it is faster, more flexible, harder to
-misuse than SHA-512, and already required by
-.Xr crypto_argon2i 3monocypher .
-Monocypher needs only one hash function, and that shall be Blake2b.
-.Pp
-Note that using Blake2b instead of SHA-512 does
-.Em not
-block your upgrade path to faster implementations: Floodyberry's Donna
-(ed25519-donna) library provides blazing fast implementations that can
-work with custom hashes.
-.Pp
-The reason why there is a SHA-512 option at all is due to official test
-vectors.
+to verify the signature.
+This verification reduces the speed of the whole operation by a factor
+of 3, and only provides an incomplete protection.