aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-03-05 17:35:10 +0000
committerlloyd <[email protected]>2010-03-05 17:35:10 +0000
commitcdd1a1509ffc74c74bd902d55a7a85ab9e2afe78 (patch)
tree05f78baed62d78da63d5da4331d80d1909440702
parentdf8c46ffb5554d8804287b340e06f79fbafe8d1d (diff)
Add RSA encrypt/decrypt ops
-rw-r--r--src/engine/def_engine/def_pk_ops.cpp12
-rw-r--r--src/pubkey/rsa/rsa.cpp39
-rw-r--r--src/pubkey/rsa/rsa.h42
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;
};
}