aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <lloyd@randombit.net>2010-03-05 06:47:02 +0000
committerlloyd <lloyd@randombit.net>2010-03-05 06:47:02 +0000
commit1b68d7e53c4bc5e6b2938194b0f7eda78a72ce43 (patch)
treeda1b0482d875a48fe95e133346aee4baabcbf7cb
parentd4ef447dc8b3b4f40f2ab250b1c364e2f74ccfa4 (diff)
Remove the sign() operation from the public key objects, totally replaced
by using the ops. Add real ECDSA test vectors (two found in ANSI X9.62)
-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;