diff --git a/crates/derive/keyfork-derive-openpgp/src/lib.rs b/crates/derive/keyfork-derive-openpgp/src/lib.rs index 0fa727f..acfcee0 100644 --- a/crates/derive/keyfork-derive-openpgp/src/lib.rs +++ b/crates/derive/keyfork-derive-openpgp/src/lib.rs @@ -110,9 +110,16 @@ pub fn derive(data: DerivationResponse, keys: &[KeyFlags], userid: &UserID) -> R let subkey = if is_enc && is_non_enc { return Err(Error::InvalidKeyFlags(subkey_flags.clone())); } else if is_enc { + // Clamp key before exporting as OpenPGP. Reference: + // https://gitlab.com/sequoia-pgp/sequoia/-/blob/main/openpgp/src/crypto/backend/rust/asymmetric.rs (see: generate_ecc constructor) + // https://github.com/jedisct1/libsodium/blob/b4c5d37fb5ee2736caa4823433926b588911e893/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c#L91-L93 + let mut bytes = PrivateKey::to_bytes(derived_key.private_key()); + bytes[0] &= 0b1111_1000; + bytes[31] &= !0b1000_0000; + bytes[31] |= 0b0100_0000; Key::from( Key4::<_, SubordinateRole>::import_secret_cv25519( - &PrivateKey::to_bytes(derived_key.private_key()), + &bytes, None, None, epoch,