diff options
author | lloyd <[email protected]> | 2010-03-05 17:35:10 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-03-05 17:35:10 +0000 |
commit | cdd1a1509ffc74c74bd902d55a7a85ab9e2afe78 (patch) | |
tree | 05f78baed62d78da63d5da4331d80d1909440702 | |
parent | df8c46ffb5554d8804287b340e06f79fbafe8d1d (diff) |
Add RSA encrypt/decrypt ops
-rw-r--r-- | src/engine/def_engine/def_pk_ops.cpp | 12 | ||||
-rw-r--r-- | src/pubkey/rsa/rsa.cpp | 39 | ||||
-rw-r--r-- | src/pubkey/rsa/rsa.h | 42 |
3 files changed, 66 insertions, 27 deletions
diff --git a/src/engine/def_engine/def_pk_ops.cpp b/src/engine/def_engine/def_pk_ops.cpp index e99908aa5..88880eea6 100644 --- a/src/engine/def_engine/def_pk_ops.cpp +++ b/src/engine/def_engine/def_pk_ops.cpp @@ -49,9 +49,9 @@ namespace Botan { PK_Ops::Encryption* Default_Engine::get_encryption_op(const Public_Key& key) const { -#if 0 && defined(BOTAN_HAS_RSA) +#if defined(BOTAN_HAS_RSA) if(const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key)) - return new RSA_Encryption_Operation(*s); + return new RSA_Public_Operation(*s); #endif #if defined(BOTAN_HAS_ELGAMAL) @@ -65,9 +65,9 @@ Default_Engine::get_encryption_op(const Public_Key& key) const PK_Ops::Decryption* Default_Engine::get_decryption_op(const Private_Key& key) const { -#if 0 && defined(BOTAN_HAS_RSA) +#if defined(BOTAN_HAS_RSA) if(const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key)) - return new RSA_Decryption_Operation(*s); + return new RSA_Private_Operation(*s); #endif #if defined(BOTAN_HAS_ELGAMAL) @@ -99,7 +99,7 @@ Default_Engine::get_signature_op(const Private_Key& key) const { #if defined(BOTAN_HAS_RSA) if(const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key)) - return new RSA_Signature_Operation(*s); + return new RSA_Private_Operation(*s); #endif #if defined(BOTAN_HAS_RW) @@ -136,7 +136,7 @@ Default_Engine::get_verify_op(const Public_Key& key) const { #if defined(BOTAN_HAS_RSA) if(const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key)) - return new RSA_Verification_Operation(*s); + return new RSA_Public_Operation(*s); #endif #if defined(BOTAN_HAS_RW) diff --git a/src/pubkey/rsa/rsa.cpp b/src/pubkey/rsa/rsa.cpp index 910fddb95..13ac1c318 100644 --- a/src/pubkey/rsa/rsa.cpp +++ b/src/pubkey/rsa/rsa.cpp @@ -120,29 +120,46 @@ bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const return true; } -RSA_Signature_Operation::RSA_Signature_Operation(const RSA_PrivateKey& rsa) : +RSA_Private_Operation::RSA_Private_Operation(const RSA_PrivateKey& rsa) : + n(rsa.get_n()), q(rsa.get_q()), c(rsa.get_c()), powermod_d1_p(rsa.get_d1(), rsa.get_p()), powermod_d2_q(rsa.get_d2(), rsa.get_q()), - mod_p(rsa.get_p()), - n_bits(rsa.get_n().bits()) + mod_p(rsa.get_p()) { } -SecureVector<byte> -RSA_Signature_Operation::sign(const byte msg[], u32bit msg_len, - RandomNumberGenerator&) const +BigInt RSA_Private_Operation::private_op(const BigInt& m) const { - const u32bit n_bytes = (n_bits + 7) / 8; + if(m >= n) + throw Invalid_Argument("RSA private op - input is too large"); - BigInt i(msg, msg_len); - BigInt j1 = powermod_d1_p(i); - BigInt j2 = powermod_d2_q(i); + BigInt j1 = powermod_d1_p(m); + BigInt j2 = powermod_d2_q(m); j1 = mod_p.reduce(sub_mul(j1, j2, c)); - return BigInt::encode_1363(mul_add(j1, q, j2), n_bytes); + return mul_add(j1, q, j2); + } + +SecureVector<byte> +RSA_Private_Operation::sign(const byte msg[], u32bit msg_len, + RandomNumberGenerator&) const + { + BigInt m(msg, msg_len); + BigInt x = private_op(m); + return BigInt::encode_1363(x, n.bytes()); + } + +/* +* RSA Decryption Operation +*/ +SecureVector<byte> +RSA_Private_Operation::decrypt(const byte msg[], u32bit msg_len) const + { + BigInt m(msg, msg_len); + return BigInt::encode(private_op(m)); } } diff --git a/src/pubkey/rsa/rsa.h b/src/pubkey/rsa/rsa.h index ed7fe9eca..794352dce 100644 --- a/src/pubkey/rsa/rsa.h +++ b/src/pubkey/rsa/rsa.h @@ -96,16 +96,23 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, BigInt private_op(const byte[], u32bit) const; }; -class BOTAN_DLL RSA_Signature_Operation : public PK_Ops::Signature +class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature, + public PK_Ops::Decryption { public: - RSA_Signature_Operation(const RSA_PrivateKey& rsa); + RSA_Private_Operation(const RSA_PrivateKey& rsa); - u32bit max_input_bits() const { return (n_bits - 1); } + u32bit max_input_bits() const { return (n.bits() - 1); } SecureVector<byte> sign(const byte msg[], u32bit msg_len, RandomNumberGenerator& rng) const; + + SecureVector<byte> decrypt(const byte msg[], u32bit msg_len) const; + private: + BigInt private_op(const BigInt& m) const; + + const BigInt& n; const BigInt& q; const BigInt& c; Fixed_Exponent_Power_Mod powermod_d1_p, powermod_d2_q; @@ -113,25 +120,40 @@ class BOTAN_DLL RSA_Signature_Operation : public PK_Ops::Signature u32bit n_bits; }; -class BOTAN_DLL RSA_Verification_Operation : public PK_Ops::Verification +class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification, + public PK_Ops::Encryption { public: - RSA_Verification_Operation(const RSA_PublicKey& rsa) : - powermod_e_n(rsa.get_e(), rsa.get_n()), - n_bits(rsa.get_n().bits()) + RSA_Public_Operation(const RSA_PublicKey& rsa) : + n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n()) {} - u32bit max_input_bits() const { return (n_bits - 1); } + u32bit max_input_bits() const { return (n.bits() - 1); } bool with_recovery() const { return true; } + SecureVector<byte> encrypt(const byte msg[], u32bit msg_len, + RandomNumberGenerator&) const + { + BigInt m(msg, msg_len); + return BigInt::encode_1363(public_op(m), n.bytes()); + } + SecureVector<byte> verify_mr(const byte msg[], u32bit msg_len) const { - return BigInt::encode(powermod_e_n(BigInt(msg, msg_len))); + BigInt m(msg, msg_len); + return BigInt::encode(public_op(m)); } private: + BigInt public_op(const BigInt& m) const + { + if(m >= n) + throw Invalid_Argument("RSA public op - input is too large"); + return powermod_e_n(m); + } + + const BigInt& n; Fixed_Exponent_Power_Mod powermod_e_n; - u32bit n_bits; }; } |