![]() |
![]()
| ![]() |
![]()
NAME
SYNOPSIS
void
int
void
DESCRIPTIONThese functions allow obfuscating X25519 public keys by making them appear effectively indistinguishable from random noise. This is of interest for key exchange protocols that require indistinguishability from randomness, such as padded uniform random blobs (PURBs). They are intended for ephemeral (short-lived, possibly just one-time) 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 Framework. This is an advanced feature. Unless you are implementing an protocol that requires indistinguishability of all communications from random noise, consider crypto_x25519(3monocypher) instead. Both this family of functions and crypto_x25519(3monocypher) should be used as a building block to implement a key exchange protocol. 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_eddsa_sign(3monocypher) and related functions.
The arguments are:
The hidden and curve arguments may overlap or point at the same buffer. RETURN VALUES
EXAMPLESGenerate a key pair manually using crypto_x25519_dirty_small(3monocypher) instead of its fast variant: 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_elligator_rev(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_elligator_map(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); SEE ALSOcrypto_x25519(3monocypher), crypto_x25519_dirty_small(3monocypher), intro(3monocypher) STANDARDSThese functions implement the Elligator 2 mapping for Curve25519. This mapping is incompatible with both the hash-to-curve Internet draft and the implementation of Elligator 2 in libsodium. Elligator 2 was described in: Daniel J. Bernstein, Mike Hamburg, Anna Krasnova, and Tanja Lange, Elligator: Elliptic-curve points indistinguishable from uniform random strings, Association for Computing Machinery, CCS '13: Proceedings of the 2013 ACM SIGSAC conference on Computer & communications security, pp. 967–980, 2013. Monocypher's Elligator 2 representatives are encoded as
little-endian 254-bit numbers. The two most significant bits (254 and 255)
are not used. HISTORYThe CAVEATSMonocypher does not perform any input validation. Any deviation from the specified input and output length ranges results in undefined behaviour. Make sure your inputs are correct. SECURITY CONSIDERATIONSThe secret keys for the public keys fed into
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.
|