--- /dev/null
+.Dd December 4, 2019
+.Dt CRYPTO_CHACHA20 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_chacha20 ,
+.Nm crypto_chacha20_ctr ,
+.Nm crypto_xchacha20 ,
+.Nm crypto_xchacha20_ctr
+.Nd Chacha20 and XChacha20 encryption functions
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_chacha20
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[8]"
+.Fc
+.Ft void
+.Fo crypto_xchacha20
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[24]"
+.Fc
+.Ft uint64_t
+.Fo crypto_chacha20_ctr
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[8]"
+.Fa "uint64_t ctr"
+.Fc
+.Ft uint64_t
+.Fo crypto_xchacha20_ctr
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[24]"
+.Fa "uint64_t ctr"
+.Fc
+.Sh DESCRIPTION
+These functions provide an interface for the Chacha20 encryption
+primitive.
+.Pp
+Chacha20 is a low-level primitive.
+Consider using authenticated encryption, implemented by
+.Xr crypto_lock 3monocypher .
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa key
+A 32-byte secret key.
+.It Fa nonce
+An 8-byte or 24-byte number, used only once with any given key.
+It does not need to be secret or random, but it does have to be unique.
+Repeating a nonce with the same key reveals the XOR of two different
+messages, which allows decryption.
+24-byte nonces can be selected at random.
+8-byte nonces
+.Em cannot .
+They are too small, and the same nonce may be selected twice by
+accident.
+See
+.Xr intro 3monocypher
+for advice about generating random numbers (use the operating system's
+random number generator).
+.It Fa plain_text
+The message to encrypt.
+It is allowed to be
+.Dv NULL ,
+in which case it will be interpreted as an all zero input.
+.Fa cipher_text
+will then contain the raw Chacha20 stream.
+.It Fa cipher_text
+The encrypted message.
+.It Fa text_size
+Length of both
+.Fa plain_text
+and
+.Fa cipher_text ,
+in bytes.
+.It Fa ctr
+The number of 64-byte blocks since the beginning of the stream.
+.El
+.Pp
+The
+.Fa key
+and
+.Fa nonce
+buffers may overlap.
+.Fa plain_text
+and
+.Fa cipher_text
+must either be the same buffer (for in-place encryption), or
+non-overlapping.
+.Pp
+.Fn crypto_chacha20
+performs a Chacha20 operation.
+It uses an 8-byte nonce, which is too small to be selected at random.
+Use a message counter as a nonce instead.
+.Pp
+.Fn crypto_xchacha20
+performs an Chacha20 operation.
+It uses a 24-byte nonce, which is large enough to be selected at random.
+.Pp
+.Fn crypto_xchacha20
+is recommended over
+.Fn crypto_chacha20 .
+The ability to use random nonces makes it easier to use securely, and
+the performance hit is often negligible in practice.
+.Pp
+The
+.Fn crypto_chacha20
+and
+.Fn crypto_xchacha20
+encrypt
+.Fa plain_text
+by XORing it with a pseudo-random stream of
+numbers, seeded by the provided
+.Fa key
+and
+.Fa nonce .
+.Pp
+Since XOR is its own inverse, decryption is the same operation as
+encryption.
+To decrypt the cipher text,
+.Dq encrypt
+it again with the same key and nonce.
+You will likely want to wipe the key when you are done with
+encryption or decryption.
+Use
+.Xr crypto_wipe 3monocypher
+to wipe them.
+.Pp
+The
+.Fa plain_text
+pointer is allowed to be
+.Dv NULL ,
+in which case it will be interpreted as an all zero input.
+This is useful as a user space random number generator.
+While
+.Sy this should not be used as a random number generator for secrets ,
+for which the operating system random number generator should be
+preferred,
+it can be handy outside of a security context.
+Deterministic procedural generation and reproducible property-based
+tests come to mind.
+Additionally, it
+.Em can
+be used to generate large amounts of random-looking data quickly,
+for example to generate padding.
+.Pp
+The
+.Fn crypto_chacha20_ctr
+and
+.Fn crypto_xchacha20_ctr
+perform a Chacha20 or XChacha20 encryption, respectively,
+starting the stream at the block
+.Fa ctr
+(which is the byte
+.Ql ctr \(mu 64 ) .
+This can be used to encrypt (or decrypt) part of a long message, or to
+implement some AEAD constructions such as the one described in RFC
+8439.
+Be careful when using this not to accidentally reuse parts of the
+random stream as that would destroy confidentiality.
+.Sh RETURN VALUES
+.Fn crypto_chacha20
+and
+.Fn crypto_xchacha20
+return nothing.
+.Fn crypto_chacha20_ctr
+and
+.Fn crypto_xchacha20_ctr
+functions return the next
+.Fa ctr
+to use with the same key and nonce values;
+this is always
+.Fa text_size
+divided by 64;
+plus one if there was a remainder.
+.Sh EXAMPLES
+Simple encryption:
+.Bd -literal -offset indent
+const uint8_t key [ 32]; /* Secret random key */
+const uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
+const uint8_t plain_text [500]; /* Message to be encrypted */
+uint8_t cipher_text[500]; /* Will be the encrypted message */
+crypto_xchacha20_encrypt(cipher_text, plain_text, 500, key, nonce);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(plain_text, 500);
+.Ed
+.Pp
+To decrypt the above:
+.Bd -literal -offset indent
+const uint8_t key [ 32]; /* Same key as above */
+const uint8_t nonce [ 24]; /* Same nonce as above */
+const uint8_t cipher_text[500]; /* Encrypted message */
+uint8_t plain_text [500]; /* Will be the decrypted message */
+crypto_xchacha20_encrypt(cipher_text, plain_text, 500, key, nonce);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+/* The plain text likely needs to be processed before you wipe it */
+crypto_wipe(plain_text, 500);
+.Ed
+.Pp
+Incremental encryption (in blocks of 64 bytes):
+.Bd -literal -offset indent
+const uint8_t key [ 32]; /* Secret random key */
+const uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
+const uint8_t plain_text [500]; /* Message to be encrypted */
+uint8_t cipher_text[500]; /* Will be the encrypted message */
+uint64_t ctr; /* Block counter */
+for(int i = 0; i < 500; i += 64) {
+ ctr = crypto_xchacha20_ctr(&ctx, cipher_text+i, plain_text+i,
+ 64, ctr);
+}
+/* Process data that didn't fit into 64 byte pieces */
+crypto_xchacha20_ctr(&ctx,
+ cipher_text+500-(i-64),
+ plain_text+500-(i-64),
+ 500-(i-64), ctr);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(plain_text, 500);
+.Ed
+.Pp
+Encryption by jumping around (do not do that, this is only meant to show
+how
+.Fn crypto_xchacha20_ctr
+works):
+.Bd -literal -offset indent
+const uint8_t key [ 32]; /* Secret random key */
+const uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
+const uint8_t plain_text [500]; /* Message to be encrypted */
+uint8_t cipher_text[500]; /* Will be the encrypted message */
+/* Encrypt the second part of the message first... */
+crypto_chacha20(&ctx,
+ cipher_text + (3 * 64),
+ plain_text + (3 * 64),
+ 500 - (3 * 64),
+ key, nonce, 3);
+/* ...then encrypt the first part */
+crypto_chacha20(&ctx, cipher_text, plain_text, 3 * 64,
+ key, nonce, 0);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(plain_text, 500);
+.Ed
+.Sh SEE ALSO
+.Xr crypto_ietf_chacha20 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement Chacha20 and XChacha20.
+Chacha20 is described in:
+.Rs
+.%A Daniel J. Bernstein
+.%J SASC 2008 \(en The State of the Art of Stream Ciphers
+.%P pp. 273\(en278
+.%T ChaCha, a variant of Salsa20
+.Re
+The nonce and counter sizes were modified in RFC 8439.
+XChacha20 derives from Chacha20 the same way XSalsa20 derives from
+Salsa20, and benefits from the same security reduction (proven secure
+as long as Chacha20 itself is secure).
+.Sh HISTORY
+.Fn crypto_chacha20 ,
+.Fn crypto_chacha20_ctr ,
+.Fn crypto_xchacha20 ,
+and
+.Fn crypto_xchacha20_ctr
+were added in Monocypher 3.0.0.
+They replace
+.Fn crypto_chacha20_encrypt ,
+.Fn crypto_chacha20_init ,
+.Fn crypto_chacha20_stream ,
+.Fn crypto_chacha20_x_init ,
+and
+.Fn crypto_chacha20_set_ctr
+that were deprecated in Monocypher 3.0.0.
+.Sh SECURITY CONSIDERATIONS
+.Ss Encrypted does not mean secure
+Chacha20 only protects against eavesdropping, not forgeries.
+Most applications need protection against forgeries to be properly
+secure.
+To ensure the integrity of a message, use Blake2b in keyed mode, or
+authenticated encryption; see
+.Xr crypto_blake2b 3monocypher
+and
+.Xr crypto_lock 3monocypher .
+.Ss Nonce reuse
+Repeating a nonce with the same key exposes the XOR of two or more
+plain text messages, effectively destroying confidentiality.
+.Pp
+For the same reason,
+.Sy do not select small nonces at random .
+The
+.Fn crypto_chacha20
+nonce spans only 64 bits, which is small enough to trigger accidental
+reuses.
+A message counter should be used instead.
+If multiple parties send out messages, Each can start with an initial
+nonce of 0, 1 .. n-1 respectively, and increment them by n for each
+new message.
+Make sure the counters never wrap around.
+.Ss Secure random number generation
+Do not use these functions as a cryptographic random number generator.
+Always use the operating system's random number generator for
+cryptographic purposes, see
+.Xr intro 3monocypher .
+.Ss Protection against side channels
+Secrets should not dwell in memory longer than needed.
+Use
+.Xr crypto_wipe 3monocypher
+to erase secrets you no longer need.
+For Chacha20, this means the key and in some cases the
+plain text itself.
+++ /dev/null
-.Dd December 28, 2017
-.Dt CRYPTO_CHACHA20_H 3MONOCYPHER
-.Os
-.Sh NAME
-.Nm crypto_chacha20_H
-.Nd HChacha20 special-purpose hashing
-.Sh SYNOPSIS
-.In monocypher.h
-.Ft void
-.Fo crypto_chacha20_H
-.Fa "uint8_t out[32]"
-.Fa "const uint8_t key[32]"
-.Fa "const uint8_t in[16]"
-.Fc
-.Sh DESCRIPTION
-.Fn crypto_chacha20_H
-provides a not-so-cryptographic hash.
-It may be used for some specific purposes, such as X25519 key
-derivation, or XChacha20 initialisation.
-If in doubt, do not use directly.
-Use
-.Xr crypto_blake2b 3monocypher
-instead.
-.Pp
-The arguments are:
-.Bl -tag -width Ds
-.It Fa key
-A sufficiently random key, such as the output of
-.Xr crypto_x25519 3monocypher .
-.It Fa in
-The space reserved for the Chacha20 nonce and counter.
-It does not have to be random.
-.It Fa out
-A cryptographically secure random number
-.Em if
-there is enough entropy in
-.Fa key .
-X25519 shared secrets have enough entropy.
-.El
-.Sh RETURN VALUES
-This function returns nothing.
-.Sh EXAMPLES
-Simple hash:
-.Bd -literal -offset indent
-const uint8_t key[32]; /* Must have enough entropy */
-const uint8_t in [16]; /* Does not have to be random */
-uint8_t out[32]; /* Will be random iff the above holds */
-crypto_chacha20_H(out, key, in);
-/* Wipe secrets if they are no longer needed */
-crypto_wipe(key, 32);
-crypto_wipe(in , 16);
-.Ed
-.Sh SEE ALSO
-.Xr crypto_chacha20_encrypt 3monocypher ,
-.Xr crypto_key_exchange 3monocypher ,
-.Xr intro 3monocypher
-.Sh STANDARDS
-This function implements HChacha20.
-HChacha20 derives from Chacha20 the same way HSalsa20 derives from
-Salsa20.
-.Sh HISTORY
-The
-.Fn crypto_chacha20_H
-function first appeared in Monocypher 0.1.
-.Sh CAVEATS
-.Sy This is not a general-purpose cryptographic hash function .
--- /dev/null
+crypto_hchacha20.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_chacha20.3monocypher
\ No newline at end of file
-.Dd December 28, 2017
+.Dd December 2, 2019
.Dt CRYPTO_CHACHA20_ENCRYPT 3MONOCYPHER
.Os
.Sh NAME
.Nm crypto_chacha20_x_init ,
.Nm crypto_chacha20_stream ,
.Nm crypto_chacha20_set_ctr
-.Nd Chacha20 and XChacha20 encryption
+.Nd deprecated Chacha20 and XChacha20 encryption functions
.Sh SYNOPSIS
.In monocypher.h
.Ft void
.Fa "uint64_t ctr"
.Fc
.Sh DESCRIPTION
-These functions provide an incremental interface for the Chacha20
-encryption primitive.
-.Pp
-Chacha20 is a low-level primitive.
-Consider using authenticated encryption, implemented by
-.Xr crypto_lock 3monocypher .
-.Pp
-The arguments are:
-.Bl -tag -width Ds
-.It Fa key
-A 32-byte secret key.
-.It Fa nonce
-An 8-byte or 24-byte number, used only once with any given key.
-It does not need to be secret or random, but it does have to be unique.
-Repeating a nonce with the same key reveals the XOR of two different
-messages, which allows decryption.
-24-byte nonces can be selected at random.
-8-byte nonces
-.Em cannot .
-They are too small, and the same nonce may be selected twice by
-accident.
-See
-.Xr intro 3monocypher
-for advice about generating random numbers (use the operating system's
-random number generator).
-.It Fa plain_text
-The message to encrypt.
-It is allowed to be
-.Dv NULL ,
-in which case it will be interpreted as an all zero input.
-.Fa cipher_text
-will then contain the raw Chacha20 stream.
-.It Fa cipher_text
-The encrypted message.
-.It Fa text_size
-Length of both
-.Fa plain_text
-and
-.Fa cipher_text ,
-in bytes.
-.It Fa stream
-The raw Chacha20 stream.
-.It Fa stream_size
-Length of
-.Fa stream ,
-in bytes.
-.It Fa ctr
-The number of 64-byte blocks since the beginning of the stream.
-.El
-.Pp
-The
-.Fa key
-and
-.Fa nonce
-buffers may overlap.
-.Fa plain_text
-and
-.Fa cipher_text
-must either be the same buffer (for in-place encryption), or
-non-overlapping.
-.Pp
-.Fn crypto_chacha20_init
-initialises the
-.Vt crypto_chacha_ctx
-context.
-It uses an 8-byte nonce, which is too small to be selected at random.
-Use a counter.
-.Pp
-.Fn crypto_chacha20_x_init
-initialises the
-.Vt crypto_chacha_ctx
-context.
-It uses a 24-byte nonce, which is big enough to be selected at random.
-.Pp
-.Fn crypto_chacha20_x_init
-is recommended over
-.Fn crypto_chacha20_init .
-The ability to use random nonces makes it easier to use securely, and
-the performance hit is negligible in practice.
-.Pp
-The following functions need an initialised context to work properly.
-Calling them with an uninitialised context triggers undefined
-behaviour.
-.Pp
-.Fn crypto_chacha20_encrypt
-encrypts
-.Fa plain_text
-by XORing it with a pseudo-random stream of
-numbers, seeded by the provided
-.Vt crypto_chacha_ctx
-context.
-You may call
-.Fn crypto_chacha20_encrypt
-repeatedly with the same context struct to encrypt a message
-incrementally.
-The
-.Fa plain_text
-pointer is allowed to be
-.Dv NULL ,
-in which case it will be interpreted as an all zero input.
-.Pp
-Since XOR is its own inverse, decryption is the same operation as
-encryption.
-To decrypt the cipher text, encrypt it again with the same key and nonce.
-You will likely want to wipe the key and context when you are done with
-encryption or decryption.
-Use
-.Xr crypto_wipe 3monocypher
-to wipe them.
-.Pp
-.Fn crypto_chacha20_stream
-is the same as
-.Fn crypto_chacha20_encrypt
-with
-.Fa plain_text
-being
-.Dv NULL .
-This is useful as a user space random number generator.
-While
-.Sy this must not be used as a cryptographic random number generator ,
-it can be handy outside of a security context.
-Deterministic procedural generation and reproducible property-based
-tests come to mind.
-.Pp
-.Fn crypto_chacha20_set_ctr
-resets the internal counter of the
-.Vt crypto_chacha_ctx
-to the value specified in
-.Fa ctr .
-Resuming the encryption will use the stream at the block
-.Fa ctr
-(which is the byte
-.Ql ctr \(mu 64 ) .
-This can be used to encrypt (or decrypt) part of a long message, or to
-implement some AEAD constructions such as the one described in RFC
-8439.
-Be careful when using this not to accidentally reuse parts of the
-random stream as that would destroy confidentiality.
+These functions provided an incremental interface for the Chacha20
+cipher.
+They are deprecated in favor of
+.Xr crypto_chacha20 3monocypher ,
+.Xr crypto_chacha20_ctr 3monocypher ,
+.Xr crypto_xchacha20 3monocypher , and
+.Xr crypto_xchacha20_ctr 3monocypher .
+.Pp
+For encryption, you can achieve an identical effect
+as the deprecated functions by using
+.Xr crypto_chacha20_ctr 3monocypher
+or
+.Xr crypto_xchacha20_ctr 3monocypher .
+Care needs to be taken with regards to handling the counter value
+when migrating old code to use the new functions.
+The new functions
+.Em always return next counter value .
+This means that input ciphertexts or plaintexts
+whose lengths are not exactly multiples of 64 bytes
+advance the counter, even though there is theoretically some space left
+in a Chacha20 block.
+New applications should design their code so that either
+the protocl is not reliant on the counter covering the entire text
+(e.g. by cutting input into independent chunks) or
+inputs are always such that their lengths are multiples of 64 bytes
+(e.g. by buffering input until 64 bytes have been obtained).
+.Pp
+To obtain the raw Chacha20 stream previously provided by
+.Fn crypto_chacha20_stream ,
+pass
+.Dv NULL
+to
+.Xr crypto_chacha20
+as plaintext.
.Sh RETURN VALUES
These functions return nothing.
-.Sh EXAMPLES
-Simple encryption:
-.Bd -literal -offset indent
-const uint8_t key [ 32]; /* Secret random key */
-const uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
-const uint8_t plain_text [500]; /* Message to be encrypted */
-uint8_t cipher_text[500]; /* Will be the encrypted message */
-crypto_chacha_ctx ctx;
-crypto_chacha20_x_init(&ctx, key, nonce);
-crypto_chacha20_encrypt(&ctx, cipher_text, plain_text, 500);
-/* Wipe secrets if they are no longer needed */
-crypto_wipe(key, 32);
-crypto_wipe(&ctx, sizeof(ctx));
-crypto_wipe(plain_text, 500);
-.Ed
-.Pp
-To decrypt the above:
-.Bd -literal -offset indent
-const uint8_t key [ 32]; /* Same key as above */
-const uint8_t nonce [ 24]; /* Same nonce as above */
-const uint8_t cipher_text[500]; /* Encrypted message */
-uint8_t plain_text [500]; /* Will be the decrypted message */
-crypto_chacha_ctx ctx;
-crypto_chacha20_x_init(&ctx, key, nonce);
-crypto_chacha20_encrypt(&ctx, plain_text, cipher_text, 500);
-/* Wipe secrets if they are no longer needed */
-crypto_wipe(key, 32);
-crypto_wipe(&ctx, sizeof(ctx));
-/* The plain text likely needs to be processed before you wipe it */
-crypto_wipe(plain_text, 500);
-.Ed
-.Pp
-Incremental encryption:
-.Bd -literal -offset indent
-const uint8_t key [ 32]; /* Secret random key */
-const uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
-const uint8_t plain_text [500]; /* Message to be encrypted */
-uint8_t cipher_text[500]; /* Will be the encrypted message */
-crypto_chacha_ctx ctx;
-crypto_chacha20_x_init(&ctx, key, nonce);
-for(int i = 0; i < 500; i += 100) {
- crypto_chacha20_encrypt(&ctx, cipher_text+i, plain_text+i, 100);
-}
-/* Wipe secrets if they are no longer needed */
-crypto_wipe(key, 32);
-crypto_wipe(&ctx, sizeof(ctx));
-crypto_wipe(plain_text, 500);
-.Ed
-.Pp
-Simple encryption with a small,
-.Em not
-random nonce:
-.Bd -literal -offset indent
-const uint8_t key [ 32]; /* Secret, random key */
-const uint8_t nonce [ 8]; /* Unique nonce (NOT random) */
-const uint8_t plain_text [500]; /* Message to be encrypted */
-uint8_t cipher_text[500]; /* Will be the encrypted message */
-crypto_chacha_ctx ctx;
-crypto_chacha20_init(&ctx, key, nonce);
-crypto_chacha20_encrypt(&ctx, cipher_text, plain_text, 500);
-/* Wipe secrets if they are no longer needed */
-crypto_wipe(key, 32);
-crypto_wipe(&ctx, sizeof(ctx));
-crypto_wipe(plain_text, 500);
-.Ed
-.Pp
-Encryption by jumping around (do not do that, this is only meant to show
-how
-.Fn crypto_chacha20_set_ctr
-works):
-.Bd -literal -offset indent
-const uint8_t key [ 32]; /* Secret random key */
-const uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
-const uint8_t plain_text [500]; /* Message to be encrypted */
-uint8_t cipher_text[500]; /* Will be the encrypted message */
-crypto_chacha_ctx ctx;
-crypto_chacha20_x_init(&ctx, key, nonce);
-/* Encrypt the second part of the message first... */
-crypto_chacha20_set_ctr(&ctx, 3);
-crypto_chacha20_encrypt(&ctx,
- cipher_text + (3 * 64),
- plain_text + (3 * 64),
- 500 - (3 * 64));
-/* ...then encrypt the first part */
-crypto_chacha20_set_ctr(&ctx, 0);
-crypto_chacha20_encrypt(&ctx, cipher_text, plain_text, 3 * 64);
-/* Wipe secrets if they are no longer needed */
-crypto_wipe(key, 32);
-crypto_wipe(&ctx, sizeof(ctx));
-crypto_wipe(plain_text, 500);
-.Ed
.Sh SEE ALSO
+.Xr crypto_chacha20 3monocypher ,
+.Xr crypto_chacha20_ctr 3monocypher ,
+.Xr crypto_xchacha20 3monocypher ,
+.Xr crypto_xchacha20_ctr 3monocypher ,
.Xr crypto_lock 3monocypher ,
.Xr crypto_wipe 3monocypher ,
.Xr intro 3monocypher
-.Sh STANDARDS
-These functions implement Chacha20 and XChacha20.
-Chacha20 is described in RFC 8439.
-XChacha20 derives from Chacha20 the same way XSalsa20 derives from
-Salsa20, and benefits from the same security reduction (proven secure
-as long as Chacha20 itself is secure).
.Sh HISTORY
The
.Fn crypto_chacha20_encrypt ,
and
.Fn crypto_chacha20_set_ctr
were added in Monocypher 1.0.
-.Sh SECURITY CONSIDERATIONS
-.Ss Encrypted does not mean secure
-Chacha20 only protects against eavesdropping, not forgeries.
-Most applications need protection against forgeries to be properly
-secure.
-To ensure the integrity of a message, use Blake2b in keyed mode, or
-authenticated encryption; see
-.Xr crypto_blake2b 3monocypher
-and
-.Xr crypto_lock 3monocypher
-.Ss Nonce reuse
-Repeating a nonce with the same key exposes the XOR of two or more
-plain text messages, effectively destroying confidentiality.
-.Pp
-For the same reason,
-.Sy do not select small nonces at random .
-The
-.Fn crypto_chacha20_init
-nonce spans only 64 bits, which is small enough to trigger accidental
-reuses.
-A counter should be used instead.
-If multiple parties send out messages, Each can start with an initial
-nonce of 0, 1 .. n-1 respectively, and increment them by n for each
-new message.
-Make sure the counters never wrap around.
-.Ss Secure random number generation
-Do not use these functions as a cryptographic random number generator.
-Always use the operating system's random number generator for
-cryptographic purposes, see
-.Xr intro 3monocypher .
-.Ss Protection against side channels
-Secrets should not dwell in memory longer than needed.
-Use
-.Xr crypto_wipe 3monocypher
-to erase secrets you no longer need.
-For Chacha20, this means the context, the key, and in some cases the
-plain text itself.
+They were deprecated in Monocypher 3.0.0
+and will be removed in Monocypher 4.0.0.
--- /dev/null
+crypto_sign_init_first_pass_custom_hash.3monocypher
\ No newline at end of file
--- /dev/null
+.Dd December 2, 2019
+.Dt CRYPTO_HCHACHA20 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_hchacha20
+.Nd HChacha20 special-purpose hashing
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_hchacha20
+.Fa "uint8_t out[32]"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t in[16]"
+.Fc
+.Sh DESCRIPTION
+.Fn crypto_hchacha20
+provides a not-so-cryptographic hash.
+It may be used for some specific purposes, such as X25519 key
+derivation, or XChacha20 initialisation.
+If in doubt, do not use directly.
+Use
+.Xr crypto_blake2b 3monocypher
+instead.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa key
+A sufficiently random key, such as the output of
+.Xr crypto_x25519 3monocypher .
+.It Fa in
+The space reserved for the Chacha20 nonce and counter.
+It does not have to be random.
+.It Fa out
+A cryptographically secure random number
+.Em if
+there is enough entropy in
+.Fa key .
+X25519 shared secrets have enough entropy.
+.El
+.Sh RETURN VALUES
+This function returns nothing.
+.Sh EXAMPLES
+Simple hash:
+.Bd -literal -offset indent
+const uint8_t key[32]; /* Must have enough entropy */
+const uint8_t in [16]; /* Does not have to be random */
+uint8_t out[32]; /* Will be random iff the above holds */
+crypto_hchacha20(out, key, in);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(in , 16);
+.Ed
+.Sh SEE ALSO
+.Xr crypto_chacha20_encrypt 3monocypher ,
+.Xr crypto_key_exchange 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+This function implements HChacha20.
+HChacha20 derives from Chacha20 the same way HSalsa20 derives from
+Salsa20.
+.Sh HISTORY
+The
+.Fn crypto_hchacha20
+function first appeared in Monocypher 0.1 as
+.Fn crypto_chacha20_H .
+It was renamed to
+.Fn crypto_hchacha20
+in Monocypher 3.0.0.
+.Sh CAVEATS
+.Sy This is not a general-purpose cryptographic hash function .
--- /dev/null
+.Dd December 2, 2019
+.Dt CRYPTO_IETF_CHACHA20 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_ietf_chacha20 ,
+.Nm crypto_ietf_chacha20_ctr
+.Nd IETF Chacha20 encryption functions
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_ietf_chacha20
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[12]"
+.Fc
+.Ft void
+.Fo crypto_ietf_chacha20_ctr
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[12]"
+.Fa "const uint32_t ctr"
+.Fc
+.Sh DESCRIPTION
+These functions provide an interface for the Chacha20 encryption
+primitive as specified by the IETF in RFC 8439.
+They are provided strictly for compatibility with existing systems
+or strict standards compliance.
+New programs are strongly encouraged to use
+.Xr crypto_xchacha20
+instead.
+.Pp
+Chacha20 is a low-level primitive.
+Consider using authenticated encryption, implemented by
+.Xr crypto_lock 3monocypher .
+.Pp
+The
+.Fn crypto_ietf_chacha20
+and
+.Fn crypto_ietf_chacha20_ctr
+functions behave the same as
+.Xr crypto_chacha20
+and
+.Xr crypto_chacha20_ctr ,
+respectively,
+but use differently-sized nonce and counter values.
+The nonce encompasses 12 bytes and the counter is correspondingly
+reduced to 4 bytes.
+The short counter limits a single pair of key and nonce to 256 GiB of
+data.
+A nonce of 12 bytes is
+.Em just barely too short
+to be safely chosen at random;
+use a message counter instead.
+RFC 8439 also permits linear feedback shift registers to generate
+nonces.
+.Sh RETURN VALUES
+.Fn crypto_ietf_chacha20
+returns nothing.
+.Fn crypto_ietf_chacha20_ctr
+functions return the next
+.Fa ctr
+to use with the same key and nonce values;
+this is always
+.Fa text_size
+divided by 64;
+plus one if there was a remainder.
+.Sh SEE ALSO
+.Xr crypto_chacha20 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement Chacha20 as described in RFC 8439.
+.Sh HISTORY
+.Fn crypto_ietf_chacha20
+and
+.Fn crypto_ietf_chacha20_ctr
+were added in Monocypher 3.0.0.
--- /dev/null
+crypto_ietf_chacha20.3monocypher
\ No newline at end of file
+++ /dev/null
-.Dd December 28, 2017
-.Dt CRYPTO_MEMCMP 3MONOCYPHER
-.Os
-.Sh NAME
-.Nm crypto_memcmp ,
-.Nm crypto_zerocmp
-.Nd deprecated timing-safe data comparisons
-.Sh SYNOPSIS
-.In monocypher.h
-.Ft int
-.Fo crypto_memcmp
-.Fa "const uint8_t *p1"
-.Fa "const uint8_t *p2"
-.Fa "size_t n"
-.Fc
-.Ft int
-.Fo crypto_zerocmp
-.Fa "const uint8_t *p"
-.Fa "size_t n"
-.Fc
-.Sh DESCRIPTION
-.Fn crypto_memcmp
-and
-.Fn crypto_zerocmp
-were meant to provide timing-safe data comparison.
-They have been removed from Monocypher because they could not uphold
-those guarantees when compiled with
-.Fl O3
-on common compilers.
-Use
-.Xr crypto_verify16 3monocypher ,
-.Xr crypto_verify32 3monocypher
-and
-.Xr crypto_verify64 3monocypher
-instead.
-.Sh SEE ALSO
-.Xr crypto_verify16 3monocypher ,
-.Xr intro 3monocypher
-.Sh HISTORY
-The
-.Fn crypto_memcmp
-function first appeared in Monocypher 0.1.
-.Fn crypto_zerocmp
-was introduced in Monocypher 0.6.
-These functions were removed in Monocypher 1.1.0.
--- /dev/null
+.Dd December 3, 2019
+.Dt CRYPTO_SIGN_INIT_FIRST_PASS_CUSTOM_HASH 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_sign_init_first_pass_custom_hash ,
+.Nm crypto_sign_public_key_custom_hash ,
+.Nm crypto_check_init_custom_hash
+.Nd public key signatures with custom hash functions
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_sign_init_first_pass_custom_hash
+.Fa "crypto_sign_ctx_abstract *ctx"
+.Fa "const uint8_t secret_key[32]"
+.Fa "const uint8_t public_key[32]"
+.Fa "const crypto_sign_vtable *hash"
+.Fc
+.Ft void
+.Fo crypto_sign_public_key_custom_hash
+.Fa "uint8_t public_key[32]"
+.Fa "const uint8_t secret_key[32]"
+.Fa "const crypto_sign_vtable *hash"
+.Fc
+.Ft void
+.Fo crypto_check_init_custom_hash
+.Fa "crypto_sign_ctx_abstract *ctx"
+.Fa "const uint8_t signature[64]"
+.Fa "const uint8_t public_key[32]"
+.Fa "const crypto_sign_vtable *hash"
+.Fc
+.Sh DESCRIPTION
+These functions are variants of the
+.Xr crypto_sign_init_first_pass 3monocypher
+family of functions:
+They provide the ability to replace the EdDSA hash function with any
+user-provided hash function.
+.Pp
+.Sy This is a highly advanced feature .
+.Xr crypto_ed25519_sign 3monocypher
+or
+.Xr crypto_ed25519_sign_init_first_pass 3monocypher
+handle interoperability issues regarding public key signatures.
+This interface is exposed only for completeness and to handle special
+situations
+(e.g. to use the hash function of the future winner of the NIST
+lightweight crypto competition on a device with highly constrained
+resources or taking advantage of hardware support for cryptographic
+hash functions).
+Whenever possible, these functions should be avoided.
+.Pp
+To make available a custom hash algorithm for use with these functions,
+a
+.Vt crypto_sign_vtable
+structure must be provided.
+It is defined as:
+.Bd -literal
+typedef struct {
+ void (*hash)(uint8_t hash[64], const uint8_t *message,
+ size_t message_size);
+ void (*init )(void *ctx);
+ void (*update)(void *ctx, const uint8_t *message,
+ size_t message_size);
+ void (*final )(void *ctx, uint8_t *hash);
+ size_t ctx_size;
+} crypto_sign_vtable;
+.Ed
+.Pp
+The context argument to the functions shall be referred to as
+.Dq outer signing context .
+The outer signing context must contain a
+.Vt crypto_sign_ctx_abstract
+as
+.Em its first member .
+Other than that, the outer signing context may be defined freely.
+Logically, it is required to contain some kind of hash context as well,
+else it cannot work as a custom hash function.
+.Pp
+Because the calling code cannot know the real type of the outer signing
+context,
+it is cast to
+.Vt void *
+when calling the hash functions in the vtable,
+but the
+.Fa ctx
+argument to the functions in the vtable is always guaranteed to be the
+outer signing context.
+.Pp
+The hash functions must not fail.
+If they somehow can fail,
+they have no way to propagate its error status,
+and thus the only ways to handle errors
+are to either assume an error never occurs (if reasonable),
+or to induce a crash in the code when an error occurs.
+.Pp
+The fields of
+.Vt crypto_sign_vtable
+are:
+.Bl -tag -width Ds
+.It Fa hash
+Function that generates a 64-byte hash for a given message.
+The output length
+.Em must
+be exactly 64 bytes.
+This will normally be constructed using the functions that provide the
+.Fa init ,
+.Fa update
+and
+.Fa final
+members.
+.It Fa init
+Function that initialises the hash context an outer signing context.
+.It Fa update
+Function that updates the hash context of an outer signing context.
+It must be able to handle message sizes of at least 32 bytes.
+.It Fa final
+Function that finalises the hash context of an outer signing context.
+This function should wipe the hash context with
+.Xr crypto_wipe 3monocypher
+if it contains pointers to objects outside the outer signing context.
+Monocypher takes care of wiping the outer signing context.
+.It Fa ctx_size
+The size of the outer signing context as determined by
+.Fn sizeof .
+.El
+.Pp
+The functions indicated in the
+.Vt crypto_sign_vtable
+must be thread-safe if any of Monocypher's signing functions are
+accessed from multiple threads.
+.Pp
+After calling
+.Fn crypto_sign_init_first_pass_custom_hash
+or
+.Fn crypto_check_init_custom_hash ,
+the
+.Xr crypto_sign_update 3monocypher ,
+.Xr crypto_sign_final 3monocypher ,
+.Xr crypto_sign_init_second_pass 3monocypher ,
+.Xr crypto_check_update 3monocypher ,
+and
+.Xr crypto_check_final 3monocypher
+functions can be used as usual.
+They will call into the hash vtable as required.
+The same security considerations and semantics apply.
+.Sh RETURN VALUES
+These functions return nothing.
+.Sh EXAMPLES
+Defining and using a custom implementation of SHA-512 and crudely
+checking its results against
+.Xr crypto_ed25519_sign 3monocypher :
+.Bd -literal -offset indent
+struct outer_ctx {
+ crypto_sign_ctx_abstract sctx;
+ SHA2_CTX hash_ctx;
+};
+
+static void
+my_hash(uint8_t hash[64], const uint8_t *msg, size_t len)
+{
+ SHA2_CTX ctx;
+ SHA512Init(&ctx);
+ SHA512Update(&ctx, msg, len);
+ SHA512Final(hash, &ctx);
+}
+
+static void
+my_init(void *ctx)
+{
+ struct outer_ctx *octx = ctx;
+ SHA512Init(&octx->hash_ctx);
+}
+
+static void
+my_update(void *ctx, const uint8_t *msg, size_t len)
+{
+ struct outer_ctx *octx = ctx;
+ SHA512Update(&octx->hash_ctx, msg, len);
+}
+
+static void
+my_final(void *ctx, uint8_t *hash)
+{
+ struct outer_ctx *octx = ctx;
+ SHA512Final(hash, &octx->hash_ctx);
+}
+
+static const crypto_sign_vtable my_vtable = {
+ my_hash,
+ my_init,
+ my_update,
+ my_final,
+ sizeof(struct outer_ctx)
+};
+
+int
+main(void)
+{
+ uint8_t theirs[64], mine[64];
+ uint8_t sk[32];
+ const uint8_t msg[] = {
+ 0x00, 0x01, 0x02, 0x04
+ };
+
+ arc4random_buf(sk, sizeof(sk));
+ crypto_ed25519_sign(theirs, sk, NULL, msg, sizeof(msg));
+
+ struct outer_ctx ctx;
+ crypto_sign_init_first_pass_custom_hash((void*)&ctx,
+ sk, NULL, &my_vtable);
+ crypto_sign_update( (void*)&ctx, msg, sizeof(msg));
+ crypto_sign_init_second_pass((void*)&ctx);
+ crypto_sign_update( (void*)&ctx, msg, sizeof(msg));
+ crypto_sign_final( (void*)&ctx, mine);
+
+ if (crypto_verify64(theirs, mine) != 0) {
+ fprintf(stderr, "theirs != mine\en");
+ return 1;
+ }
+ puts("ok");
+}
+.Ed
+.Sh SEE ALSO
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_sha512 3monocypher ,
+.Xr crypto_sign 3monocypher ,
+.Xr crypto_sign_init_first_pass 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr intro 3monocypher
+.Sh HISTORY
+The
+.Fn crypto_sign_init_first_pass_custom_hash ,
+.Fn crypto_sign_public_key_custom_hash ,
+.Fn crypto_check_init_first_pass_custom_hash
+functions first appeared in Monocypher 3.0.0.
--- /dev/null
+crypto_sign_init_first_pass_custom_hash.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_chacha20.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_chacha20.3monocypher
\ No newline at end of file
+++ /dev/null
-crypto_memcmp.3monocypher
\ No newline at end of file
-.Dd March 6, 2019
+.Dd December 4, 2019
.Dt INTRO 3MONOCYPHER
.Os
.Sh NAME
and
.Xr crypto_unlock 3monocypher
use the Chacha20 cipher and the Poly1305 one time authenticator.
-An incremental interface is also available.
.Pp
Chacha20 is a stream cipher based on a cryptographic hash function.
It runs efficiently on a wide variety of hardware, and unlike AES
Poly1305 is a one time authenticator, derived from Carter & Wegman
universal hashing.
It is very fast and very simple.
+.Pp
+For specialised needs,
+.Xr crypto_chacha20 3monocypher
+and
+.Xr crypto_poly1305 3monocypher
+are available to implement constructions involving them.
+Whenever possible,
+.Xr crypto_lock 3monocypher
+should be preferred, however.
.Ss Hashing
.Xr crypto_blake2b 3monocypher
implements the Blake2b hash.
implement EdDSA, with Curve25519 and Blake2b.
This is the same as the more famous Ed25519, with SHA-512 replaced by
the faster and more secure Blake2b.
-Ed25519 (EdDSA with SHA-512), is supported as a compilation option.
+.Pp
+For highly specialised needs,
+it is possible to use a custom hash function with EdDSA;
+see
+.Xr crypto_sign_init_first_pass_custom_hash 3monocypher .
.Ss Constant time comparison
.Xr crypto_verify16 3monocypher ,
.Xr crypto_verify32 3monocypher ,
wipes a buffer.
It is meant to erase secrets when they are no longer needed, to reduce
the chances of leaks.
+.Ss Optional code
+If Monocypher was compiled and installed with
+.Dv USE_ED25519 ,
+SHA-512 functions become available as well.
+See
+.Xr crypto_ed25519_sign 3monocypher ,
+.Xr crypto_ed25519_sign_init_first_pass 3monocypher ,
+.Xr crypto_sha512 3monocypher ,
+and
+.Xr crypto_hmac_sha512 3monocypher .
.Sh SEE ALSO
.Xr crypto_argon2i 3monocypher ,
.Xr crypto_argon2i_general 3monocypher ,
.Xr crypto_blake2b_general_init 3monocypher ,
.Xr crypto_blake2b_init 3monocypher ,
.Xr crypto_blake2b_update 3monocypher ,
-.Xr crypto_chacha20_encrypt 3monocypher ,
-.Xr crypto_chacha20_H 3monocypher ,
-.Xr crypto_chacha20_init 3monocypher ,
-.Xr crypto_chacha20_set_ctr 3monocypher ,
-.Xr crypto_chacha20_stream 3monocypher ,
-.Xr crypto_chacha20_x_init 3monocypher ,
+.Xr crypto_chacha20 3monocypher ,
+.Xr crypto_chacha20_ctr 3monocypher ,
.Xr crypto_check 3monocypher ,
.Xr crypto_check_final 3monocypher ,
.Xr crypto_check_init 3monocypher ,
.Xr crypto_check_update 3monocypher ,
+.Xr crypto_hchacha20 3monocypher ,
.Xr crypto_key_exchange 3monocypher ,
.Xr crypto_lock 3monocypher ,
.Xr crypto_lock_aead 3monocypher ,
.Xr crypto_sign 3monocypher ,
.Xr crypto_sign_final 3monocypher ,
.Xr crypto_sign_init_first_pass 3monocypher ,
+.Xr crypto_sign_init_first_pass_custom_hash 3monocypher ,
.Xr crypto_sign_init_second_pass 3monocypher ,
.Xr crypto_sign_public_key 3monocypher ,
.Xr crypto_sign_update 3monocypher ,
.Xr crypto_verify64 3monocypher ,
.Xr crypto_wipe 3monocypher ,
.Xr crypto_x25519 3monocypher ,
-.Xr crypto_x25519_public_key 3monocypher
+.Xr crypto_x25519_public_key 3monocypher ,
+.Xr crypto_xchacha20 3monocypher ,
+.Xr crypto_xchacha20_ctr 3monocypher
.Sh SECURITY CONSIDERATIONS
Using cryptography securely is difficult.
Flaws that never manifest under normal use might be exploited by a
--- /dev/null
+crypto_ed25519_sign.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_ed25519_sign.3monocypher
\ No newline at end of file
--- /dev/null
+.Dd December 3, 2019
+.Dt CRYPTO_ED25519_SIGN 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_ed25519_sign ,
+.Nm crypto_ed25519_check ,
+.Nm crypto_ed25519_sign_public_key
+.Nd public key signatures
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_ed25519_sign_public_key
+.Fa "uint8_t public_key[32]"
+.Fa "const uint8_t secret_key[32]"
+.Fc
+.Ft void
+.Fo crypto_ed25519_sign
+.Fa "uint8_t signature[64]"
+.Fa "const uint8_t secret_key[32]"
+.Fa "const uint8_t public_key[32]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft int
+.Fo crypto_ed25519_check
+.Fa "const uint8_t signature[64]"
+.Fa "const uint8_t public_key[32]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn crypto_ed25519_sign
+and
+.Fn crypto_ed25519_check
+functions provide Ed25519 public key signatures and verification
+with SHA-512 as the underlying hash function;
+they are interoperable with other Ed25519 implementations.
+If you have no interoperability requirements, prefer
+.Xr crypto_sign 3monocypher .
+.Pp
+The arguments and security considerations are the same as those
+described in
+.Xr crypto_sign 3monocypher .
+.Pp
+An incremental interface is available; see
+.Xr crypto_ed25519_sign_init_first_pass 3monocypher .
+.Sh RETURN VALUES
+.Fn crypto_ed25519_sign_public_key
+and
+.Fn crypto_ed25519_sign
+return nothing.
+.Pp
+.Fn crypto_ed25519_check
+returns 0 for legitimate messages and -1 for forgeries.
+.Sh SEE ALSO
+.Xr crypto_check 3monocypher ,
+.Xr crypto_key_exchange 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr crypto_sha512 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement Ed25519 as described in RFC 8032.
+.Sh HISTORY
+The
+.Fn crypto_ed25519_sign ,
+.Fn crypto_ed25519_check ,
+and
+.Fn crypto_ed25519_sign_public_key
+functions appeared in Monocypher 3.0.0.
+They replace recompilation of Monocypher with the
+.Dv ED25519_SHA512
+preprocessor definition.
--- /dev/null
+crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
--- /dev/null
+.Dd December 3, 2019
+.Dt CRYPTO_ED25519_SIGN_INIT_FIRST_PASS 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_ed25519_sign_init_first_pass ,
+.Nm crypto_ed25519_sign_update ,
+.Nm crypto_ed25519_sign_final ,
+.Nm crypto_ed25519_sign_init_second_pass ,
+.Nm crypto_ed25519_check_init ,
+.Nm crypto_ed25519_check_update ,
+.Nm crypto_ed25519_check_final
+.Nd incremental public key signatures
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_ed25519_sign_init_first_pass
+.Fa "crypto_ed25519_sign_ctx *ctx"
+.Fa "const uint8_t secret_key[32]"
+.Fa "const uint8_t public_key[32]"
+.Fc
+.Ft void
+.Fo crypto_ed25519_sign_update
+.Fa "crypto_ed25519_sign_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_ed25519_sign_final
+.Fa "crypto_ed25519_sign_ctx *ctx"
+.Fa "uint8_t signature[64]"
+.Fc
+.Ft void
+.Fo crypto_ed25519_sign_init_second_pass
+.Fa "crypto_ed25519_sign_ctx *ctx"
+.Fc
+.Ft void
+.Fo crypto_ed25519_check_init
+.Fa "crypto_ed25519_check_ctx *ctx"
+.Fa "const uint8_t signature[64]"
+.Fa "const uint8_t public_key[32]"
+.Fc
+.Ft void
+.Fo crypto_ed25519_check_update
+.Fa "crypto_ed25519_check_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft int
+.Fo crypto_ed25519_check_final
+.Fa "crypto_ed25519_check_ctx *ctx"
+.Fc
+.Sh DESCRIPTION
+These functions are variants of
+.Xr crypto_ed25519_sign 3monocypher
+and
+.Xr crypto_ed25519_check 3monocypher .
+Prefer those simpler functions if possible.
+.Pp
+These functions provide Ed25519 public key signatures and verification
+with SHA-512 as the underlying hash function;
+they are interoperable with other Ed25519 implementations.
+If you have no interoperability requirements, prefer
+.Xr crypto_sign 3monocypher .
+.Pp
+The arguments, security considerations and semantics are the same as
+those described in
+.Xr crypto_sign_init_first_pass 3monocypher
+and
+.Xr crypto_sign 3monocypher .
+.Sh RETURN VALUES
+.Fn crypto_ed25519_sign_init_first_pass ,
+.Fn crypto_ed25519_sign_init_second_pass ,
+.Fn crypto_ed25519_sign_update ,
+.Fn crypto_ed25519_sign_final ,
+.Fn crypto_ed25519_check_init
+and
+.Fn crypto_ed25519_check_update
+return nothing.
+.Pp
+.Fn crypto_ed25519_check_final
+returns 0 for legitimate messages and -1 for forgeries.
+.Sh SEE ALSO
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_key_exchange 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr crypto_ed25519_sign 3monocypher ,
+.Xr crypto_sign 3monocypher ,
+.Xr crypto_sign_init_first_pass 3monocypher ,
+.Xr crypto_sha512 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement Ed25519 as described in RFC 8032.
+.Sh HISTORY
+The
+.Fn crypto_ed25519_sign_init_first_pass ,
+.Fn crypto_ed25519_sign_update ,
+.Fn crypto_ed25519_sign_final ,
+.Fn crypto_ed25519_sign_init_second_pass ,
+.Fn crypto_ed25519_check_init ,
+.Fn crypto_ed25519_check_update ,
+and
+.Fn crypto_ed25519_check_final
+functions first appeared in Monocypher 3.0.0.
+They replace recompilation of Monocypher with the
+.Dv ED25519_SHA512
+preprocessor definition.
--- /dev/null
+crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
--- /dev/null
+.Dd December 5, 2019
+.Dt CRYPTO_HMAC_SHA512 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_hmac_sha512 ,
+.Nm crypto_hmac_sha512_init ,
+.Nm crypto_hmac_sha512_update ,
+.Nm crypto_hmac_sha512_final
+.Nd cryptographic hash-based message authentication code with SHA-512
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_hmac_sha512
+.Fa "uint8_t hmac[64]"
+.Fa "const uint8_t *key"
+.Fa "size_t key_size"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_hmac_sha512_init
+.Fa "crypto_hmac_sha512_ctx *ctx"
+.Fa "const uint8_t *key"
+.Fa "size_t key_size"
+.Fc
+.Ft void
+.Fo crypto_hmac_sha512_update
+.Fa "crypto_hmac_sha512_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_hmac_sha512_final
+.Fa "crypto_hmac_sha512_ctx *ctx"
+.Fa "uint8_t hmac[64]"
+.Fc
+.Sh DESCRIPTION
+HMAC with SHA-512 is a cryptographically secure message authentication
+code (MAC),
+provided to enable compatibility with other cryptographic systems.
+It is generally recommended to use
+.Xr crypto_blake2b_general 3monocypher
+instead,
+as it performs faster on x86_64 CPUs.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa hmac
+The output MAC,
+which is always 64 bytes long.
+.It Fa key
+Some secret key.
+One cannot predict the final hash without it.
+Users may want to wipe the key with
+.Xr crypto_wipe 3monocypher
+once they are done with it.
+.It Fa key_size
+Length of
+.Fa key ,
+in bytes.
+32 is a good default.
+Keys longer than 128 bytes will be reduced to 64 bytes by hashing
+the key with SHA-512.
+.It Fa message
+The message to compute the HMAC for.
+May overlap with
+.Fa hmac .
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Pp
+An incremental interface is provided.
+It is useful for handling streams of data or
+large files without using too much memory.
+This interface uses three steps:
+.Bl -bullet
+.It
+initialisation with
+.Fn crypto_hmac_sha512_init ,
+where we set up a context with the hashing parameters;
+.It
+update with
+.Fn crypto_hmac_sha512_update ,
+where we hash the message chunk by chunk, and keep the intermediary
+result in the context;
+.It
+and finalisation with
+.Fn crypto_hmac_sha512_final ,
+where we produce the final hash.
+The
+.Ft crypto_hmac_sha512_ctx
+is automatically wiped upon finalisation.
+.El
+.Pp
+.Fn crypto_hmac_sha512
+is a convenience function that
+performs
+.Fn crypto_hmac_sha512_init ,
+.Fn crypto_hmac_sha512_update ,
+and
+.Fn crypto_hmac_sha512_final .
+.Pp
+Use
+.Xr crypto_verify64 3monocypher
+to compare MACs.
+.Sh RETURN VALUES
+These functions return nothing.
+.Sh EXAMPLES
+Computing a message authentication code all at once:
+.Bd -literal -offset indent
+uint8_t hash [ 64]; /* Output hash (between 1 and 64 bytes) */
+uint8_t key [ 32]; /* Optional key (between 0 and 64 bytes) */
+uint8_t message[500]; /* Message to hash */
+crypto_hmac_sha512(hash, 64, key, 32, message, 500);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(message, 500);
+crypto_wipe(key, 32);
+.Ed
+.Pp
+Computing a message authentication code incrementally:
+.Bd -literal -offset indent
+uint8_t hash [ 64]; /* Output hash (between 1 and 64 bytes) */
+uint8_t key [ 32]; /* Optional key (between 0 and 64 bytes) */
+uint8_t message[500]; /* Message to hash */
+crypto_hmac_sha512_ctx ctx;
+crypto_hmac_sha512_init(&ctx, 64, key, 32);
+/* Wipe the key */
+crypto_wipe(key, 32);
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_hmac_sha512_update(&ctx, message + i, 100);
+ /* Wipe secrets if they are no longer needed */
+ crypto_wipe(message + i, 100);
+}
+crypto_hmac_sha512_final(&ctx, hash);
+.Ed
+.Sh SEE ALSO
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr crypto_poly1305 3monocypher ,
+.Xr crypto_sha512 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement HMAC with SHA-512.
+HMAC and SHA-512 itself are described in RFC 6234;
+SHA-512 is also described in the Federal Information Processing Standard
+(FIPS) 180-4;
+HMAC is also described in FIPS 198-1.
+.Sh HISTORY
+The
+.Fn crypto_hmac_sha512 ,
+.Fn crypto_hmac_sha512_init ,
+.Fn crypto_hmac_sha512_update ,
+and
+.Fn crypto_hmac_sha512_final
+functions first appeared in Monocypher 3.0.0.
--- /dev/null
+crypto_hmac_sha512.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_hmac_sha512.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_hmac_sha512.3monocypher
\ No newline at end of file
--- /dev/null
+.Dd December 5, 2019
+.Dt CRYPTO_SHA512 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_sha512 ,
+.Nm crypto_sha512_init ,
+.Nm crypto_sha512_update ,
+.Nm crypto_sha512_final
+.Nd cryptographic hashing with the SHA-512 algorithm
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_sha512
+.Fa "uint8_t hash[64]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_init
+.Fa "crypto_sha512_ctx *ctx"
+.Fc
+.Ft void
+.Fo crypto_sha512_update
+.Fa "crypto_sha512_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_final
+.Fa "crypto_sha512_ctx *ctx"
+.Fa "uint8_t hash[64]"
+.Fc
+.Sh DESCRIPTION
+SHA-512 is a cryptographically secure hash,
+provided to enable compatibility with other cryptographic systems.
+It is generally recommended to use
+.Xr crypto_blake2b 3monocypher
+instead,
+as it both performs faster on x86_64 CPUs and
+lacks many of the pitfalls of SHA-512.
+.Pp
+SHA-512 is
+.Em vulnerable to length extension attacks ;
+using it as a message authentication code (MAC) algorithm or keyed hash
+requires precautions.
+The
+.Xr crypto_hmac_sha512 3monocypher
+family of functions provides HMAC with SHA-512.
+Use
+.Xr crypto_verify64 3monocypher
+to compare MACs created this way.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa hash
+The output hash,
+which is always 64 bytes long.
+.It Fa message
+The message to hash.
+May overlap with
+.Fa hash .
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Pp
+An incremental interface is provided.
+It is useful for handling streams of data or
+large files without using too much memory.
+This interface uses three steps:
+.Bl -bullet
+.It
+initialisation with
+.Fn crypto_sha512_init ,
+where we set up a context with the hashing parameters;
+.It
+update with
+.Fn crypto_sha512_update ,
+where we hash the message chunk by chunk, and keep the intermediary
+result in the context;
+.It
+and finalisation with
+.Fn crypto_sha512_final ,
+where we produce the final hash.
+The
+.Ft crypto_sha512_ctx
+is automatically wiped upon finalisation.
+.El
+.Pp
+.Fn crypto_sha512
+is a convenience function that
+performs
+.Fn crypto_sha512_init ,
+.Fn crypto_sha512_update ,
+and
+.Fn crypto_sha512_final .
+.Sh RETURN VALUES
+These functions return nothing.
+.Sh EXAMPLES
+Hashing a message all at once:
+.Bd -literal -offset indent
+uint8_t hash [ 64]; /* Output hash (64 bytes) */
+uint8_t message[500]; /* Message to hash */
+crypto_sha512(hash, message, 500);
+.Ed
+.Pp
+Hashing a message incrementally:
+.Bd -literal -offset indent
+uint8_t hash [ 64]; /* Output hash (64 bytes) */
+uint8_t message[500]; /* Message to hash */
+crypto_sha512_ctx ctx;
+crypto_sha512_init(&ctx);
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_sha512_update(&ctx, message + i, 100);
+}
+crypto_sha512_final(&ctx, hash);
+.Ed
+.Sh SEE ALSO
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_hmac_sha512 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement SHA-512, described in RFC 6234 and
+the Federal Information Processing Standard (FIPS) 180-4.
+.Sh HISTORY
+The
+.Fn crypto_sha512 ,
+.Fn crypto_sha512_init ,
+.Fn crypto_sha512_update ,
+and
+.Fn crypto_sha512_final
+functions first appeared in Monocypher 0.3;
+they were not intended for use outside Monocypher itself and thus
+undocumented.
+They became part of the official API in Monocypher 3.0.0.
--- /dev/null
+crypto_sha512.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_sha512.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_sha512.3monocypher
\ No newline at end of file
# clean before build
rm -rf "$DIR/html/*.html"
-for name in $(ls -1 "$DIR/man/man3/" | sed 's/.3monocypher//')
-do
- mandoc \
+convert() {
+ MANS=$1
+ for name in $(ls -1 "$MANS/" | sed 's/.3monocypher//')
+ do
+ test -f "$MANS/$name.3monocypher" || continue
+ mandoc \
-Oman=%N.html,style=style.css \
- -Thtml "$DIR/man/man3/$name.3monocypher" > "$DIR/html/$name.html"
-done
+ -Thtml "$MANS/$name.3monocypher" \
+ > "$DIR/html/$name.html"
+ done
+}
+
+convert "$DIR/man/man3"
+convert "$DIR/man/man3/optional"
+
install-doc:
mkdir -p $(MAN_DIR)
- cp -r doc/man/man3/*.3monocypher $(MAN_DIR)
+ cp -PR doc/man/man3/*.3monocypher $(MAN_DIR)
+ifdef USE_ED25519
+ cp -PR doc/man/man3/optional/*.3monocypher $(MAN_DIR)
+endif
pkg-config-libhydrogen:
mkdir -p $(PKGCONFIG)