Skip to content

Commit

Permalink
Introduce Public_Key::raw_public_key_bits()
Browse files Browse the repository at this point in the history
For most algorithms this returns the canonical byte encoding of the
public key's intrinsic object(s). This is particularly useful for the
algorithms of the PQC NIST competition where the public key encoding
is a simple byte-concatenation of the internal objects.

Some algorithm may not have such a canonical byte serialization and may
throw Not_Implemented in this case (e.g. RSA).

For Key Exchange Schemes this is returning the bare 'public_value'.
  • Loading branch information
reneme committed Apr 8, 2024
1 parent 637c117 commit 90ec5a4
Show file tree
Hide file tree
Showing 38 changed files with 149 additions and 99 deletions.
4 changes: 4 additions & 0 deletions src/lib/prov/pkcs11/p11_ecc_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ size_t PKCS11_EC_PrivateKey::key_length() const {
return m_domain_params.get_order().bits();
}

std::vector<uint8_t> PKCS11_EC_PrivateKey::raw_public_key_bits() const {
return public_point().encode(EC_Point_Format::Compressed);
}

std::vector<uint8_t> PKCS11_EC_PrivateKey::public_key_bits() const {
return public_point().encode(EC_Point_Format::Compressed);
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/prov/pkcs11/p11_ecc_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ class BOTAN_PUBLIC_API(2, 0) PKCS11_EC_PrivateKey : public virtual Private_Key,

// Private_Key methods

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

std::size_t key_length() const override;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/curve25519/curve25519.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ Curve25519_PublicKey::Curve25519_PublicKey(const AlgorithmIdentifier& /*unused*/
size_check(m_public.size(), "public key");
}

std::vector<uint8_t> Curve25519_PublicKey::raw_public_key_bits() const {
return m_public;
}

std::vector<uint8_t> Curve25519_PublicKey::public_key_bits() const {
return m_public;
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/curve25519/curve25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class BOTAN_PUBLIC_API(2, 0) Curve25519_PublicKey : public virtual Public_Key {

AlgorithmIdentifier algorithm_identifier() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

std::vector<uint8_t> public_value() const { return m_public; }
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/curve448/ed448/ed448.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ Ed448_PublicKey::Ed448_PublicKey(std::span<const uint8_t> key_bits) {
copy_mem(m_public, key_bits.first<ED448_LEN>());
}

std::vector<uint8_t> Ed448_PublicKey::raw_public_key_bits() const {
return {m_public.begin(), m_public.end()};
}

std::vector<uint8_t> Ed448_PublicKey::public_key_bits() const {
return {m_public.begin(), m_public.end()};
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/curve448/ed448/ed448.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class BOTAN_PUBLIC_API(3, 4) Ed448_PublicKey : public virtual Public_Key {

AlgorithmIdentifier algorithm_identifier() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

std::unique_ptr<Private_Key> generate_another(RandomNumberGenerator& rng) const final;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/curve448/x448/x448.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ bool X448_PublicKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/)
return true; // no tests possible?
}

std::vector<uint8_t> X448_PublicKey::raw_public_key_bits() const {
return public_value();
}

std::vector<uint8_t> X448_PublicKey::public_key_bits() const {
return public_value();
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/curve448/x448/x448.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class BOTAN_PUBLIC_API(3, 4) X448_PublicKey : public virtual Public_Key {

std::vector<uint8_t> public_value() const { return {m_public.begin(), m_public.end()}; }

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

bool supports_operation(PublicKeyOperation op) const override { return (op == PublicKeyOperation::KeyAgreement); }
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/dh/dh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ AlgorithmIdentifier DH_PublicKey::algorithm_identifier() const {
return AlgorithmIdentifier(object_identifier(), m_public_key->group().DER_encode(DL_Group_Format::ANSI_X9_42));
}

std::vector<uint8_t> DH_PublicKey::raw_public_key_bits() const {
return public_value();
}

std::vector<uint8_t> DH_PublicKey::public_key_bits() const {
return m_public_key->DER_encode();
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib/pubkey/dh/dh.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class BOTAN_PUBLIC_API(2, 0) DH_PublicKey : public virtual Public_Key {
DH_PublicKey(const DL_Group& group, const BigInt& y);

AlgorithmIdentifier algorithm_identifier() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator& rng, bool strong) const override;
Expand Down
6 changes: 6 additions & 0 deletions src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,13 @@ size_t Dilithium_PublicKey::estimated_strength() const {
return m_public->mode().nist_security_strength();
}

std::vector<uint8_t> Dilithium_PublicKey::raw_public_key_bits() const {
return m_public->raw_pk();
}

std::vector<uint8_t> Dilithium_PublicKey::public_key_bits() const {
// Technically, that's not really correct. The docstring for public_key_bits()
// states that it should return a BER-encoding of the public key.
return m_public->raw_pk();
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/dilithium/dilithium_common/dilithium.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class BOTAN_PUBLIC_API(3, 0) Dilithium_PublicKey : public virtual Public_Key {

size_t estimated_strength() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator&, bool) const override;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/dsa/dsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ AlgorithmIdentifier DSA_PublicKey::algorithm_identifier() const {
return AlgorithmIdentifier(object_identifier(), m_public_key->group().DER_encode(DL_Group_Format::ANSI_X9_57));
}

std::vector<uint8_t> DSA_PublicKey::raw_public_key_bits() const {
return m_public_key->public_key_as_bytes();
}

std::vector<uint8_t> DSA_PublicKey::public_key_bits() const {
return m_public_key->DER_encode();
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/dsa/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class BOTAN_PUBLIC_API(2, 0) DSA_PublicKey : public virtual Public_Key {
size_t message_part_size() const override;

AlgorithmIdentifier algorithm_identifier() const override;

std::vector<uint8_t> raw_public_key_bits() const override;
std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator& rng, bool strong) const override;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/ecc_key/ecc_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const {
return AlgorithmIdentifier(object_identifier(), DER_domain());
}

std::vector<uint8_t> EC_PublicKey::raw_public_key_bits() const {
return public_point().encode(point_encoding());
}

std::vector<uint8_t> EC_PublicKey::public_key_bits() const {
return public_point().encode(point_encoding());
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/ecc_key/ecc_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class BOTAN_PUBLIC_API(2, 0) EC_PublicKey : public virtual Public_Key {

AlgorithmIdentifier algorithm_identifier() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator& rng, bool strong) const override;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/ed25519/ed25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class BOTAN_PUBLIC_API(2, 2) Ed25519_PublicKey : public virtual Public_Key {

AlgorithmIdentifier algorithm_identifier() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

std::unique_ptr<Private_Key> generate_another(RandomNumberGenerator& rng) const final;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/ed25519/ed25519_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ Ed25519_PublicKey::Ed25519_PublicKey(const AlgorithmIdentifier& /*unused*/, std:
}
}

std::vector<uint8_t> Ed25519_PublicKey::raw_public_key_bits() const {
return m_public;
}

std::vector<uint8_t> Ed25519_PublicKey::public_key_bits() const {
return m_public;
}
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/elgamal/elgamal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ AlgorithmIdentifier ElGamal_PublicKey::algorithm_identifier() const {
return AlgorithmIdentifier(object_identifier(), m_public_key->group().DER_encode(DL_Group_Format::ANSI_X9_42));
}

std::vector<uint8_t> ElGamal_PublicKey::raw_public_key_bits() const {
return m_public_key->public_key_as_bytes();
}

std::vector<uint8_t> ElGamal_PublicKey::public_key_bits() const {
return m_public_key->DER_encode();
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/pubkey/elgamal/elgamal.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class BOTAN_PUBLIC_API(2, 0) ElGamal_PublicKey : public virtual Public_Key {
ElGamal_PublicKey(const DL_Group& group, const BigInt& y);

AlgorithmIdentifier algorithm_identifier() const override;
std::vector<uint8_t> raw_public_key_bits() const override;
std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator& rng, bool strong) const override;
Expand Down
8 changes: 7 additions & 1 deletion src/lib/pubkey/frodokem/frodokem_common/frodokem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,16 @@ size_t FrodoKEM_PublicKey::estimated_strength() const {
return m_public->constants().estimated_strength();
}

std::vector<uint8_t> FrodoKEM_PublicKey::public_key_bits() const {
std::vector<uint8_t> FrodoKEM_PublicKey::raw_public_key_bits() const {
return concat_as<std::vector<uint8_t>>(m_public->seed_a(), m_public->b().pack(m_public->constants()));
}

std::vector<uint8_t> FrodoKEM_PublicKey::public_key_bits() const {
// Technically, that's not really correct. The docstring for public_key_bits()
// states that it should return a BER-encoding of the public key.
return raw_public_key_bits();
}

bool FrodoKEM_PublicKey::check_key(RandomNumberGenerator&, bool) const {
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/frodokem/frodokem_common/frodokem.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class BOTAN_PUBLIC_API(3, 3) FrodoKEM_PublicKey : public virtual Public_Key {

size_t estimated_strength() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator&, bool) const override;
Expand Down
20 changes: 9 additions & 11 deletions src/lib/pubkey/kyber/kyber_common/kyber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1133,7 +1133,7 @@ class Kyber_KEM_Encryptor final : public PK_Ops::KEM_Encryption_with_KDF,

// Multitarget countermeasure for coins + contributory KEM
G->update(shared_secret);
G->update(m_key.H_public_key_bits_raw());
G->update(m_key.m_public->H_public_key_bits_raw());
const auto g_out = G->final();

BOTAN_ASSERT_EQUAL(g_out.size(), 64, "Expected output length of Kyber G");
Expand Down Expand Up @@ -1178,7 +1178,7 @@ class Kyber_KEM_Decryptor final : public PK_Ops::KEM_Decryption_with_KDF,

// Multitarget countermeasure for coins + contributory KEM
G->update(shared_secret);
G->update(m_key.H_public_key_bits_raw());
G->update(m_key.m_public->H_public_key_bits_raw());

const auto g_out = G->final();

Expand Down Expand Up @@ -1260,16 +1260,14 @@ Kyber_PublicKey::Kyber_PublicKey(std::span<const uint8_t> pub_key, KyberMode m)
Kyber_PublicKey::Kyber_PublicKey(const Kyber_PublicKey& other) :
m_public(std::make_shared<Kyber_PublicKeyInternal>(*other.m_public)) {}

std::vector<uint8_t> Kyber_PublicKey::public_key_bits() const {
return public_key_bits_raw();
}

const std::vector<uint8_t>& Kyber_PublicKey::public_key_bits_raw() const {
std::vector<uint8_t> Kyber_PublicKey::raw_public_key_bits() const {
return m_public->public_key_bits_raw();
}

const std::vector<uint8_t>& Kyber_PublicKey::H_public_key_bits_raw() const {
return m_public->H_public_key_bits_raw();
std::vector<uint8_t> Kyber_PublicKey::public_key_bits() const {
// Technically, that's not really correct. The docstring for public_key_bits()
// states that it should return a BER-encoding of the public key.
return raw_public_key_bits();
}

size_t Kyber_PublicKey::key_length() const {
Expand Down Expand Up @@ -1349,8 +1347,8 @@ secure_vector<uint8_t> Kyber_PrivateKey::raw_private_key_bits() const {

secure_vector<uint8_t> Kyber_PrivateKey::private_key_bits() const {
return concat(m_private->polynomials().to_bytes<secure_vector<uint8_t>>(),
public_key_bits_raw(),
H_public_key_bits_raw(),
m_public->public_key_bits_raw(),
m_public->H_public_key_bits_raw(),
m_private->z());
}

Expand Down
5 changes: 2 additions & 3 deletions src/lib/pubkey/kyber/kyber_common/kyber.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class BOTAN_PUBLIC_API(3, 0) Kyber_PublicKey : public virtual Public_Key {

size_t estimated_strength() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator&, bool) const override;
Expand All @@ -115,9 +117,6 @@ class BOTAN_PUBLIC_API(3, 0) Kyber_PublicKey : public virtual Public_Key {
static std::shared_ptr<Kyber_PublicKeyInternal> initialize_from_encoding(std::span<const uint8_t> pub_key,
KyberMode m);

const std::vector<uint8_t>& public_key_bits_raw() const;
const std::vector<uint8_t>& H_public_key_bits_raw() const;

protected:
friend class Kyber_KEM_Encryptor;
friend class Kyber_KEM_Decryptor;
Expand Down
1 change: 1 addition & 0 deletions src/lib/pubkey/mce/mceliece.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class BOTAN_PUBLIC_API(2, 0) McEliece_PublicKey : public virtual Public_Key {
size_t key_length() const override;
size_t estimated_strength() const override;

std::vector<uint8_t> raw_public_key_bits() const override;
std::vector<uint8_t> public_key_bits() const override;

bool check_key(RandomNumberGenerator&, bool) const override { return true; }
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/mce/mceliece_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ AlgorithmIdentifier McEliece_PublicKey::algorithm_identifier() const {
return AlgorithmIdentifier(object_identifier(), AlgorithmIdentifier::USE_EMPTY_PARAM);
}

std::vector<uint8_t> McEliece_PublicKey::raw_public_key_bits() const {
return m_public_matrix;
}

std::vector<uint8_t> McEliece_PublicKey::public_key_bits() const {
std::vector<uint8_t> output;
DER_Encoder(output)
Expand Down
11 changes: 11 additions & 0 deletions src/lib/pubkey/pk_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ class BOTAN_PUBLIC_API(2, 0) Public_Key : public virtual Asymmetric_Key {
*/
virtual AlgorithmIdentifier algorithm_identifier() const = 0;

/**
* @return binary public key bits, with no additional encoding
*
* For key agreements this is an alias for PK_Key_Agreement_Key::public_value.
*
* Note: some algorithms (for example RSA) do not have an obvious encoding
* for this value due to having many different values, and thus not implement
* this function.
*/
virtual std::vector<uint8_t> raw_public_key_bits() const = 0;

/**
* @return BER encoded public key bits
*/
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pubkey/rsa/rsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ AlgorithmIdentifier RSA_PublicKey::algorithm_identifier() const {
return AlgorithmIdentifier(object_identifier(), AlgorithmIdentifier::USE_NULL_PARAM);
}

std::vector<uint8_t> RSA_PublicKey::raw_public_key_bits() const {
throw Not_Implemented("an RSA public key does not provide a raw binary representation.");
}

std::vector<uint8_t> RSA_PublicKey::public_key_bits() const {
std::vector<uint8_t> output;
DER_Encoder der(output);
Expand Down
2 changes: 2 additions & 0 deletions src/lib/pubkey/rsa/rsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class BOTAN_PUBLIC_API(2, 0) RSA_PublicKey : public virtual Public_Key {

AlgorithmIdentifier algorithm_identifier() const override;

std::vector<uint8_t> raw_public_key_bits() const override;

std::vector<uint8_t> public_key_bits() const override;

/**
Expand Down
6 changes: 6 additions & 0 deletions src/lib/pubkey/sphincsplus/sphincsplus_common/sphincsplus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,13 @@ bool SphincsPlus_PublicKey::check_key(RandomNumberGenerator&, bool) const {
return true;
}

std::vector<uint8_t> SphincsPlus_PublicKey::raw_public_key_bits() const {
return m_public->key_bits();
}

std::vector<uint8_t> SphincsPlus_PublicKey::public_key_bits() const {
// Technically, that's not really correct. The docstring for public_key_bits()
// states that it should return a BER-encoding of the public key.
return m_public->key_bits();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class BOTAN_PUBLIC_API(3, 1) SphincsPlus_PublicKey : public virtual Public_Key {
AlgorithmIdentifier algorithm_identifier() const override;
OID object_identifier() const override;
bool check_key(RandomNumberGenerator& rng, bool strong) const override;
std::vector<uint8_t> raw_public_key_bits() const override;
std::vector<uint8_t> public_key_bits() const override;

std::unique_ptr<Private_Key> generate_another(RandomNumberGenerator& rng) const final;
Expand Down
Loading

0 comments on commit 90ec5a4

Please sign in to comment.