aboutsummaryrefslogtreecommitdiffstats
path: root/src/cmd
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-09-22 12:10:24 -0400
committerJack Lloyd <[email protected]>2015-09-29 17:57:50 -0400
commit2a6f5f10cc9713230bdd6204c57219451584f4a4 (patch)
tree804a78cbd34d69f01aed3a337fd4a693c59297bc /src/cmd
parentac9689990da914cd58788dab9d5e0d7bebb72e30 (diff)
McEliece cleanups
Remove and consolidate various headers Reduce memory usage of GF2m_Field by sharing the log and exponent tables across all instances of a particular word size. Remove McEliece_Public_Operation and McEliece_Private_Operation which were difficult to use safely. Instead only the KEM operations are exposed. Add McEliece_PublicKey::random_plaintext_element Add command line `mce` tool and some McEliece documentation Convert the speed program to check McEliece keys of the suggested size Add McEliece KATs for both key generation and KEM Fix HMAC_DRBG constructor which derefed a pointer before its time
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/implementation/speed_public_key.cpp19
-rw-r--r--src/cmd/mce.cpp117
2 files changed, 127 insertions, 9 deletions
diff --git a/src/cmd/implementation/speed_public_key.cpp b/src/cmd/implementation/speed_public_key.cpp
index 73bbd7c1e..83c0156ae 100644
--- a/src/cmd/implementation/speed_public_key.cpp
+++ b/src/cmd/implementation/speed_public_key.cpp
@@ -734,20 +734,21 @@ void benchmark_mce(RandomNumberGenerator& rng,
Benchmark_Report& report)
{
const std::vector<std::pair<size_t, size_t>> params = {
- { 1024, 35 },
- { 2048, 50 },
- { 2960, 56 },
+ { 1632, 33 },
+ { 2480, 45 },
+ { 2960, 57 },
+ { 3408, 67 },
+ { 4264, 95 },
{ 6624, 115 }
};
const std::string algo_name = "McEliece";
- const std::string padding = "Raw";
for(auto& param : params)
{
Timer keygen_timer("keygen");
- Timer enc_timer(padding + " encrypt");
- Timer dec_timer(padding + " decrypt");
+ Timer enc_timer("encrypt");
+ Timer dec_timer("decrypt");
keygen_timer.start();
McEliece_PrivateKey priv_key(rng, param.first, param.second);
@@ -776,9 +777,9 @@ void benchmark_mce(RandomNumberGenerator& rng,
std::to_string(param.second);
std::ostringstream keysize_report;
- keysize_report << "(size " << pub_key.x509_subject_public_key().size() << " pub "
- << priv_key.pkcs8_private_key().size() << " priv "
- << pub_key.estimated_strength() << " work factor)";
+ keysize_report << "(work factor " << pub_key.estimated_strength() << ", "
+ << "pub bytes " << pub_key.x509_subject_public_key().size() << " "
+ << "priv bytes " << priv_key.pkcs8_private_key().size() << ")";
report.report(nm + " " + keysize_report.str(), keygen_timer);
report.report(nm, enc_timer);
diff --git a/src/cmd/mce.cpp b/src/cmd/mce.cpp
new file mode 100644
index 000000000..3b33df661
--- /dev/null
+++ b/src/cmd/mce.cpp
@@ -0,0 +1,117 @@
+#include "apps.h"
+
+#if defined(BOTAN_HAS_MCELIECE)
+
+#include <botan/mceliece.h>
+#include <botan/mceies.h>
+#include <botan/pkcs8.h>
+#include <fstream>
+
+namespace {
+
+int mce(int argc, char* argv[])
+ {
+ if(argc < 4)
+ {
+ std::cout << "Usage: " << argv[0] << " [keygen n t pass|keybits n t|encrypt file key|decrypt file key pass]\n";
+ return 1;
+ }
+
+ const std::string cmd = argv[1];
+
+ AutoSeeded_RNG rng;
+
+ if(cmd == "keygen")
+ {
+ const size_t n = std::stol(argv[2]);
+ const size_t t = std::stol(argv[3]);
+ const std::string pass = argv[4];
+
+ McEliece_PrivateKey pk(rng, n, t);
+
+ bool ok = pk.check_key(rng, true);
+
+ if(!ok)
+ {
+ std::cout << "Keygen failed self-test\n";
+ return 2;
+ }
+
+ /*
+ secure_vector<byte> priv = PKCS8::BER_encode(pk);
+ std::vector<byte> pub = X509::BER_encode(pk);
+ std::cout << priv.size()/1024.0 << " " << pub.size()/1024.0 << "\n";
+ */
+
+ std::ofstream pub_file("mce.pub");
+ pub_file << X509::PEM_encode(pk);
+ pub_file.close();
+
+ std::ofstream priv_file("mce.priv");
+ priv_file << PKCS8::PEM_encode(pk, rng, pass);
+ priv_file.close();
+ }
+ else if(cmd == "keybits")
+ {
+ const size_t n = std::stol(argv[2]);
+ const size_t t = std::stol(argv[3]);
+ std::cout << "McEliece key with params (" << n << "," << t << ") has "
+ << mceliece_work_factor(n, t) << " bit security\n";
+ }
+ else if(cmd == "encrypt")
+ {
+ std::unique_ptr<Public_Key> p8(X509::load_key(argv[3]));
+ const McEliece_PublicKey* key = dynamic_cast<McEliece_PublicKey*>(p8.get());
+
+ if(!key)
+ {
+ throw std::runtime_error("Loading McEliece public key failed");
+ }
+
+ const std::string input_path = argv[2];
+ std::ifstream in(input_path, std::ios::binary);
+ std::string pt((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
+
+ secure_vector<byte> ct = mceies_encrypt(*key,
+ reinterpret_cast<const byte*>(pt.data()),
+ pt.size(),
+ nullptr, 0, rng, "AES-128/GCM");
+
+ std::cout << pt.size() << " -> " << ct.size() << "\n";
+
+ std::ofstream out(std::string(input_path) + ".ct", std::ios::binary);
+ out.write(reinterpret_cast<const char*>(ct.data()), ct.size());
+ out.close();
+ }
+ else if(cmd == "decrypt")
+ {
+ const std::string key_file = argv[3];
+ const std::string pass = argv[4];
+ std::unique_ptr<Private_Key> p8(PKCS8::load_key(key_file, rng, pass));
+ const McEliece_PrivateKey* key = dynamic_cast<McEliece_PrivateKey*>(p8.get());
+
+ if(!key)
+ {
+ throw std::runtime_error("Loading McEliece private key failed");
+ }
+
+ std::ifstream in(argv[2], std::ios::binary);
+ std::string ct((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
+
+ secure_vector<byte> pt = mceies_decrypt(*key,
+ reinterpret_cast<const byte*>(ct.data()),
+ ct.size(),
+ nullptr, 0, "AES-128/GCM");
+
+ std::ofstream out("mce.plaintext", std::ios::binary);
+ out.write(reinterpret_cast<const char*>(pt.data()), pt.size());
+ out.close();
+ }
+ return 0;
+ }
+
+}
+
+REGISTER_APP(mce);
+
+#endif