- **ChaCha20:** Daniel J. Bernstein.
- **Poly1305:** Daniel J. Bernstein.
- **BLAKE2:** Jean-Philippe Aumasson, Christian Winnerlein, Samuel Neves,
- and Zooko Wilcox-O'Hearn
-- **Argon2:** Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich
-- **X25519:** Daniel J. Bernstein
+ and Zooko Wilcox-O'Hearn.
+- **Argon2:** Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich.
+- **X25519:** Daniel J. Bernstein.
- **EdDSA:** Daniel J. Bernstein, Bo-Yin Yang, Niels Duif, Peter
- Schwabe, and Tanja Lange
+ Schwabe, and Tanja Lange.
Implementors
------------
Fabio Scotoni provided much needed advice about testing, interface,
packaging, and the general direction of the whole project. He also
-redesigned monocypher.org style sheets.
+redesigned the monocypher.org style sheets.
Mike Pechkin and André Maroneze found bugs in earlier versions of
Monocypher.
elliptic-curve cryptography. This made EdDSA signatures over twice as
fast.
+Samuel Lucas found many typos the manual and website.
+
Jens Alfke added some #ifdefs that enabled Monocypher to compile into
a C++ namespace, preventing symbol collisions with similarly-named
functions in other crypto libraries.
- Added Elligator 2 mappings (hash to curve, curve to hash).
- Added OPRF support (with scalar inversion).
-- Added Edwards25519 -> Curve25519 conversions
+- Added Edwards25519 -> Curve25519 conversions.
3.0.0
- `crypto_x25519()` and `crypto_key_exchange()` now return `void`.
- Added a custom hash interface to EdDSA. Several instances of EdDSA
can share the same binary.
-- Added optional support for HMAC SHA-512
-- Moved all SHA-512 operations to `src/optional/monocypher-ed25519.(h|c)`
+- Added optional support for HMAC SHA-512.
+- Moved SHA-512 operations to `src/optional/monocypher-ed25519.(h|c)`.
- Optional support for Ed25519 no longer requires a preprocessor flag.
Add `src/optional/monocypher-ed25519.(h|c)` to your project instead.
-----
2019/10/21
-- Added the `BLAKE2_NO_UNROLLING` preprocessor definition. Activating it
- makes the binary about 5KB smaller, and speeds up processing times on
- many embedded processors.
+- Added the `BLAKE2_NO_UNROLLING` preprocessor definition. Activating
+ it makes the binary about 5KB smaller and speeds up processing times
+ on many embedded processors.
- Reduced the stack usage of signature verification by about
40%. Signature verification now fits in smaller machines.
- Fixed many implicit casts warnings.
-----
2018/06/24
-- Corrected a critical vulnerability in EdDSA, where crypto_check() was
- accepting invalid signatures. (Found by Mike Pechkin.) The current
+- Corrected a critical vulnerability found by Mike Pechkin in EdDSA,
+ where crypto_check() was accepting invalid signatures. The current
fix removes a buggy optimisation, effectively halving the performance
of EdDSA.
- The test suite no longer tries to allocate zero bytes (some platforms
-----
2018/06/16
-- Corrected undefined behaviour in BLAKE2b
-- Improved the test suite (faster, better coverage)
+- Corrected undefined behaviour in BLAKE2b.
+- Improved the test suite (faster, better coverage).
2.0.2
-----
- Removed `crypto_lock_encrypt()` and `crypto_lock_auth()`.
- Renamed `crypto_lock_aead_auth()` to `crypto_lock_auth_ad()`.
- Renamed `crypto_unlock_aead_auth()` to `crypto_unlock_auth_ad()`.
-- Added `crypto_lock_auth_message()` and `crypto_unlock_auth_message()`
-- Renamed `crypto_aead_lock` to `crypto_lock_aead`;
-- Renamed `crypto_aead_unlock` to `crypto_unlock_aead`;
+- Added `crypto_lock_auth_message()` and `crypto_unlock_auth_message()`.
+- Renamed `crypto_aead_lock` to `crypto_lock_aead`.
+- Renamed `crypto_aead_unlock` to `crypto_unlock_aead`.
The format change facilitates optimisation by aligning data to block
boundaries. The API changes increase consistency.
2017/07/23
- Optimised the loading and unloading code of the symmetric crypto
- (BLAKE2b, sha512, Chacha20, and Poly1305).
-- Fused self contained tests together for easier analysis with Frama-C
+ (BLAKE2b, SHA-512, Chacha20, and Poly1305).
+- Fused self-contained tests together for easier analysis with Frama-C
and the TIS interpreter.
1.0
- Added about a hundred lines of code to improve performance of public
key cryptography. Diffie-Hellman is now 20% faster than before.
- (The effects are less pronounces for EdDSA).
+ The effects are less pronounced for EdDSA.
- Added random self-consistency tests.
- Added a speed benchmark against libsodium.
- Slightly changed the authenticated encryption API. Functions are
now all in "detached" mode. The reason is better support for
authenticated encryption _without_ additional data.
-- Rewrote BLAKE2b from spec, so it can use the same licence as
+- Rewrote BLAKE2b from spec so it can use the same licence as
everything else.
- Added random tests that compare Monocypher with libsodium and
ed25519-donna.
- Added explicit support for Frama-C analysis (this doesn't affect the
- source code)
+ source code).
0.6
---
2017/03/17
-- Fixed incorrect poly1305 output on empty messages. (Found by Mike
+- Fixed incorrect Poly1305 output on empty messages. (Found by Mike
Pechkin.)
0.5
---
2017/03/10
-- Fixed many undefined behaviours in curve25519, that occur whenever
+- Fixed many undefined behaviours in Curve25519 that occur whenever
we perform a left shift on a signed negative integer. It doesn't
affect the generated code, but you never know. (Found with Frama-C
by André Maroneze.)
-Fun fact: TweetNaCl and ref10 have the same bug. Libsodium have
+Fun fact: TweetNaCl and ref10 have the same bug. Libsodium has
corrected the issue, though.
For those who don't comprehend the magnitude of this madness, the
2017/03/09
- Fixed critical bug causing Argon2i to fail whenever it uses more
- than 512 blocks. It was reading uninitialised memory, and the
+ than 512 blocks. It was reading uninitialised memory and the
results were incorrect. (Found by Mike Pechkin.)
-- Fixed an undefined behaviour in curve25519 (`fe_tobytes()`). It was
- accessing uninitialised memory, before throwing it away. It didn't
+- Fixed an undefined behaviour in Curve25519 (`fe_tobytes()`). It was
+ accessing uninitialised memory before throwing it away. It didn't
affect the compiled code nor the results, but you never know.
(Found with [Frama-C](http://frama-c.com) by André Maroneze.)
---
2017/02/27
-- Got the invariants of poly1305 right, put them in the comments.
+- Got the invariants of Poly1305 right and put them in the comments.
There was no bug, but that was lucky (turned out the IETF test
vectors were designed to trigger the bugs I was afraid of).
-- Simplified poly1305 finalisation (replaced conditional subtraction
+- Simplified Poly1305 finalisation (replaced conditional subtraction
by a carry propagation).
- Made a few cosmetic changes here and there.
- Public interface significantly reworked. Removed redundant, hard to
mess up constructions.
- Added AEAD.
-- Sped up curve25519 by a factor of more than 6 (switched to ref10
- arithmetic)
-- Added various test vectors, completed the consistency tests.
+- Sped up Curve25519 by a factor of more than 6 (switched to ref10
+ arithmetic).
+- Added various test vectors and completed the consistency tests.
0.1
---
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
+.Em cannot
+because they are too small and the same nonce may be selected twice by
accident.
See
.Xr intro 3monocypher
The message to encrypt.
It is allowed to be
.Dv NULL ,
-in which case it will be interpreted as an all zero input.
+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
.Fa plain_text
and
.Fa cipher_text
-must either be the same buffer (for in-place encryption), or
+must either be the same buffer (for in-place encryption) or
non-overlapping.
.Pp
.Fn crypto_chacha20
.Fa plain_text
pointer is allowed to be
.Dv NULL ,
-in which case it will be interpreted as an all zero input.
+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 ,
tests come to mind.
Additionally, it
.Em can
-be used to generate large amounts of random-looking data quickly,
-for example to generate padding.
+be used to generate large amounts of random-looking data quickly
+\(en for example to generate padding.
.Pp
The
.Fn crypto_chacha20_ctr
and
.Fn crypto_xchacha20_ctr
-perform a ChaCha20 or XChaCha20 encryption, respectively,
+perform ChaCha20 or XChaCha20 encryption,
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
+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
+When using this, be careful not to accidentally reuse parts of the
random stream as that would destroy confidentiality.
.Sh RETURN VALUES
.Fn crypto_chacha20
to use with the same key and nonce values;
this is always
.Fa text_size
-divided by 64;
+divided by 64,
plus one if there was a remainder.
.Sh EXAMPLES
The following examples assume the existence of
crypto_xchacha20(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 */
+/* The plaintext likely needs to be processed before you wipe it */
crypto_wipe(plain_text, 12);
.Ed
.Pp
ctr = crypto_xchacha20_ctr(cipher_text+i, plain_text+i, 64,
key, nonce, ctr);
}
-/* Process data that didn't fit into 64 byte pieces */
+/* Process data that didn't fit into 64-byte pieces */
crypto_xchacha20_ctr(cipher_text+500-(i-64),
plain_text+500-(i-64),
500-(i-64),
crypto_wipe(plain_text, 500);
.Ed
.Pp
-Encryption by jumping around (do not do that, this is only meant to show
+Encryption by jumping around (do not do this, this is only meant to show
how
.Fn crypto_xchacha20_ctr
works):
.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
+Salsa20 and benefits from the same security reduction (proven secure
as long as ChaCha20 itself is secure).
.Sh HISTORY
.Fn crypto_chacha20 ,
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
+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.
+plaintext messages, effectively destroying confidentiality.
.Pp
For the same reason,
.Sy do not select small nonces at random .
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.
+If multiple parties send out messages,
+each can start with an initial nonce of 0, 1, 2 (...) 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
+cryptographic purposes; see
.Xr intro 3monocypher .
.Ss Protection against side channels
Secrets should not dwell in memory longer than needed.
.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.
+plaintext itself.
X25519 keys, not for long-term public keys.
After an initial key exchange involving hidden keys,
subsequent key exchange messages should be encrypted instead;
-see, for example, the Noise protocol.
+see, for example, the Noise Protocol Framework.
This is an
-.Em advanced feature
-\(en unless you are implementing an protocol that requires
+.Em advanced feature .
+Unless you are implementing an protocol that requires
indistinguishability of all communications from random noise,
consider
.Xr crypto_key_exchange_public_key 3monocypher
.Fa curve
and a
.Fa tweak ,
-hiding the public key it so that it is effectively indistinguishable
+hiding the public key so that it is effectively indistinguishable
from random noise.
Note that only
.Xr crypto_x25519_dirty_fast 3monocypher
must be chosen at random.
Even then, this operation
.Em may
-fail:
-Not all curve points are capable of being hidden.
+fail because
+not all curve points are capable of being hidden.
In this case,
.Fn crypto_curve_to_hidden
-must be tried again with a new key pair;
-the
+must be tried again with a new key pair,
+though
.Fa tweak
does not need to be changed.
On average, two attempts are needed.
The arguments are:
.Bl -tag -width Ds
.It Fa curve
-A point on the curve, which is a Curve25519 public key generated with
+A point on the curve which is a Curve25519 public key generated with
either
.Xr crypto_x25519_dirty_fast 3monocypher
or
arguments may overlap or point at the same buffer.
.Sh RETURN VALUES
.Fn crypto_curve_to_hidden
-returns 0 on success, -1 if the given
+returns 0 on success and -1 if the given
.Fa curve
argument is unsuitable for hiding.
.Pp
.Fn crypto_hidden_to_curve
and
.Fn crypto_hidden_key_pair
-return nothing; they cannot fail.
+return nothing.
+They cannot fail.
.Sh EXAMPLES
Generate a key pair manually using
.Xr crypto_x25519_dirty_small 3monocypher
.Sh SECURITY CONSIDERATIONS
The secret keys for the public keys fed into
.Fn crypto_curve_to_hidden
-.Sy must be chosen randomly ,
+.Sy must be chosen randomly
rather than deterministically.
Otherwise, the timing information given by the required number of
retries also leaks information on the secret keys.
.Pp
These functions
.Em help
-build highly difficult-to-analyze protocols,
+build highly difficult-to-analyse protocols
but are insufficient by themselves:
-Other metadata, such as the amount of bytes sent in a packet or the size
-of the 32-byte random-looking string that represents the curve point
+Other metadata, such as the number of bytes sent in a packet or the size
+of the 32-byte random looking string that represents the curve point
itself, can be very strong indicators of the use of cryptography.
Consider using appropriate padding algorithms, such as PADME,
and obscure other metadata as much as possible.
and
.Xr crypto_x25519 3monocypher .
This may be useful in some resource-constrained contexts or when no
-other key is available (for example, when retrieving SSH public keys
-from GitHub and reusing the SSH public keys as X25519 public keys).
+other key is available \(en for example when retrieving SSH public keys
+from GitHub and reusing the SSH public keys as X25519 public keys.
.Pp
The
.Fn crypto_from_eddsa_private
.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.
+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
and
.Xr crypto_chacha20_ctr ,
respectively,
-but use differently-sized nonce and counter values.
+but their counter and nonce have different sizes.
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
+The short counter limits a single key and nonce pair to 256 GiB of
data.
-A nonce of 12 bytes is
+A 12-bytes nonce is
.Em just barely too short
to be safely chosen at random;
use a message counter instead.
to use with the same key and nonce values;
this is always
.Fa text_size
-divided by 64;
+divided by 64,
plus one if there was a remainder.
.Sh SEE ALSO
.Xr crypto_chacha20 3monocypher ,
this occurs when encrypting more than 256 GiB of data and then
incrementing the nonce.
More specifically, this can be triggered by encrypting more than
-512 bytes with crypto_ietf_chacha20_ctr() at ctr = 0xffffffff,
+512 bytes with crypto_ietf_chacha20_ctr() at ctr = 0xffffffff
then encrypting a message at nonce[0]+1 and ctr = 0;
it can be observed that the keystreams are identical.
.Pp
It does not specify what actions can or should be taken when this limit
is exceeded.
Encrypting more than 256 GiB of data is therefore
-.Sy undefined behaviour ;
+.Sy undefined behaviour .
Monocypher may change the way it handles counter overflows at any time.
.Dq One-time
means the authentication key can be used only once.
.Sy This makes Poly1305 easy to misuse .
-On the other hand, Poly1305 is fast, and provably secure if used
+On the other hand, Poly1305 is fast and provably secure if used
correctly.
.Pp
Poly1305 is a low-level primitive.
The arguments are:
.Bl -tag -width Ds
.It Fa mac
-The authentication code.
+The message authentication code.
.It Fa key
The secret authentication key.
Use only once per message.
initialises a context.
.Fa key
should be wiped once the context is initialised.
-Then,
+Then
.Fn crypto_poly1305_update
authenticates the message chunk by chunk.
Once the message is entirely processed,
.Em dedicated
to the authentication key:
if it is reused to encrypt the message itself, the attacker may recover
-that chunk by guessing the message, then forge arbitrary messages.
+that chunk by guessing the message then forge arbitrary messages.
.Pp
To get this right, you need a session key, a
.Em unique
Use
.Xr crypto_verify16 3monocypher
to compare message authentication codes.
-Avoid standard buffer comparison functions.
-They may not run in constant time, enabling an attacker to exploit timing
+Avoid standard buffer comparison functions:
+they may not run in constant time, enabling an attacker to exploit timing
attacks to recover the MAC.
.Pp
The authentication key should be wiped with
.Xr crypto_wipe 3monocypher
after use.
.Pp
-The incremental interface automatically wipes its context when finished
+The incremental interface automatically wipes its context when finished,
so users do not need to do it themselves.
.It
Initialisation of the first pass with
.Fn crypto_sign_init_first_pass .
-The public key is optional, and will be recomputed if not provided.
+The public key is optional and will be recomputed if not provided.
This recomputation doubles the execution time for short messages.
.It
The first pass proper, with
.Fn crypto_sign_update .
-.Sy Under no circumstances must you forget the first pass :
+.Sy Under no circumstances must you forget the first pass .
Forgetting to call
.Fn crypto_sign_update
-will appear to work in that it produces valid signatures,
+will appear to work in that it produces valid signatures
but also
loses all security because attackers may now recover the secret key.
.It
.Fn crypto_sign_init_second_pass ,
.Fn crypto_sign_update ,
.Fn crypto_sign_final ,
-.Fn crypto_check_init
+.Fn crypto_check_init ,
and
.Fn crypto_check_update
return nothing.
than the block
size (96 bytes for BLAKE2b and SHA-512).
Access to a cryptographically secure pseudo-random generator is a
-requirement for effective side channel mitigation.
-Signing a message with increased power-related side channel mitigations:
+requirement for effective side-channel mitigation.
+Signing a message with increased power-related side-channel mitigations:
.Bd -literal -offset indent
const uint8_t message [ 500]; /* Message to sign */
uint8_t sk [ 32]; /* Secret key */
described in RFC 8032.
This is the same as Ed25519, with BLAKE2b instead of SHA-512.
.Pp
-The example for side channel mitigation follows the methodology outlined
+The example for side-channel mitigation follows the methodology outlined
in I-D.draft-mattsson-cfrg-det-sigs-with-noise-02.
.Sh HISTORY
The
When signing messages, the security considerations documented in
.Xr crypto_sign 3monocypher
also apply.
-In particular, if power-related side channels are part of your threat
-model,
-note that there may still be other power-related side channels (such as
+If power-related side-channels are part of your threat model,
+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.
.Sh IMPLEMENTATION DETAILS
.Sh DESCRIPTION
These functions are variants of the
.Xr crypto_sign_init_first_pass 3monocypher
-family of functions:
+family of functions.
They provide the ability to replace the EdDSA hash function with any
user-provided hash function.
.Pp
hash functions).
Whenever possible, these functions should be avoided.
.Pp
-To make available a custom hash algorithm for use with these functions,
+To make a custom hash algorithm available for use with these functions,
a
.Vt crypto_sign_vtable
structure must be provided.
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.
+Logically, it is required to contain some kind of hash context as well;
+otherwise it cannot work as a custom hash function.
.Pp
Because the calling code cannot know the real type of the outer signing
context,
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),
+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
be exactly 64 bytes.
This will normally be constructed using the functions that provide the
.Fa init ,
-.Fa update
+.Fa update ,
and
.Fa final
members.
The
.Fn crypto_sign_init_first_pass_custom_hash ,
.Fn crypto_sign_public_key_custom_hash ,
+and
.Fn crypto_check_init_first_pass_custom_hash
functions first appeared in Monocypher 3.0.0.
compare the output of
.Fn crypto_x25519
to an all-zero buffer using
-.Xr crypto_verify32 3monocypher ;
-abort the protocol if the output and the all-zero buffer are equal.
+.Xr crypto_verify32 3monocypher ,
+then abort the protocol if the output and the all-zero buffer are equal.
.Pp
Do not use the same secret key for both key exchanges and signatures.
-The public keys are different, and revealing both may leak information.
+The public keys are different and revealing both may leak information.
If there really is no room to store or derive two different secret keys,
consider generating a key pair for signatures and then converting it
with
for advice about how to generate cryptographically secure random bytes.
.Pp
Generate a pair of shared keys with your secret key and their public
-key.
-(This can help nonce management for full duplex communications.)
+key
+(this can help nonce management for full duplex communications).
.Bd -literal -offset indent
const uint8_t their_pk [32]; /* Their public key */
uint8_t your_sk [32]; /* Your secret key */
This function implements X25519, described in RFC 7748.
.Sh HISTORY
The
-.Fn crypto_x25519 ,
+.Fn crypto_x25519
and
.Fn crypto_x25519_public_key
functions first appeared in Monocypher 0.1.
.Sh SECURITY CONSIDERATIONS
-If either of the long term secret keys leaks, it may compromise
+If either of the long-term secret keys leaks, it may compromise
.Em all past messages .
This can be avoided by using protocols that provide forward secrecy,
such as the X3DH key agreement protocol.
Both functions generate a Curve25519 public key
.Fa pk
from the given secret key
-.Fa sk ;
-the public keys are on the
+.Fa sk .
+The public keys are on the
.Em whole
curve, rather than just the main prime-order subgroup.
Both do the same with different code size and memory characteristics:
.Fn crypto_x25519_dirty_fast
-uses multiple large temporary variables and uses functions that are
+uses multiple large temporary variables and functions that are
normally used internally for
-.Xr crypto_sign 3monocypher ;
-accordingly, it uses both more memory (for the temporary variables) and
+.Xr crypto_sign 3monocypher .
+Accordingly, it uses both more memory (for the temporary variables) and
more code size (unless the signing code is already compiled in
elsewhere).
.Fn crypto_x25519_dirty_small
-yields the same result, but does so using less code and memory at a
-large performance penalty compared to
+yields the same result with less code, less memory, and more time than
.Fn crypto_x25519_dirty_fast .
.Pp
The resulting public keys are to be used with
The output point.
.It Fa private_key
The private key (scalar) to use.
-First, the value is clamped;
+First, the value is clamped,
then the clamped value's multiplicative inverse (modulo the curve order)
-is determined;
-the clamped value's multiplicative inverse then has its cofactor
+is determined.
+The clamped value's multiplicative inverse then has its cofactor
cleared,
and that final value is then used for scalar multiplication.
.It Fa curve_point
.Os
.Sh NAME
.Nm crypto_argon2i
-.Nd password key derivation
+.Nd password-based key derivation
.Sh SYNOPSIS
.In monocypher.h
.Ft void
.Fa "uint32_t ad_size"
.Fc
.Sh DESCRIPTION
-Argon2i is a resource intensive password key derivation scheme
+Argon2i is a resource intensive password-based key derivation scheme
optimised for the typical x86-like processor.
It runs in constant time with respect to the contents of the password.
.Pp
-Typical applications are password checking (for online services), and
+Typical applications are password checking (for online services) and
key derivation (for encryption).
Derived keys can be used to encrypt, for example, private keys or
password databases.
Temporary buffer for the algorithm, allocated by the caller.
It must be
.Fa nb_blocks
-× 1024 bytes big, and suitably aligned for 64-bit integers.
+× 1024 bytes big and suitably aligned for 64-bit integers.
If you are not sure how to allocate that buffer, just use
.Fn malloc .
.Pp
.Pp
Use
.Xr crypto_verify16 3monocypher ,
-.Xr crypto_verify32 3monocypher
+.Xr crypto_verify32 3monocypher ,
or
.Xr crypto_verify64 3monocypher
to compare password hashes to prevent timing attacks.
.Pp
Since parameter selection depends on your hardware, some trial and error
will be required in order to determine the ideal settings.
-Three iterations and 100000 blocks (that is, one hundred megabytes of
-memory) is a good starting point.
+Three iterations and 100000 blocks
+(one hundred megabytes of memory)
+is a good starting point.
Adjust
.Fa nb_blocks
first.
is zero.
The key is generally not needed, but it does have some uses.
In the context of password derivation, it would be stored separately
-from the password database, and would remain secret even if an
+from the password database and would remain secret even if an
attacker were to steal the database.
Note that changing the key requires rehashing the user's password,
-which is only possible upon user login.
+which is only possible upon user log in.
.It Fa key_size
Length of
.Fa key ,
.Fa "uint8_t *hash"
.Fc
.Sh DESCRIPTION
-BLAKE2b is a fast cryptographically secure hash, based on the ideas of
+BLAKE2b is a fast cryptographically secure hash based on the ideas of
ChaCha20.
It is faster than MD5, yet just as secure as SHA-3.
.Pp
.Xr crypto_argon2i 3monocypher
family of functions for that purpose instead.
.Pp
-BLAKE2b is immune to length extension attacks, and as such does not
-require any specific precautions, such as using the HMAC algorithm.
+BLAKE2b is immune to length extension attacks, and as such, does not
+require specific precautions such as using the HMAC algorithm.
.Pp
The arguments are:
.Bl -tag -width Ds
and
.Fn crypto_blake2b_general .
.Fn crypto_blake2b
-is provided for convenience, and is equivalent to calling
+is provided for convenience and is equivalent to calling
.Fn crypto_blake2b_general
with no key and a 64-byte hash.
.Pp
.Fn crypto_blake2b_general
-users can specify the size of the hash, and use a secret key to
-make the hash unpredictable \(en useful for message authentication
-codes.
+users can specify the size of the hash and use a secret key to
+make the hash unpredictable,
+\(en which is useful for message authentication codes.
Even when using a key, you do not have to wipe the context struct with
.Xr crypto_wipe 3monocypher .
.Ss Incremental interface
This interface uses three steps:
.Bl -bullet
.It
-initialisation with
+Initialisation with
.Fn crypto_blake2b_general_init
or
.Fn crypto_blake2b_init ,
which sets up a context with the hashing parameters;
.It
-update with
+Update with
.Fn crypto_blake2b_update ,
-which hashes the message chunk by chunk, and keep the intermediary
+which hashes the message chunk by chunk and keeps the intermediary
result in the context;
.It
-and finalisation with
+and Finalisation with
.Fn crypto_blake2b_final ,
which produces the final hash.
The
.Sh SECURITY CONSIDERATIONS
BLAKE2b is a general-purpose cryptographic hash function;
this means that it is not suited for hashing passwords and deriving
-cryptographic keys from passwords in particular.
+cryptographic keys from passwords.
While cryptographic keys usually have hundreds of bits of entropy,
passwords are often much less complex.
When storing passwords as hashes or when deriving keys from them,
the goal is normally to prevent attackers from quickly iterating all
possible passwords.
Because passwords tend to be simple,
-it is important to artificially slow down attackers by using especially
+it is important to artificially slow down attackers by using
computationally difficult hashing algorithms.
Monocypher therefore provides
.Xr crypto_argon2i 3monocypher
.It Fa shared_key
The shared secret, known only to those who know a relevant secret key
(yours or theirs).
-It is cryptographically random, and suitable for use with the
+It is cryptographically random and suitable for use with the
.Xr crypto_lock 3monocypher
family of functions.
.It Fa your_secret_key
-A 32-byte random number, known only to you.
+A 32-byte random number known only to you.
See
.Xr intro 3monocypher
for advice about generating random bytes (use the operating system's
.Fa your_secret_key
may overlap if the secret is no longer required.
.Pp
-Some poorly designed protocols require to test for
+Some poorly designed protocols require a test for
.Dq contributory
behaviour, which ensures that no untrusted party forces the shared
secret to a known constant.
Protocols should instead be designed in such a way that no such check
-is necessary, namely by authenticating the other party or exchanging
+is necessary; namely, by authenticating the other party or exchanging
keys over a trusted channel.
.Pp
Do not use the same secret key for both key exchanges and signatures.
-The public keys are different, and revealing both may leak information.
+The public keys are different and revealing both may leak information.
If there really is no room to store or derive two different secret keys,
consider generating a key pair for signatures and then converting it
with
.Fn crypto_key_exchange_public_key
macro alias first appeared in Monocypher 1.1.0.
.Sh SECURITY CONSIDERATIONS
-If either of the long term secret keys leaks, it may compromise
+If either of the long-term secret keys leaks, it may compromise
.Em all past messages .
This can be avoided by using protocols that provide forward secrecy,
such as the X3DH key agreement protocol.
The arguments are:
.Bl -tag -width Ds
.It Fa key
-A 32-byte session key, shared between the sender and the recipient.
+A 32-byte session key shared between the sender and the recipient.
It must be secret and random.
-Different methods can be used to produce and exchange this key, such
-as Diffie-Hellman key exchange, password key derivation (the password
-must be communicated on a secure channel), or even meeting physically.
+Different methods can be used to produce and exchange this key,
+such as Diffie-Hellman key exchange,
+password-based key derivation
+(the password must be communicated on a secure channel),
+or even meeting physically.
See
.Xr crypto_key_exchange 3monocypher
-for key exchange, and
+for key exchange and
.Xr crypto_argon2i 3monocypher
-for password key derivation.
+for password-based key derivation.
.It Fa nonce
A 24-byte number, used only once with any given session key.
It does not need to be secret or random, but it does have to be
unique.
.Em Never
use the same nonce twice with the same key.
-This would reveal the XOR of 2 different messages, which allows
-decryption and forgeries.
+This would basically reveal the affected messages
+and leave you vulnerable to forgeries.
The easiest (and recommended) way to generate this nonce is to
select it at random.
See
.It Fa mac
A 16-byte
.Em message authentication code
-(MAC), that can only be produced by someone who knows the session key.
+(MAC) that can only be produced by someone who knows the session key.
This guarantee cannot be upheld if a nonce has been reused with the
-session key, because doing so allows the attacker to learn the
+session key because doing so allows the attacker to learn the
authentication key associated with that nonce.
The MAC is intended to be sent along with the ciphertext.
.It Fa plain_text
The secret message.
Its contents will be kept hidden from attackers.
-Its length however, will
+Its length, however, will
.Em not .
Be careful when combining encryption with compression.
See
If it has been corrupted,
.Fn crypto_unlock
returns -1 immediately.
-Otherwise, it decrypts the message, then returns zero.
+Otherwise, it decrypts the message then returns zero.
.Em Always check the return value .
.Pp
.Fn crypto_lock_aead
and
.Fn crypto_unlock ,
permitting additional data.
-Additional data is authenticated, but
+Additional data is authenticated but
.Em not
encrypted.
This is used to authenticate relevant data that cannot be encrypted.
mismatched the combination of
.Fa key ,
.Fa nonce ,
-.Fa ad
+.Fa ad ,
and
.Fa cipher_text ) .
Corruption can be caused by transmission errors, programmer error, or an
.Sh STANDARDS
These functions implement RFC 8439, with XChaCha20 instead of ChaCha20.
XChaCha20 derives from ChaCha20 the same way XSalsa20 derives from
-Salsa20, and benefits from the same security reduction (proven secure
+Salsa20 and benefits from the same security reduction (proven secure
as long as ChaCha20 itself is secure).
.Sh HISTORY
The
.It Fa signature
The signature.
.It Fa secret_key
-A 32-byte random number, known only to you.
+A 32-byte random number known only to you.
See
.Xr intro 3monocypher
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.
+The public keys are different and revealing both may leak information.
.It Fa public_key
The public key, generated from
.Fa secret_key
with
.Fn crypto_sign_public_key .
.It Fa message
-Message to sign.
+The message to sign.
.It Fa message_size
Length of
.Fa message ,
.Fn crypto_sign
signs a message with
.Fa secret_key .
-The public key is optional, and will be recomputed if not provided.
+The public key is optional and will be recomputed if not provided.
This recomputation doubles the execution time.
.Pp
.Fn crypto_check
Meaning, only someone who had the private key could have signed the
message.
.Sy \&It does not run in constant time .
-It does not have to in most threat models, because nothing is secret:
+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
.Fn crypto_sign
follows this specification.
However, someone with the private key can generate arbitrarily many
-valid, canonical, different signatures of the same message.
+valid, canonical, and different signatures of the same message.
Because of this, never assume that signatures are unique.
.Ss Fault injection and power analysis
Fault injection (also known as glitching) and power analysis may be used
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
+equipment, you could try using the incremental interface provided by
.Xr crypto_sign_init_first_pass 3monocypher
-to mitigate the side channel attacks.
+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.
If the attacker attempts a forgery, one does not want to reveal
.Dq your MAC is wrong, Em and it took 384 microseconds to tell .
If the next attempt takes 462 microseconds instead, it tells the
-attacker they just guessed a byte correctly.
-That way, an attacker can derive the correct MAC byte by byte,
+attacker that they just guessed a byte correctly.
+That way, an attacker can derive the correct MAC byte by byte
and successfully forge a message.
-This has lead to practical attacks in the past.
+This has led to practical attacks in the past.
.Pp
To avoid such catastrophic failure,
.Fn crypto_verify16 ,
-.Fn crypto_verify32
+.Fn crypto_verify32 ,
and
.Fn crypto_verify64
provide comparison functions whose timing is independent from
When in doubt, prefer these functions over
.Fn memcmp .
.Sh RETURN VALUES
-These functions return 0 if the two memory chunks are the same, -1
+These functions return 0 if the two memory chunks are the same and -1
otherwise.
.Sh SEE ALSO
.Xr intro 3monocypher
The
.Fn crypto_verify16 ,
.Fn crypto_verify32 ,
-.Fn crypto_verify64
+.Fn crypto_verify64 ,
functions first appeared in Monocypher 1.1.0.
They replaced the
.Fn crypto_memcmp
securely erases sensitive data in memory.
.Pp
Sensitive data (such as cryptographic keys or secret plaintexts) should
-be erased from memory as early as possible, to minimise the window in
+be erased from memory as early as possible to minimise the window in
which it can be leaked.
-Standard functions like memset and bzero are not safe to use, as the
+Standard functions like memset and bzero are not safe to use as the
compiler may decide they have no effect and optimise them out.
.Pp
The arguments are:
The buffer to erase.
.It Fa secret_size
The number of bytes to erase from the buffer.
-Normally this is the size of the entire buffer.
+This is normally the size of the entire buffer.
.El
.Pp
Monocypher will wipe its context structs when finalizing an operation
When using direct interfaces like
.Xr crypto_lock 3monocypher ,
these context structs are invisible to you.
-They are exposed in incremental interfaces like
+However, they are exposed in incremental interfaces like
.Xr crypto_blake2b_init 3monocypher .
The original key buffer does not get automatically wiped.
When using incremental interfaces, you may want to wipe the original key
.Pp
Using
.Fn crypto_wipe
-alone may not suffice for security.
+alone may not be enough for security.
It is recommended to lock down relevant memory regions as well.
Refer to
.Xr intro 3monocypher
.Sh DESCRIPTION
These functions provided an incremental interface for the ChaCha20
cipher.
-They are deprecated in favor of
+They were deprecated in favour of
.Xr crypto_chacha20 3monocypher ,
.Xr crypto_chacha20_ctr 3monocypher ,
.Xr crypto_xchacha20 3monocypher , and
.Xr crypto_chacha20_ctr 3monocypher
or
.Xr crypto_xchacha20_ctr 3monocypher .
-Care needs to be taken with regards to handling the counter value
+However,
+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 .
+.Em always return the 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
+the protocol 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).
.Fn crypto_chacha20_stream ,
pass
.Dv NULL
-to
+to
.Xr crypto_chacha20
as plaintext.
.Sh RETURN VALUES
.Xr intro 3monocypher
.Sh HISTORY
The
-.Fn crypto_chacha20_encrypt ,
-.Fn crypto_chacha20_init ,
+.Fn crypto_chacha20_encrypt
+and
+.Fn crypto_chacha20_init
functions first appeared in Monocypher 0.1.
.Fn crypto_chacha20_stream
was added in Monocypher 0.2.
which can be used to hash passwords for storage and to derive keys
from passwords.
Argon2 won the password hashing competition in 2015.
-Unlike Scrypt, Argon2i is immune to timing attacks.
+Unlike scrypt, Argon2i is immune to timing attacks.
.Ss Key exchange (Public Key Cryptography)
.Xr crypto_key_exchange 3monocypher
implements X25519, an elliptic curve Diffie Hellman key exchange
.Ss Random number generation
Use the facilities of your operating system.
Avoid user space random number generators.
-They are easy to misuse, which has lead to countless vulnerabilities
+They are easy to misuse, which has led to countless vulnerabilities
in the past.
For instance, the random stream may be repeated if one is not careful
with multi-threading, and forward secrecy is lost without proper key
.In linux/random.h .
Do not set any flag.
.It
-BSD, Darwin/macOS, illumos as well as Solaris provide
+BSD, Darwin/macOS, illumos, and Solaris provide
.Fn arc4random_buf
in
.In stdlib.h
.Pp
The
.Pa /dev/urandom
-special file may be used on systems that do not provide an easy to use
+special file may be used on systems that do not provide an easy-to-use
system call.
Be careful though, being a file makes
.Pa /dev/urandom
cookies when compression is enabled, dubbed
.Dq CRIME .
.Ss Forward secrecy
-Long term secrets cannot be expected to stay safe indefinitely.
+Long-term secrets cannot be expected to stay safe indefinitely.
Users may reveal them by mistake, or the host computer might have a
vulnerability and be compromised.
To mitigate this problem, some protocols guarantee that past messages
-are not compromised even if the long term keys are.
+are not compromised even if the long-term keys are.
This is done by generating temporary keys, then encrypting messages
using them.
.Pp
way.
.Pp
UNIX systems can disable swap for specific buffers with
-.Fn mlock ,
+.Fn mlock
and disable swap for the whole process with
.Fn mlockall .
Windows can disable swap for specific buffers with
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.
+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
described in
.Xr crypto_sign 3monocypher .
.Pp
-An incremental interface is available; see
+For an incremental interface, see
.Xr crypto_ed25519_sign_init_first_pass 3monocypher .
.Sh RETURN VALUES
.Fn crypto_ed25519_public_key
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.
+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
+The arguments, security considerations, and semantics are the same as
those described in
.Xr crypto_sign_init_first_pass 3monocypher
and
.Fn crypto_ed25519_sign_init_second_pass ,
.Fn crypto_ed25519_sign_update ,
.Fn crypto_ed25519_sign_final ,
-.Fn crypto_ed25519_check_init
+.Fn crypto_ed25519_check_init ,
and
.Fn crypto_ed25519_check_update
return nothing.
.Bl -tag -width Ds
.It Fa hmac
The output MAC,
-which is always 64 bytes long.
+which is always 64-bytes long.
.It Fa key
Some secret key.
One cannot predict the final hash without it.
.It
update with
.Fn crypto_hmac_sha512_update ,
-which hashes the message chunk by chunk, and keep the intermediary
+which hashes the message chunk by chunk and keeps the intermediary
result in the context;
.It
and finalisation with
.Xr crypto_verify32 3monocypher ,
and
.Xr crypto_verify16 3monocypher
-functions can be used to to compare (possibly truncated) MACs.
+functions can be used to compare (possibly truncated) MACs.
.Sh RETURN VALUES
These functions return nothing.
.Sh EXAMPLES
.Bl -tag -width Ds
.It Fa hash
The output hash,
-which is always 64 bytes long.
+which is always 64-bytes long.
.It Fa message
The message to hash.
May overlap with
.It
update with
.Fn crypto_sha512_update ,
-which hashes the message chunk by chunk, and keep the intermediary
+which hashes the message chunk by chunk and keeps the intermediary
result in the context;
.It
and finalisation with
.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
+functions first appeared in Monocypher 0.3,
+but were not intended for use outside Monocypher itself and thus
undocumented.
They became part of the official API in Monocypher 3.0.0.
.Sh SECURITY CONSIDERATIONS
SHA-512 is a general-purpose cryptographic hash function;
this means that it is not suited for hashing passwords and deriving
-cryptographic keys from passwords in particular.
+cryptographic keys from passwords.
While cryptographic keys usually have hundreds of bits of entropy,
passwords are often much less complex.
When storing passwords as hashes or when deriving keys from them,