Skip to content

Commit

Permalink
Doc: examples how to load raw ECC keys
Browse files Browse the repository at this point in the history
This does come up as usage questions occasionally (randombit#3137, randombit#4224)
  • Loading branch information
reneme committed Jul 18, 2024
1 parent 3fa7718 commit 92c6dc1
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/examples/ecc_raw_private_key.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <botan/bigint.h>
#include <botan/ecdh.h>
#include <botan/hex.h>
#include <botan/pkcs8.h>
#include <botan/rng.h>
#include <botan/x509_key.h>

#include <iostream>
#include <string>

int main() {
const std::string curve_name = "secp256r1";
const auto private_scalar_bytes =
Botan::hex_decode("D2AC61C35CAEE918E47B0BD5E61DA9B3A5C2964AB317647DEF6DFC042A06C829");

Botan::Null_RNG null_rng;
const auto domain = Botan::EC_Group::from_name(curve_name);
const auto private_scalar = Botan::BigInt(private_scalar_bytes);

// This loads the private scalar into an ECDH_PrivateKey. Creating an
// ECDSA_PrivateKey would work the same way.
const auto private_key = Botan::ECDH_PrivateKey(null_rng, domain, private_scalar);
const auto public_key = private_key.public_key();

std::cout << "Private Key (PEM):\n\n" << Botan::PKCS8::PEM_encode(private_key) << '\n';
std::cout << "Public Key (PEM):\n\n" << Botan::X509::PEM_encode(*public_key) << '\n';
}
32 changes: 32 additions & 0 deletions src/examples/ecc_raw_public_key.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <botan/ecdsa.h>
#include <botan/hex.h>
#include <botan/x509_key.h>

#include <iostream>
#include <span>
#include <string>
#include <vector>

std::vector<uint8_t> to_uncompress_point_encoding(std::span<const uint8_t> x, std::span<const uint8_t> y) {
std::vector<uint8_t> public_key_bytes;
public_key_bytes.reserve(x.size() + y.size() + 1);
public_key_bytes.push_back(0x04); // means: uncompressed point encoding
public_key_bytes.insert(public_key_bytes.end(), x.begin(), x.end());
public_key_bytes.insert(public_key_bytes.end(), y.begin(), y.end());
return public_key_bytes;
}

int main() {
const std::string curve_name = "secp256r1";
const auto public_x_bytes = Botan::hex_decode("278309D4A88ADF89CA0E5328D3B655CF8949F2D9F9B2308AA22FE28202A315EC");
const auto public_y_bytes = Botan::hex_decode("AC457F18D1F3675D46E98ED2E509EE47AC2CB9A012F73263B30CD7248AEA6020");

const auto domain = Botan::EC_Group::from_name(curve_name);
const auto encoded_public_point = to_uncompress_point_encoding(public_x_bytes, public_y_bytes);

// This loads the public point into an ECDSA_PublicKey. Creating an
// ECDH_PublicKey would work the same way.
const auto public_key = Botan::ECDSA_PublicKey(domain, domain.OS2ECP(encoded_public_point));

std::cout << "Public Key (PEM):\n\n" << Botan::X509::PEM_encode(public_key) << '\n';
}

0 comments on commit 92c6dc1

Please sign in to comment.