aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/ec_tests.cpp80
-rw-r--r--checks/ecdsa.cpp164
-rw-r--r--checks/pk.cpp54
-rw-r--r--checks/pk_valid.dat18
-rw-r--r--src/pubkey/dsa/dsa.cpp18
-rw-r--r--src/pubkey/dsa/dsa.h3
-rw-r--r--src/pubkey/ecc_key/ecc_key.cpp11
-rw-r--r--src/pubkey/ecc_key/ecc_key.h1
-rw-r--r--src/pubkey/ecdsa/ecdsa.cpp41
-rw-r--r--src/pubkey/ecdsa/ecdsa.h10
-rw-r--r--src/pubkey/gost_3410/gost_3410.cpp40
-rw-r--r--src/pubkey/gost_3410/gost_3410.h9
-rw-r--r--src/pubkey/nr/nr.cpp18
-rw-r--r--src/pubkey/nr/nr.h5
-rw-r--r--src/pubkey/pk_ops.h25
-rw-r--r--src/pubkey/rsa/rsa.cpp11
-rw-r--r--src/pubkey/rsa/rsa.h3
17 files changed, 153 insertions, 358 deletions
diff --git a/checks/ec_tests.cpp b/checks/ec_tests.cpp
index f378de8a4..0532e35fe 100644
--- a/checks/ec_tests.cpp
+++ b/checks/ec_tests.cpp
@@ -847,84 +847,6 @@ void test_curve_cp_ctor()
CurveGFp curve(dom_pars.get_curve());
}
-/**
-* The following test checks assignment operator and copy ctor for ec keys
-*/
-void test_ec_key_cp_and_assignment(RandomNumberGenerator& rng)
- {
- std::cout << "." << std::flush;
-
-
- std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82");
- SecureVector<byte> sv_g_secp = decode_hex ( g_secp);
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
-
- BigInt cofactor = BigInt(1);
- PointGFp p_G = OS2ECP ( sv_g_secp, curve );
-
- EC_Domain_Params dom_pars = EC_Domain_Params(curve, p_G, order, cofactor);
- ECDSA_PrivateKey my_priv_key(rng, dom_pars);
-
- std::string str_message = ("12345678901234567890abcdef12");
- SecureVector<byte> sv_message = decode_hex(str_message);
-
- // sign with the original key
- SecureVector<byte> signature = my_priv_key.sign(sv_message.begin(), sv_message.size(), rng);
- bool ver_success = my_priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size());
- CHECK_MESSAGE(ver_success, "generated signature could not be verified positively");
-
- // make a copy and sign
- ECDSA_PrivateKey cp_key(my_priv_key);
- SecureVector<byte> cp_sig = cp_key.sign(sv_message.begin(), sv_message.size(), rng);
-
- // now cross verify...
- CHECK(my_priv_key.verify(sv_message.begin(), sv_message.size(), cp_sig.begin(), cp_sig.size()));
- CHECK(cp_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()));
-
- // make an copy assignment and verify
- ECDSA_PrivateKey ass_key = my_priv_key;
- SecureVector<byte> ass_sig = ass_key.sign(sv_message.begin(), sv_message.size(), rng);
-
- // now cross verify...
- CHECK(my_priv_key.verify(sv_message.begin(), sv_message.size(), ass_sig.begin(), ass_sig.size()));
- CHECK(ass_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size()));
- }
-
-void test_ec_key_cast(RandomNumberGenerator& rng)
- {
- std::cout << "." << std::flush;
-
- std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82");
- SecureVector<byte> sv_g_secp = decode_hex ( g_secp);
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- BigInt cofactor = BigInt(1);
- PointGFp p_G = OS2ECP ( sv_g_secp, curve );
-
- EC_Domain_Params dom_pars = EC_Domain_Params(curve, p_G, order, cofactor);
- ECDSA_PrivateKey my_priv_key(rng, dom_pars);
- ECDSA_PublicKey my_ecdsa_pub_key = my_priv_key;
-
- Public_Key* my_pubkey = static_cast<Public_Key*>(&my_ecdsa_pub_key);
- ECDSA_PublicKey* ec_cast_back = dynamic_cast<ECDSA_PublicKey*>(my_pubkey);
-
- std::string str_message = ("12345678901234567890abcdef12");
- SecureVector<byte> sv_message = decode_hex(str_message);
-
- // sign with the original key
- SecureVector<byte> signature = my_priv_key.sign(sv_message.begin(), sv_message.size(), rng);
-
- bool ver_success = ec_cast_back->verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size());
- CHECK_MESSAGE(ver_success, "generated signature could not be verified positively");
- }
-
}
void do_ec_tests(RandomNumberGenerator& rng)
@@ -955,8 +877,6 @@ void do_ec_tests(RandomNumberGenerator& rng)
test_point_swap(rng);
test_mult_sec_mass(rng);
test_curve_cp_ctor();
- test_ec_key_cp_and_assignment(rng);
- test_ec_key_cast(rng);
std::cout << std::endl;
}
diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp
index 64ac4be6b..036cc4dd1 100644
--- a/checks/ecdsa.cpp
+++ b/checks/ecdsa.cpp
@@ -116,35 +116,6 @@ void test_hash_larger_than_n(RandomNumberGenerator& rng)
std::cout << "Corrupt ECDSA signature verified, should not have\n";
}
-/**
-* Tests whether the the signing routine will work correctly in case the integer e
-* that is constructed from the message is larger than n, the order of the base point
-*/
-void test_message_larger_than_n(RandomNumberGenerator& rng)
- {
- std::cout << "." << std::flush;
-
- EC_Domain_Params dom_pars(OID("1.3.132.0.8"));
- ECDSA_PrivateKey priv_key(rng, dom_pars);
- std::string str_message = ("12345678901234567890abcdef1212345678901234567890abcdef1212345678901234567890abcdef12");
-
- SecureVector<byte> sv_message = decode_hex(str_message);
- bool thrn = false;
- SecureVector<byte> signature;
- try
- {
- signature = priv_key.sign(sv_message.begin(), sv_message.size(), rng);
- }
- catch (Invalid_Argument e)
- {
- thrn = true;
- }
- //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n";
- bool ver_success = priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size());
- CHECK_MESSAGE(ver_success, "generated signature could not be verified positively");
- //CHECK_MESSAGE(thrn, "no exception was thrown although message to sign was too long");
- }
-
void test_decode_ecdsa_X509()
{
std::cout << "." << std::flush;
@@ -187,30 +158,28 @@ void test_decode_ver_link_SHA1()
void test_sign_then_ver(RandomNumberGenerator& rng)
{
- std::cout << "." << std::flush;
+ std::cout << '.' << std::flush;
- std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82");
- SecureVector<byte> sv_g_secp = decode_hex(g_secp);
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- BigInt cofactor = BigInt(1);
- PointGFp p_G = OS2ECP ( sv_g_secp, curve );
-
- EC_Domain_Params dom_pars = EC_Domain_Params(curve, p_G, order, cofactor);
- ECDSA_PrivateKey my_priv_key(rng, dom_pars);
-
- std::string str_message = ("12345678901234567890abcdef12");
- SecureVector<byte> sv_message = decode_hex(str_message);
- SecureVector<byte> signature = my_priv_key.sign(sv_message.begin(), sv_message.size(), rng);
- //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n";
- bool ver_success = my_priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size());
- CHECK_MESSAGE(ver_success, "generated signature could not be verified positively");
- signature[signature.size()-1] += 0x01;
- bool ver_must_fail = my_priv_key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size());
- CHECK_MESSAGE(!ver_must_fail, "corrupted signature could be verified positively");
+ EC_Domain_Params dom_pars(OID("1.3.132.0.8"));
+ ECDSA_PrivateKey ecdsa(rng, dom_pars);
+
+ std::auto_ptr<PK_Signer> signer(get_pk_signer(ecdsa, "EMSA1(SHA-1)"));
+
+ SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12");
+ SecureVector<byte> sig = signer->sign_message(msg, rng);
+
+ std::auto_ptr<PK_Verifier> verifier(get_pk_verifier(ecdsa, "EMSA1(SHA-1)"));
+
+ bool ok = verifier->verify_message(msg, sig);
+
+ if(!ok)
+ std::cout << "ERROR: Could not verify ECDSA signature\n";
+
+ sig[0]++;
+ ok = verifier->verify_message(msg, sig);
+
+ if(ok)
+ std::cout << "ERROR: Bogus ECDSA signature verified anyway\n";
}
bool test_ec_sign(RandomNumberGenerator& rng)
@@ -392,13 +361,16 @@ void test_curve_registry(RandomNumberGenerator& rng)
OID oid(oids[i]);
EC_Domain_Params dom_pars(oid);
dom_pars.get_base_point().check_invariants();
- ECDSA_PrivateKey key(rng, dom_pars);
+ ECDSA_PrivateKey ecdsa(rng, dom_pars);
- std::string str_message = ("12345678901234567890abcdef12");
- SecureVector<byte> sv_message = decode_hex(str_message);
- SecureVector<byte> signature = key.sign(sv_message.begin(), sv_message.size(), rng);
- bool ver_success = key.verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size());
- CHECK_MESSAGE(ver_success, "generated signature could not be verified positively");
+ std::auto_ptr<PK_Signer> signer(get_pk_signer(ecdsa, "EMSA1(SHA-1)"));
+ std::auto_ptr<PK_Verifier> verifier(get_pk_verifier(ecdsa, "EMSA1(SHA-1)"));
+
+ SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12");
+ SecureVector<byte> sig = signer->sign_message(msg, rng);
+
+ if(!verifier->verify_message(msg, sig))
+ std::cout << "Failed testing ECDSA sig for curve " << oids[i] << "\n";
}
catch(Invalid_Argument& e)
{
@@ -414,28 +386,37 @@ void test_read_pkcs8(RandomNumberGenerator& rng)
try
{
std::auto_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
- ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get());
- CHECK_MESSAGE(loaded_ec_key, "the loaded key could not be converted into an ECDSA_PrivateKey");
+ ECDSA_PrivateKey* ecdsa = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get());
+ CHECK_MESSAGE(ecdsa, "the loaded key could not be converted into an ECDSA_PrivateKey");
+
+ std::auto_ptr<PK_Signer> signer(get_pk_signer(*ecdsa, "EMSA1(SHA-1)"));
+
+ SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12");
+ SecureVector<byte> sig = signer->sign_message(msg, rng);
- std::string str_message = ("12345678901234567890abcdef12");
- SecureVector<byte> sv_message = decode_hex(str_message);
- SecureVector<byte> signature = loaded_ec_key->sign(sv_message.begin(), sv_message.size(), rng);
- //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n";
- bool ver_success = loaded_ec_key->verify(sv_message.begin(), sv_message.size(), signature.begin(), signature.size());
- CHECK_MESSAGE(ver_success, "generated signature could not be verified positively");
+ std::auto_ptr<PK_Verifier> verifier(get_pk_verifier(*ecdsa, "EMSA1(SHA-1)"));
+
+ bool ok = verifier->verify_message(msg, sig);
+
+ CHECK_MESSAGE(ok, "generated sig could not be verified positively");
std::auto_ptr<PKCS8_PrivateKey> loaded_key_nodp(PKCS8::load_key(TEST_DATA_DIR "/nodompar_private.pkcs8.pem", rng));
// anew in each test with unregistered domain-parameters
- ECDSA_PrivateKey* loaded_ec_key_nodp = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_nodp.get());
- CHECK_MESSAGE(loaded_ec_key_nodp, "the loaded key could not be converted into an ECDSA_PrivateKey");
+ ECDSA_PrivateKey* ecdsa_nodp = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_nodp.get());
+ CHECK_MESSAGE(ecdsa_nodp, "the loaded key could not be converted into an ECDSA_PrivateKey");
+
+ signer.reset(get_pk_signer(*ecdsa_nodp, "EMSA1(SHA-1)"));
+ verifier.reset(get_pk_verifier(*ecdsa_nodp, "EMSA1(SHA-1)"));
+
+ SecureVector<byte> signature_nodp = signer->sign_message(msg, rng);
+
+ ok = verifier->verify_message(msg, signature_nodp);
+ CHECK_MESSAGE(ok, "generated signature could not be verified positively (no_dom)");
- SecureVector<byte> signature_nodp = loaded_ec_key_nodp->sign(sv_message.begin(), sv_message.size(), rng);
- //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n";
- bool ver_success_nodp = loaded_ec_key_nodp->verify(sv_message.begin(), sv_message.size(), signature_nodp.begin(), signature_nodp.size());
- CHECK_MESSAGE(ver_success_nodp, "generated signature could not be verified positively (no_dom)");
try
{
- std::auto_ptr<PKCS8_PrivateKey> loaded_key_withdp(PKCS8::load_key(TEST_DATA_DIR "/withdompar_private.pkcs8.pem", rng));
+ std::auto_ptr<PKCS8_PrivateKey> loaded_key_withdp(
+ PKCS8::load_key(TEST_DATA_DIR "/withdompar_private.pkcs8.pem", rng));
std::cout << "Unexpected success: loaded key with unknown OID\n";
}
@@ -447,48 +428,12 @@ void test_read_pkcs8(RandomNumberGenerator& rng)
}
}
-/**
-* The following test tests the copy ctors and and copy-assignment operators
-*/
-void test_cp_and_as_ctors(RandomNumberGenerator& rng)
- {
- std::cout << "." << std::flush;
-
- std::auto_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
- ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get());
- CHECK_MESSAGE(loaded_ec_key, "the loaded key could not be converted into an ECDSA_PrivateKey");
- std::string str_message = ("12345678901234567890abcdef12");
- SecureVector<byte> sv_message = decode_hex(str_message);
- SecureVector<byte> signature_1 = loaded_ec_key->sign(sv_message.begin(), sv_message.size(), rng);
- //cout << "signature = " << hex_encode(signature.begin(), signature.size()) << "\n";
-
- ECDSA_PrivateKey cp_priv_key(*loaded_ec_key); // priv-key, cp-ctor
- SecureVector<byte> signature_2 = cp_priv_key.sign(sv_message.begin(), sv_message.size(), rng);
-
- ECDSA_PrivateKey as_priv_key = *loaded_ec_key; //priv-key, as-op
- SecureVector<byte> signature_3 = as_priv_key.sign(sv_message.begin(), sv_message.size(), rng);
-
- ECDSA_PublicKey pk_1 = cp_priv_key; // pub-key, as-op
- ECDSA_PublicKey pk_2(pk_1); // pub-key, cp-ctor
- ECDSA_PublicKey pk_3 = pk_2;
-
- bool ver_success_1 = pk_1.verify(sv_message.begin(), sv_message.size(), signature_1.begin(), signature_1.size());
-
- bool ver_success_2 = pk_2.verify(sv_message.begin(), sv_message.size(), signature_2.begin(), signature_2.size());
-
- bool ver_success_3 = pk_3.verify(sv_message.begin(), sv_message.size(), signature_3.begin(), signature_3.size());
-
- CHECK_MESSAGE((ver_success_1 && ver_success_2 && ver_success_3), "different results for copied keys");
- }
-
}
u32bit do_ecdsa_tests(Botan::RandomNumberGenerator& rng)
{
std::cout << "Testing ECDSA (InSiTo unit tests): ";
- test_hash_larger_than_n(rng);
- //test_message_larger_than_n();
test_decode_ecdsa_X509();
test_decode_ver_link_SHA256();
test_decode_ver_link_SHA1();
@@ -498,7 +443,6 @@ u32bit do_ecdsa_tests(Botan::RandomNumberGenerator& rng)
test_create_and_verify(rng);
test_curve_registry(rng);
test_read_pkcs8(rng);
- test_cp_and_as_ctors(rng);
std::cout << std::endl;
diff --git a/checks/pk.cpp b/checks/pk.cpp
index 1a202bd7d..33d4da0fc 100644
--- a/checks/pk.cpp
+++ b/checks/pk.cpp
@@ -489,6 +489,31 @@ u32bit validate_dsa_sig(const std::string& algo,
return 2;
}
+u32bit validate_ecdsa_sig(const std::string& algo,
+ const std::vector<std::string>& str,
+ RandomNumberGenerator& rng)
+ {
+ if(str.size() != 5)
+ throw std::runtime_error("Invalid input from pk_valid.dat");
+
+#if defined(BOTAN_HAS_ECDSA)
+
+ EC_Domain_Params group(OIDS::lookup(str[0]));
+ ECDSA_PrivateKey ecdsa(group, to_bigint(str[1]));
+
+ std::string emsa = algo.substr(6, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(ecdsa, emsa);
+ PK_Signer* s = get_pk_signer(ecdsa, emsa);
+
+ bool failure = false;
+ validate_signature(v, s, algo, str[2], str[3], str[4], failure);
+ return (failure ? 1 : 0);
+#endif
+
+ return 2;
+ }
+
u32bit validate_dsa_ver(const std::string& algo,
const std::vector<std::string>& str)
{
@@ -791,33 +816,36 @@ u32bit do_pk_validation_tests(const std::string& filename,
try
{
- if(algorithm.find("DSA/") != std::string::npos)
+ if(algorithm.find("DSA/") == 0)
new_errors = validate_dsa_sig(algorithm, substr, rng);
- else if(algorithm.find("DSA_VA/") != std::string::npos)
+ else if(algorithm.find("DSA_VA/") == 0)
new_errors = validate_dsa_ver(algorithm, substr);
- else if(algorithm.find("RSAES_PKCS8/") != std::string::npos)
+ else if(algorithm.find("ECDSA/") == 0)
+ new_errors = validate_ecdsa_sig(algorithm, substr, rng);
+
+ else if(algorithm.find("RSAES_PKCS8/") == 0)
new_errors = validate_rsa_enc_pkcs8(algorithm, substr, rng);
- else if(algorithm.find("RSAVA_X509/") != std::string::npos)
+ else if(algorithm.find("RSAVA_X509/") == 0)
new_errors = validate_rsa_ver_x509(algorithm, substr);
- else if(algorithm.find("RSAES/") != std::string::npos)
+ else if(algorithm.find("RSAES/") == 0)
new_errors = validate_rsa_enc(algorithm, substr, rng);
- else if(algorithm.find("RSASSA/") != std::string::npos)
+ else if(algorithm.find("RSASSA/") == 0)
new_errors = validate_rsa_sig(algorithm, substr, rng);
- else if(algorithm.find("RSAVA/") != std::string::npos)
+ else if(algorithm.find("RSAVA/") == 0)
new_errors = validate_rsa_ver(algorithm, substr);
- else if(algorithm.find("RWVA/") != std::string::npos)
+ else if(algorithm.find("RWVA/") == 0)
new_errors = validate_rw_ver(algorithm, substr);
- else if(algorithm.find("RW/") != std::string::npos)
+ else if(algorithm.find("RW/") == 0)
new_errors = validate_rw_sig(algorithm, substr, rng);
- else if(algorithm.find("NR/") != std::string::npos)
+ else if(algorithm.find("NR/") == 0)
new_errors = validate_nr_sig(algorithm, substr, rng);
- else if(algorithm.find("ElGamal/") != std::string::npos)
+ else if(algorithm.find("ElGamal/") == 0)
new_errors = validate_elg_enc(algorithm, substr, rng);
- else if(algorithm.find("DH/") != std::string::npos)
+ else if(algorithm.find("DH/") == 0)
new_errors = validate_dh(algorithm, substr, rng);
- else if(algorithm.find("DLIES/") != std::string::npos)
+ else if(algorithm.find("DLIES/") == 0)
new_errors = validate_dlies(algorithm, substr, rng);
else
std::cout << "WARNING: Unknown PK algorithm "
diff --git a/checks/pk_valid.dat b/checks/pk_valid.dat
index 1e2a84c19..fbf3c3b45 100644
--- a/checks/pk_valid.dat
+++ b/checks/pk_valid.dat
@@ -4182,6 +4182,24 @@ MIG6AgEAMIGhBgcqhkjOOAQBMIGVAkAA8HR2W1fHj8t8G9/BzpO5z1Ea5YnMTwMS\
25ECC0ED4CE7118A72D133704D002A:\
14593FBF63EAC64976987524044D8B11AB9A95B4B75A760FE22C45A3EFD6:
+# ECDSA format is group name:private key:message:nonce:signature
+[ECDSA/EMSA1(SHA-1)]
+
+# From ANSI X9.62
+secp192r1:\
+1A8D598FC15BF0FD89030B5CB1111AEB92AE8BAF5EA475FB:\
+616263:\
+FA6DE29746BBEB7F8BB1E761F85F7DFB2983169D82FA2F4E:\
+885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD\
+E9ECC78106DEF82BF1070CF1D4D804C3CB390046951DF686
+
+x962_p239v1:\
+7EF7C6FABEFFFDEA864206E80B0B08A9331ED93E698561B64CA0F7777F3D:\
+616263:\
+656C7196BF87DCC5D1F1020906DF2782360D36B2DE7A17ECE37D503784AF:\
+2CB7F36803EBB9C427C58D8265F11FC5084747133078FC279DE874FBECB0\
+2EEAE988104E9C2234A3C2BEB1F53BFA5DC11FF36A875D1E3CCB1F7E45CF
+
# NR Format: p:q:g:y:x:message:k:output
[NR/EMSA1(SHA-1)]
# Trickiness: in some of these, we put a leading 0 digit on the nonce (k). This
diff --git a/src/pubkey/dsa/dsa.cpp b/src/pubkey/dsa/dsa.cpp
index 403243a97..628841fba 100644
--- a/src/pubkey/dsa/dsa.cpp
+++ b/src/pubkey/dsa/dsa.cpp
@@ -66,24 +66,6 @@ DSA_PrivateKey::DSA_PrivateKey(const AlgorithmIdentifier& alg_id,
}
/*
-* DSA Signature Operation
-*/
-SecureVector<byte> DSA_PrivateKey::sign(const byte in[], u32bit length,
- RandomNumberGenerator& rng) const
- {
- const BigInt& q = group_q();
-
- rng.add_entropy(in, length);
-
- BigInt k;
- do
- k.randomize(rng, q.bits());
- while(k >= q);
-
- return core.sign(in, length, k);
- }
-
-/*
* Check Private DSA Parameters
*/
bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
diff --git a/src/pubkey/dsa/dsa.h b/src/pubkey/dsa/dsa.h
index 444b3a825..e0aab1b52 100644
--- a/src/pubkey/dsa/dsa.h
+++ b/src/pubkey/dsa/dsa.h
@@ -63,9 +63,6 @@ class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey,
const BigInt& private_key = 0);
bool check_key(RandomNumberGenerator& rng, bool strong) const;
-
- SecureVector<byte> sign(const byte hash[], u32bit hash_len,
- RandomNumberGenerator& rng) const;
};
class BOTAN_DLL DSA_Signature_Operation : public PK_Ops::Signature_Operation
diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp
index f1ece3ebd..5ad0fbddd 100644
--- a/src/pubkey/ecc_key/ecc_key.cpp
+++ b/src/pubkey/ecc_key/ecc_key.cpp
@@ -87,17 +87,18 @@ const BigInt& EC_PrivateKey::private_value() const
/**
* EC_PrivateKey generator
-**/
+*/
EC_PrivateKey::EC_PrivateKey(const EC_Domain_Params& dom_par,
- const BigInt& priv_key) :
- EC_PublicKey(dom_par, dom_par.get_base_point() * private_key),
- private_key(priv_key)
+ const BigInt& priv_key)
{
+ domain_params = dom_par;
+ public_key = domain().get_base_point() * priv_key;
+ private_key = priv_key;
}
/**
* EC_PrivateKey generator
-**/
+*/
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
const EC_Domain_Params& dom_par)
{
diff --git a/src/pubkey/ecc_key/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h
index fcbc4b679..92f02613c 100644
--- a/src/pubkey/ecc_key/ecc_key.h
+++ b/src/pubkey/ecc_key/ecc_key.h
@@ -31,7 +31,6 @@ namespace Botan {
class BOTAN_DLL EC_PublicKey : public virtual Public_Key
{
public:
-
EC_PublicKey(const EC_Domain_Params& dom_par,
const PointGFp& pub_point);
diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp
index 6ca3fb9b1..ba8c20571 100644
--- a/src/pubkey/ecdsa/ecdsa.cpp
+++ b/src/pubkey/ecdsa/ecdsa.cpp
@@ -9,6 +9,8 @@
#include <botan/ecdsa.h>
+#include <iostream>
+
namespace Botan {
bool ECDSA_PublicKey::verify(const byte msg[], u32bit msg_len,
@@ -39,38 +41,6 @@ bool ECDSA_PublicKey::verify(const byte msg[], u32bit msg_len,
return (R.get_affine_x() % n == r);
}
-SecureVector<byte> ECDSA_PrivateKey::sign(const byte msg[],
- u32bit msg_len,
- RandomNumberGenerator& rng) const
- {
- const BigInt& n = domain().get_order();
-
- if(n == 0 || private_value() == 0)
- throw Invalid_State("ECDSA_PrivateKey::sign: Not initialized");
-
- BigInt k;
- do
- k.randomize(rng, n.bits()-1);
- while(k >= n);
-
- BigInt e(msg, msg_len);
-
- PointGFp k_times_P = domain().get_base_point() * k;
- BigInt r = k_times_P.get_affine_x() % n;
-
- if(r == 0)
- throw Internal_Error("Default_ECDSA_Op::sign: r was zero");
-
- BigInt k_inv = inverse_mod(k, n);
-
- BigInt s = (((r * private_value()) + e) * k_inv) % n;
-
- SecureVector<byte> output(2*n.bytes());
- r.binary_encode(output + (output.size() / 2 - r.bytes()));
- s.binary_encode(output + (output.size() - s.bytes()));
- return output;
- }
-
ECDSA_Signature_Operation::ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa) :
base_point(ecdsa.domain().get_base_point()),
order(ecdsa.domain().get_order()),
@@ -85,9 +55,10 @@ SecureVector<byte> ECDSA_Signature_Operation::sign(const byte msg[],
rng.add_entropy(msg, msg_len);
BigInt k;
- do
- k.randomize(rng, order.bits()-1);
- while(k >= order);
+ k.randomize(rng, order.bits());
+
+ while(k >= order)
+ k.randomize(rng, order.bits() - 1);
BigInt e(msg, msg_len);
diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h
index a54b28b46..75a7b152a 100644
--- a/src/pubkey/ecdsa/ecdsa.h
+++ b/src/pubkey/ecdsa/ecdsa.h
@@ -96,16 +96,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey,
*/
ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) :
EC_PrivateKey(domain, x) {}
-
- /**
- * Sign a message with this key.
- * @param message the byte array representing the message to be signed
- * @param mess_len the length of the message byte array
- * @result the signature
- */
-
- SecureVector<byte> sign(const byte message[], u32bit mess_len,
- RandomNumberGenerator& rng) const;
};
class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature_Operation
diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp
index ef0bac726..c3735c720 100644
--- a/src/pubkey/gost_3410/gost_3410.cpp
+++ b/src/pubkey/gost_3410/gost_3410.cpp
@@ -101,46 +101,6 @@ bool GOST_3410_PublicKey::verify(const byte msg[], u32bit msg_len,
return (R.get_affine_x() == r);
}
-SecureVector<byte>
-GOST_3410_PrivateKey::sign(const byte msg[],
- u32bit msg_len,
- RandomNumberGenerator& rng) const
- {
- if(private_value() == 0)
- throw Invalid_State("GOST_3410::sign(): no private key");
-
- const BigInt& n = domain().get_order();
-
- if(n == 0)
- throw Invalid_State("GOST_3410::sign(): domain parameters not set");
-
- BigInt k;
- do
- k.randomize(rng, n.bits()-1);
- while(k >= n);
-
- BigInt e(msg, msg_len);
-
- e %= n;
- if(e == 0)
- e = 1;
-
- PointGFp k_times_P = domain().get_base_point() * k;
- k_times_P.check_invariants();
-
- BigInt r = k_times_P.get_affine_x() % n;
-
- if(r == 0)
- throw Invalid_State("GOST_3410::sign: r was zero");
-
- BigInt s = (r*private_value() + k*e) % n;
-
- SecureVector<byte> output(2*n.bytes());
- r.binary_encode(output + (output.size() / 2 - r.bytes()));
- s.binary_encode(output + (output.size() - s.bytes()));
- return output;
- }
-
GOST_3410_Signature_Operation::GOST_3410_Signature_Operation(
const GOST_3410_PrivateKey& gost_3410) :
diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h
index 1bf55aa21..12abd6354 100644
--- a/src/pubkey/gost_3410/gost_3410.h
+++ b/src/pubkey/gost_3410/gost_3410.h
@@ -106,15 +106,6 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey,
AlgorithmIdentifier pkcs8_algorithm_identifier() const
{ return EC_PublicKey::algorithm_identifier(); }
-
- /**
- * Sign a message with this key.
- * @param message the byte array representing the message to be signed
- * @param mess_len the length of the message byte array
- * @result the signature
- */
- SecureVector<byte> sign(const byte message[], u32bit mess_len,
- RandomNumberGenerator& rng) const;
};
class BOTAN_DLL GOST_3410_Signature_Operation : public PK_Ops::Signature_Operation
diff --git a/src/pubkey/nr/nr.cpp b/src/pubkey/nr/nr.cpp
index 08ed6b376..df483499b 100644
--- a/src/pubkey/nr/nr.cpp
+++ b/src/pubkey/nr/nr.cpp
@@ -74,22 +74,6 @@ NR_PrivateKey::NR_PrivateKey(const AlgorithmIdentifier& alg_id,
}
/*
-* Nyberg-Rueppel Signature Operation
-*/
-SecureVector<byte> NR_PrivateKey::sign(const byte in[], u32bit length,
- RandomNumberGenerator& rng) const
- {
- const BigInt& q = group_q();
-
- BigInt k;
- do
- k.randomize(rng, q.bits());
- while(k >= q);
-
- return core.sign(in, length, k);
- }
-
-/*
* Check Private Nyberg-Rueppel Parameters
*/
bool NR_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
@@ -141,7 +125,7 @@ SecureVector<byte> NR_Signature_Operation::sign(const byte msg[],
BigInt c = mod_q.reduce(powermod_g_p(k) + f);
if(c.is_zero())
- throw Internal_Error("Default_NR_Op::sign: c was zero");
+ throw Internal_Error("NR_Signature_Operation: c was zero");
BigInt d = mod_q.reduce(k - x * c);
SecureVector<byte> output(2*q.bytes());
diff --git a/src/pubkey/nr/nr.h b/src/pubkey/nr/nr.h
index 013f3d42b..5fc7b2914 100644
--- a/src/pubkey/nr/nr.h
+++ b/src/pubkey/nr/nr.h
@@ -1,6 +1,6 @@
/*
* Nyberg-Rueppel
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -48,9 +48,6 @@ class BOTAN_DLL NR_PrivateKey : public NR_PublicKey,
public virtual DL_Scheme_PrivateKey
{
public:
- SecureVector<byte> sign(const byte msg[], u32bit msg_len,
- RandomNumberGenerator& rng) const;
-
bool check_key(RandomNumberGenerator& rng, bool strong) const;
NR_PrivateKey(const AlgorithmIdentifier& alg_id,
diff --git a/src/pubkey/pk_ops.h b/src/pubkey/pk_ops.h
index 5aa50efdb..2386b968a 100644
--- a/src/pubkey/pk_ops.h
+++ b/src/pubkey/pk_ops.h
@@ -49,6 +49,31 @@ class Signature_Operation
virtual ~Signature_Operation() {}
};
+class Verification_Operation
+ {
+ public:
+ /**
+ * Get the maximum message size in bits supported by this public key.
+ * @return the maximum message in bits
+ */
+ virtual u32bit max_input_bits() const = 0;
+
+ /**
+ * @return boolean specifying if this key type supports recovery
+ */
+ virtual bool with_recovery() const = 0;
+
+ /*
+ * Perform a signature operation
+ * @param msg the message
+ * @param msg_len the length of msg in bytes
+ * @returns recovered message if with_recovery() otherwise {0} or {1}
+ */
+ virtual SecureVector<byte> verify(const byte msg[], u32bit msg_len);
+
+ virtual ~Verification_Operation() {}
+ };
+
/*
* A generic Key Agreement Operation (eg DH or ECDH)
*/
diff --git a/src/pubkey/rsa/rsa.cpp b/src/pubkey/rsa/rsa.cpp
index 72a99b4f7..f21459f7b 100644
--- a/src/pubkey/rsa/rsa.cpp
+++ b/src/pubkey/rsa/rsa.cpp
@@ -96,15 +96,6 @@ SecureVector<byte> RSA_PrivateKey::decrypt(const byte in[], u32bit len) const
}
/*
-* RSA Signature Operation
-*/
-SecureVector<byte> RSA_PrivateKey::sign(const byte in[], u32bit len,
- RandomNumberGenerator&) const
- {
- return BigInt::encode_1363(private_op(in, len), n.bytes());
- }
-
-/*
* Check Private RSA Parameters
*/
bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
@@ -150,7 +141,7 @@ RSA_Signature_Operation::RSA_Signature_Operation(const RSA_PrivateKey& rsa) :
SecureVector<byte> RSA_Signature_Operation::sign(const byte msg[],
u32bit msg_len,
- RandomNumberGenerator& rng)
+ RandomNumberGenerator&)
{
const u32bit n_bytes = (n_bits + 7) / 8;
diff --git a/src/pubkey/rsa/rsa.h b/src/pubkey/rsa/rsa.h
index aa2f8124f..989cfd038 100644
--- a/src/pubkey/rsa/rsa.h
+++ b/src/pubkey/rsa/rsa.h
@@ -59,9 +59,6 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey,
public IF_Scheme_PrivateKey
{
public:
- SecureVector<byte> sign(const byte[], u32bit,
- RandomNumberGenerator&) const;
-
SecureVector<byte> decrypt(const byte[], u32bit) const;
bool check_key(RandomNumberGenerator& rng, bool) const;