CRYPTO_CURVE_TO_HIDDEN(3MONOCYPHER) | 3MONOCYPHER | CRYPTO_CURVE_TO_HIDDEN(3MONOCYPHER) |
crypto_curve_to_hidden
,
crypto_hidden_to_curve
,
crypto_hidden_key_pair
—
#include <monocypher.h>
int
crypto_curve_to_hidden
(uint8_t
hidden[32], const uint8_t curve[32],
uint8_t tweak);
void
crypto_hidden_to_curve
(uint8_t
curve[32], const uint8_t hidden[32]);
void
crypto_hidden_key_pair
(uint8_t
hidden[32], uint8_t secret_key[32],
uint8_t seed[32]);
For understanding what these functions do, it is important to note that a “public key” in this context refers to a point on Curve25519. This also means that these functions are not compatible with crypto_sign(3monocypher) and related functions.
crypto_curve_to_hidden
() takes a public
key curve and a tweak, hiding
the public key so that it is effectively indistinguishable from random
noise. Note that only
crypto_x25519_dirty_fast(3monocypher)
or
crypto_x25519_dirty_small(3monocypher)
can generate a suitable public key; the
crypto_x25519(3monocypher)
function is insufficient. The tweak must be chosen at
random. Even then, this operation may fail because not all
curve points are capable of being hidden. In this case,
crypto_curve_to_hidden
() must be tried again with a
new key pair, though tweak does not need to be
changed. On average, two attempts are needed. Once a suitable public key has
been found, crypto_curve_to_hidden
() always succeeds
for it. Given the same values for tweak and
curve,
crypto_curve_to_hidden
() yields the same output
value hidden.
crypto_hidden_to_curve
() performs the
inverse operation: It decodes a hidden point to a curve point on
Curve25519.
crypto_hidden_key_pair
() is a convenience
function that generates a secret key and its corresponding public key, which
is effectively indistinguishable from random noise, from a random seed.
The execution time of this function is unpredictable
because it may take many failures until a key pair could be generated
successfully. crypto_hidden_key_pair
() uses
crypto_x25519_dirty_fast(3monocypher)
internally; if code size is an important concern, its functionality can be
replicated with
crypto_x25519_dirty_small(3monocypher)
instead.
The arguments are:
crypto_curve_to_hidden
().The hidden and curve arguments may overlap or point at the same buffer.
crypto_curve_to_hidden
() returns 0 on success and -1 if
the given curve argument is unsuitable for hiding.
crypto_hidden_to_curve
() and
crypto_hidden_key_pair
() return nothing. They cannot
fail.
uint8_t sk [32]; /* Secret key output */ uint8_t pk [32]; /* Hidden public key output */ uint8_t tweak; /* Random tweak input */ arc4random_buf(&tweak, 1); for (;;) { arc4random_buf(sk, 32); crypto_x25519_dirty_small(pk, sk); if (crypto_curve_to_hidden(pk, pk, tweak) == 0) break; } /* Now save the secret key and send the hidden public key. */
Performing a key exchange with the other party's public key having been hidden:
uint8_t hidden_pk [32]; /* Their hidden public key */ uint8_t their_pk [32]; /* Their unhidden public key */ uint8_t your_sk [32]; /* Your secret key */ uint8_t shared_key[32]; /* Shared session key */ crypto_hidden_to_curve(their_pk, hidden_pk); crypto_x25519(shared_key, your_sk, their_pk); /* Wipe secrets if they are no longer needed */ crypto_wipe(your_sk, 32);
crypto_curve_to_hidden
(),
crypto_hidden_to_curve
(), and
crypto_hidden_key_pair
() functions first appeared in
Monocypher 3.1.0.
crypto_curve_to_hidden
() 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.
These functions help build highly difficult-to-analyse protocols but are insufficient by themselves: 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.
February 13, 2022 | Debian |