monotone

monotone Mtn Source Tree

Root/botan/rsa.cpp

1/*************************************************
2* RSA Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/rsa.h>
7#include <botan/numthry.h>
8#include <botan/keypair.h>
9#include <botan/parsing.h>
10
11namespace Botan {
12
13/*************************************************
14* RSA_PublicKey Constructor *
15*************************************************/
16RSA_PublicKey::RSA_PublicKey(const BigInt& mod, const BigInt& exp)
17 {
18 n = mod;
19 e = exp;
20 X509_load_hook();
21 }
22
23/*************************************************
24* RSA Public Operation *
25*************************************************/
26BigInt RSA_PublicKey::public_op(const BigInt& i) const
27 {
28 if(i >= n)
29 throw Invalid_Argument(algo_name() + "::public_op: input is too large");
30 return core.public_op(i);
31 }
32
33/*************************************************
34* RSA Encryption Function *
35*************************************************/
36SecureVector<byte> RSA_PublicKey::encrypt(const byte in[], u32bit len) const
37 {
38 BigInt i(in, len);
39 return BigInt::encode_1363(public_op(i), n.bytes());
40 }
41
42/*************************************************
43* RSA Verification Function *
44*************************************************/
45SecureVector<byte> RSA_PublicKey::verify(const byte in[], u32bit len) const
46 {
47 BigInt i(in, len);
48 return BigInt::encode(public_op(i));
49 }
50
51/*************************************************
52* Create a RSA private key *
53*************************************************/
54RSA_PrivateKey::RSA_PrivateKey(u32bit bits, u32bit exp)
55 {
56 if(bits < 128)
57 throw Invalid_Argument(algo_name() + ": Can't make a key that is only " +
58 to_string(bits) + " bits long");
59 if(exp < 3 || exp % 2 == 0)
60 throw Invalid_Argument(algo_name() + ": Invalid encryption exponent");
61
62 e = exp;
63 p = random_prime((bits + 1) / 2, LongTermKey, e);
64 q = random_prime(bits - p.bits(), LongTermKey, e);
65 d = inverse_mod(e, lcm(p - 1, q - 1));
66
67 PKCS8_load_hook();
68 check_generated_private();
69
70 if(n.bits() != bits)
71 throw Self_Test_Failure(algo_name() + " private key generation failed");
72 }
73
74/*************************************************
75* RSA_PrivateKey Constructor *
76*************************************************/
77RSA_PrivateKey::RSA_PrivateKey(const BigInt& prime1, const BigInt& prime2,
78 const BigInt& exp, const BigInt& d_exp,
79 const BigInt& mod)
80 {
81 p = prime1;
82 q = prime2;
83 e = exp;
84 d = d_exp;
85 n = mod;
86
87 if(d == 0)
88 d = inverse_mod(e, lcm(p - 1, q - 1));
89
90 PKCS8_load_hook();
91 check_loaded_private();
92 }
93
94/*************************************************
95* RSA Private Operation *
96*************************************************/
97BigInt RSA_PrivateKey::private_op(const byte in[], u32bit length) const
98 {
99 BigInt i(in, length);
100 if(i >= n)
101 throw Invalid_Argument(algo_name() + "::private_op: input is too large");
102
103 BigInt r = core.private_op(i);
104 if(i != public_op(r))
105 throw Self_Test_Failure(algo_name() + " private operation check failed");
106 return r;
107 }
108
109/*************************************************
110* RSA Decryption Operation *
111*************************************************/
112SecureVector<byte> RSA_PrivateKey::decrypt(const byte in[], u32bit len) const
113 {
114 return BigInt::encode(private_op(in, len));
115 }
116
117/*************************************************
118* RSA Signature Operation *
119*************************************************/
120SecureVector<byte> RSA_PrivateKey::sign(const byte in[], u32bit len) const
121 {
122 return BigInt::encode_1363(private_op(in, len), n.bytes());
123 }
124
125/*************************************************
126* Check Private RSA Parameters *
127*************************************************/
128bool RSA_PrivateKey::check_key(bool strong) const
129 {
130 if(!IF_Scheme_PrivateKey::check_key(strong))
131 return false;
132
133 if(!strong)
134 return true;
135
136 if((e * d) % lcm(p - 1, q - 1) != 1)
137 return false;
138
139 try {
140 KeyPair::check_key(get_pk_encryptor(*this, "EME1(SHA-1)"),
141 get_pk_decryptor(*this, "EME1(SHA-1)")
142 );
143
144 KeyPair::check_key(get_pk_signer(*this, "EMSA4(SHA-1)"),
145 get_pk_verifier(*this, "EMSA4(SHA-1)")
146 );
147 }
148 catch(Self_Test_Failure)
149 {
150 return false;
151 }
152
153 return true;
154 }
155
156}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status