From 6fd80726a4d0aeeec263b2127366cca42936b4f0 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Fri, 31 Jul 2020 16:11:32 +0200 Subject: openpgp: Add and use MPI::new_compressed_point. --- openpgp/src/crypto/backend/nettle/asymmetric.rs | 29 ++++++++++--------------- openpgp/src/crypto/backend/nettle/ecdh.rs | 9 ++++---- openpgp/src/crypto/mpi.rs | 19 ++++++++++++++++ 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/openpgp/src/crypto/backend/nettle/asymmetric.rs b/openpgp/src/crypto/backend/nettle/asymmetric.rs index c2af71e8..d2f8e29b 100644 --- a/openpgp/src/crypto/backend/nettle/asymmetric.rs +++ b/openpgp/src/crypto/backend/nettle/asymmetric.rs @@ -376,8 +376,8 @@ impl Key4 S: Into>, T: Into> { - let mut public_key = [0x40u8; curve25519::CURVE25519_SIZE + 1]; - curve25519::mul_g(&mut public_key[1..], private_key).unwrap(); + let mut public_key = [0; curve25519::CURVE25519_SIZE]; + curve25519::mul_g(&mut public_key, private_key).unwrap(); let mut private_key = Vec::from(private_key); private_key.reverse(); @@ -389,7 +389,7 @@ impl Key4 curve: Curve::Cv25519, hash: hash.into().unwrap_or(HashAlgorithm::SHA512), sym: sym.into().unwrap_or(SymmetricAlgorithm::AES256), - q: mpi::MPI::new(&public_key), + q: MPI::new_compressed_point(&public_key), }, mpi::SecretKeyMaterial::ECDH { scalar: private_key.into(), @@ -405,15 +405,15 @@ impl Key4 pub fn import_secret_ed25519(private_key: &[u8], ctime: T) -> Result where T: Into> { - let mut public_key = [0x40u8; ed25519::ED25519_KEY_SIZE + 1]; - ed25519::public_key(&mut public_key[1..], private_key).unwrap(); + let mut public_key = [0; ed25519::ED25519_KEY_SIZE]; + ed25519::public_key(&mut public_key, private_key).unwrap(); Self::with_secret( ctime.into().unwrap_or_else(SystemTime::now), PublicKeyAlgorithm::EdDSA, mpi::PublicKey::EdDSA { curve: Curve::Ed25519, - q: mpi::MPI::new(&public_key), + q: MPI::new_compressed_point(&public_key), }, mpi::SecretKeyMaterial::EdDSA { scalar: mpi::MPI::new(private_key).into(), @@ -484,16 +484,14 @@ impl Key4 let (mpis, secret, pk_algo) = match (curve.clone(), for_signing) { (Curve::Ed25519, true) => { - let mut public = [0u8; ed25519::ED25519_KEY_SIZE + 1]; + let mut public = [0; ed25519::ED25519_KEY_SIZE]; let private: Protected = ed25519::private_key(&mut rng).into(); - - public[0] = 0x40; - ed25519::public_key(&mut public[1..], &private)?; + ed25519::public_key(&mut public, &private)?; let public_mpis = PublicKey::EdDSA { curve: Curve::Ed25519, - q: MPI::new(&public), + q: MPI::new_compressed_point(&public), }; let private_mpis = mpi::SecretKeyMaterial::EdDSA { scalar: private.into(), @@ -504,13 +502,10 @@ impl Key4 } (Curve::Cv25519, false) => { - let mut public = [0u8; curve25519::CURVE25519_SIZE + 1]; + let mut public = [0; curve25519::CURVE25519_SIZE]; let mut private: Protected = curve25519::private_key(&mut rng).into(); - - public[0] = 0x40; - - curve25519::mul_g(&mut public[1..], &private)?; + curve25519::mul_g(&mut public, &private)?; // Reverse the scalar. See // https://lists.gnupg.org/pipermail/gnupg-devel/2018-February/033437.html. @@ -518,7 +513,7 @@ impl Key4 let public_mpis = PublicKey::ECDH { curve: Curve::Cv25519, - q: MPI::new(&public), + q: MPI::new_compressed_point(&public), hash: HashAlgorithm::SHA256, sym: SymmetricAlgorithm::AES256, }; diff --git a/openpgp/src/crypto/backend/nettle/ecdh.rs b/openpgp/src/crypto/backend/nettle/ecdh.rs index d6062789..7e8f6b00 100644 --- a/openpgp/src/crypto/backend/nettle/ecdh.rs +++ b/openpgp/src/crypto/backend/nettle/ecdh.rs @@ -31,12 +31,11 @@ pub fn encrypt(recipient: &Key, let v: Protected = curve25519::private_key(&mut rng).into(); - // Compute the public key. We need to add an encoding - // octet in front of the key. - let mut VB = [0x40; 1 + curve25519::CURVE25519_SIZE]; - curve25519::mul_g(&mut VB[1..], &v) + // Compute the public key. + let mut VB = [0; curve25519::CURVE25519_SIZE]; + curve25519::mul_g(&mut VB, &v) .expect("buffers are of the wrong size"); - let VB = MPI::new(&VB); + let VB = MPI::new_compressed_point(&VB); // Compute the shared point S = vR; let mut S: Protected = diff --git a/openpgp/src/crypto/mpi.rs b/openpgp/src/crypto/mpi.rs index b2610810..1f19b382 100644 --- a/openpgp/src/crypto/mpi.rs +++ b/openpgp/src/crypto/mpi.rs @@ -71,6 +71,25 @@ impl MPI { } } + /// Creates new MPI encoding a compressed EC point using native + /// encoding. + /// + /// Encodes the given point on a elliptic curve (see [Section 13.2 + /// of RFC4880bis] for details). This is used to encode public + /// keys and ciphertexts for the Bernstein curves (currently + /// `X25519`). + /// + /// [Section 13.2 of RFC4880bis]: https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-09#section-13.2 + pub fn new_compressed_point(x: &[u8]) -> Self { + let mut val = vec![0; 1 + x.len()]; + val[0] = 0x40; + val[1..].copy_from_slice(x); + + MPI { + value: val.into_boxed_slice(), + } + } + /// Returns the length of the MPI in bits. pub fn bits(&self) -> usize { self.value.len() * 8 -- cgit v1.2.3