X25519: optionally use unclamped private keys
#30.831 aberto em 15 de abr. de 2026
Métricas do repositório
- Stars
- (30.157 stars)
- Métricas de merge de PR
- (Nenhuma PRs mesclada em 30d)
Description
Request
This issue requests the optional feature to perform X25519 operations, specifically scalar-point multiplications, without "clamping" the private key. Currently, in all exposed operations, the private key is implicitly clamped, even if the bits in the key differ:
Proposed path
The X25519 functions could take a unsigned char disclamp parameter, defaulting to 0. If the 0th-2nd bits (0-indexed) are set, then the 3 LSBs of the private key aren't cleared inside the operation. If the 6th bit of disclamp is set, then the 254th bit of the private isn't set. So a fully unclamped scalar-point multiplication would use disclamp=0x47. A scalar-point multiplication with a torsion clear, but without the 254th bit set would use disclamp=0x07. I don't think it makes sense in any real application to allow the 255th bit to be set. So the clamp function would look something like this:
void clamp_curve25519_privkey(unsigned char k[32], const unsigned char disclamp)
{
k[31] &= 0x7f;
k[31] |= (0x40 & ~disclamp);
k[0] &= (0xf8 | disclamp);
}
Since this affects the derivation of the public key, the disclamp parameter should probably be a configuration value attached to the key pair (e.g. EVP_PKEY), and not an operation context (e.g. EVP_PKEY_CTX).
Example use cases
Most Ed25519 implementations generate and use private keys without the key clamping specified in the RPC for X25519. Giving the option to use X25519 without key clamping allows one to use an already-generated Ed25519 key pair to do X25519 ECDH key exchanges. It also allows for "inverse" ECDH key exchanges, where knowing $a, Q$ s.t. $Q = a P$, one can calculate $P = a^{-1} Q$. It is difficult to find an inverse of a private key when the 254th bit of the key is clamped.