diff options
Diffstat (limited to 'src/pubkey/rsa/rsa.h')
-rw-r--r-- | src/pubkey/rsa/rsa.h | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/src/pubkey/rsa/rsa.h b/src/pubkey/rsa/rsa.h index 0580fe8eb..72cd80fef 100644 --- a/src/pubkey/rsa/rsa.h +++ b/src/pubkey/rsa/rsa.h @@ -9,15 +9,15 @@ #define BOTAN_RSA_H__ #include <botan/if_algo.h> +#include <botan/reducer.h> +#include <botan/blinding.h> namespace Botan { /** * RSA Public Key */ -class BOTAN_DLL RSA_PublicKey : public PK_Encrypting_Key, - public PK_Verifying_with_MR_Key, - public virtual IF_Scheme_PublicKey +class BOTAN_DLL RSA_PublicKey : public virtual IF_Scheme_PublicKey { public: std::string algo_name() const { return "RSA"; } @@ -25,57 +25,57 @@ class BOTAN_DLL RSA_PublicKey : public PK_Encrypting_Key, SecureVector<byte> encrypt(const byte[], u32bit, RandomNumberGenerator& rng) const; - SecureVector<byte> verify(const byte[], u32bit) const; - - RSA_PublicKey() {} + RSA_PublicKey(const AlgorithmIdentifier& alg_id, + const MemoryRegion<byte>& key_bits) : + IF_Scheme_PublicKey(alg_id, key_bits) + {} /** * Create a RSA_PublicKey * @arg n the modulus * @arg e the exponent */ - RSA_PublicKey(const BigInt& n, const BigInt& e); + RSA_PublicKey(const BigInt& n, const BigInt& e) : + IF_Scheme_PublicKey(n, e) + {} + protected: - BigInt public_op(const BigInt&) const; + RSA_PublicKey() {} }; /** * RSA Private Key class. */ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, - public PK_Decrypting_Key, - public PK_Signing_Key, 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; - /** - * Default constructor, does not set any internal values. Use this - * constructor if you wish to decode a DER or PEM encoded key. - */ - RSA_PrivateKey() {} + RSA_PrivateKey(const AlgorithmIdentifier& alg_id, + const MemoryRegion<byte>& key_bits, + RandomNumberGenerator& rng) : + IF_Scheme_PrivateKey(rng, alg_id, key_bits) {} /** * Construct a private key from the specified parameters. - * @param rng the random number generator to use - * @param prime1 the first prime - * @param prime2 the second prime - * @param exp the exponent - * @param d_exp if specified, this has to be d with + * @param rng a random number generator + * @param p the first prime + * @param q the second prime + * @param e the exponent + * @param d if specified, this has to be d with * exp * d = 1 mod (p - 1, q - 1). Leave it as 0 if you wish to * the constructor to calculate it. * @param n if specified, this must be n = p * q. Leave it as 0 * if you wish to the constructor to calculate it. */ RSA_PrivateKey(RandomNumberGenerator& rng, - const BigInt& p, const BigInt& q, const BigInt& e, - const BigInt& d = 0, const BigInt& n = 0); + const BigInt& p, const BigInt& q, + const BigInt& e, const BigInt& d = 0, + const BigInt& n = 0) : + IF_Scheme_PrivateKey(rng, p, q, e, d, n) {} /** * Create a new private key with the specified bit length @@ -85,8 +85,66 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, */ RSA_PrivateKey(RandomNumberGenerator& rng, u32bit bits, u32bit exp = 65537); + }; + +class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature, + public PK_Ops::Decryption + { + public: + RSA_Private_Operation(const RSA_PrivateKey& rsa); + + u32bit max_input_bits() const { return (n.bits() - 1); } + + SecureVector<byte> sign(const byte msg[], u32bit msg_len, + RandomNumberGenerator& rng); + + SecureVector<byte> decrypt(const byte msg[], u32bit msg_len); + + private: + BigInt private_op(const BigInt& m) const; + + const BigInt& n; + const BigInt& q; + const BigInt& c; + Fixed_Exponent_Power_Mod powermod_e_n, powermod_d1_p, powermod_d2_q; + Modular_Reducer mod_p; + Blinder blinder; + }; + +class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification, + public PK_Ops::Encryption + { + public: + 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); } + bool with_recovery() const { return true; } + + SecureVector<byte> encrypt(const byte msg[], u32bit msg_len, + RandomNumberGenerator&) + { + BigInt m(msg, msg_len); + return BigInt::encode_1363(public_op(m), n.bytes()); + } + + SecureVector<byte> verify_mr(const byte msg[], u32bit msg_len) + { + BigInt m(msg, msg_len); + return BigInt::encode(public_op(m)); + } + private: - BigInt private_op(const byte[], u32bit) const; + 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; }; } |