rsa 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -17,10 +17,31 @@ Features
17
17
  * Compatible with Ruby 1.9.1+ and JRuby 1.5.0+.
18
18
  * Compatible with older Ruby versions with the help of the [Backports][] gem.
19
19
 
20
+ Examples
21
+ --------
22
+
23
+ require 'rsa'
24
+
25
+ ### Generating a new RSA key pair
26
+
27
+ key_pair = RSA::KeyPair.generate(128)
28
+
29
+ ### Encrypting a plaintext message
30
+
31
+ ciphertext = key_pair.encrypt("Hello, world!")
32
+
33
+ ### Decrypting a ciphertext message
34
+
35
+ plaintext = key_pair.decrypt(ciphertext)
36
+
20
37
  Documentation
21
38
  -------------
22
39
 
23
- * <http://rsa.rubyforge.org/>
40
+ <http://rsa.rubyforge.org/>
41
+
42
+ * {RSA::KeyPair}
43
+ * {RSA::Key}
44
+ * {RSA::PKCS1}
24
45
 
25
46
  Dependencies
26
47
  ------------
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -91,65 +91,140 @@ module RSA
91
91
  # Encrypts the given `plaintext` using the public key from this key
92
92
  # pair.
93
93
  #
94
- # @param [Integer, String, IO] plaintext
94
+ # @overload encrypt(plaintext, options = {})
95
+ # @param [Integer] plaintext
96
+ # @param [Hash{Symbol => Object}] options
97
+ # @return [Integer]
98
+ #
99
+ # @overload encrypt(plaintext, options = {})
100
+ # @param [String, IO, StringIO] plaintext
101
+ # @param [Hash{Symbol => Object}] options
102
+ # @return [String]
103
+ #
104
+ # @param [Object] plaintext
95
105
  # @param [Hash{Symbol => Object}] options
96
106
  # @option options [Symbol, #to_sym] :padding (nil)
97
- # @return [Integer]
98
107
  def encrypt(plaintext, options = {})
99
- PKCS1.rsaep(public_key, convert_to_integer(plaintext))
108
+ case plaintext
109
+ when Integer then encrypt_integer(plaintext, options)
110
+ when String then PKCS1.i2osp(encrypt_integer(PKCS1.os2ip(plaintext), options))
111
+ when StringIO, IO then PKCS1.i2osp(encrypt_integer(PKCS1.os2ip(plaintext.read), options))
112
+ else raise ArgumentError, plaintext.inspect # FIXME
113
+ end
100
114
  end
101
115
 
102
116
  ##
103
117
  # Decrypts the given `ciphertext` using the private key from this key
104
118
  # pair.
105
119
  #
106
- # @param [Integer, String, IO] ciphertext
120
+ # @overload decrypt(ciphertext, options = {})
121
+ # @param [Integer] ciphertext
122
+ # @param [Hash{Symbol => Object}] options
123
+ # @return [Integer]
124
+ #
125
+ # @overload decrypt(ciphertext, options = {})
126
+ # @param [String, IO, StringIO] ciphertext
127
+ # @param [Hash{Symbol => Object}] options
128
+ # @return [String]
129
+ #
130
+ # @param [Object] ciphertext
107
131
  # @param [Hash{Symbol => Object}] options
108
132
  # @option options [Symbol, #to_sym] :padding (nil)
109
- # @return [Integer]
110
133
  def decrypt(ciphertext, options = {})
111
- PKCS1.rsadp(private_key, convert_to_integer(ciphertext))
134
+ case ciphertext
135
+ when Integer then decrypt_integer(ciphertext, options)
136
+ when String then PKCS1.i2osp(decrypt_integer(PKCS1.os2ip(ciphertext), options))
137
+ when StringIO, IO then PKCS1.i2osp(decrypt_integer(PKCS1.os2ip(ciphertext.read), options))
138
+ else raise ArgumentError, ciphertext.inspect # FIXME
139
+ end
112
140
  end
113
141
 
114
142
  ##
115
143
  # Signs the given `plaintext` using the private key from this key pair.
116
144
  #
117
- # @param [Integer, String, IO] plaintext
145
+ # @overload sign(plaintext, options = {})
146
+ # @param [Integer] plaintext
147
+ # @param [Hash{Symbol => Object}] options
148
+ # @return [Integer]
149
+ #
150
+ # @overload sign(plaintext, options = {})
151
+ # @param [String, IO, StringIO] plaintext
152
+ # @param [Hash{Symbol => Object}] options
153
+ # @return [String]
154
+ #
155
+ # @param [Object] plaintext
118
156
  # @param [Hash{Symbol => Object}] options
119
157
  # @option options [Symbol, #to_sym] :padding (nil)
120
- # @return [Integer]
121
158
  def sign(plaintext, options = {})
122
- PKCS1.rsasp1(private_key, convert_to_integer(plaintext))
159
+ case plaintext
160
+ when Integer then sign_integer(plaintext, options)
161
+ when String then PKCS1.i2osp(sign_integer(PKCS1.os2ip(plaintext), options))
162
+ when StringIO, IO then PKCS1.i2osp(sign_integer(PKCS1.os2ip(plaintext.read), options))
163
+ else raise ArgumentError, plaintext.inspect # FIXME
164
+ end
123
165
  end
124
166
 
125
167
  ##
126
168
  # Verifies the given `signature` using the public key from this key
127
169
  # pair.
128
170
  #
129
- # @param [Integer, String, IO] signature
130
- # @param [Integer, String, IO] plaintext
171
+ # @overload verify(signature, plaintext, options = {})
172
+ # @param [Integer] signature
173
+ # @param [Integer] plaintext
174
+ # @param [Hash{Symbol => Object}] options
175
+ # @return [Boolean]
176
+ #
177
+ # @overload verify(signature, plaintext, options = {})
178
+ # @param [String, IO, StringIO] signature
179
+ # @param [String, IO, StringIO] plaintext
180
+ # @param [Hash{Symbol => Object}] options
181
+ # @return [Boolean]
182
+ #
183
+ # @param [Object] signature
184
+ # @param [Object] plaintext
131
185
  # @param [Hash{Symbol => Object}] options
132
186
  # @option options [Symbol, #to_sym] :padding (nil)
133
187
  # @return [Boolean]
134
188
  def verify(signature, plaintext, options = {})
135
- PKCS1.rsavp1(public_key, convert_to_integer(signature)).eql?(convert_to_integer(plaintext))
189
+ signature = case signature
190
+ when Integer then signature
191
+ when String then PKCS1.os2ip(signature)
192
+ when StringIO, IO then PKCS1.os2ip(signature.read)
193
+ else raise ArgumentError, signature.inspect # FIXME
194
+ end
195
+ plaintext = case plaintext
196
+ when Integer then plaintext
197
+ when String then PKCS1.os2ip(plaintext)
198
+ when StringIO, IO then PKCS1.os2ip(plaintext.read)
199
+ else raise ArgumentError, plaintext.inspect # FIXME
200
+ end
201
+ verify_integer(signature, plaintext, options)
136
202
  end
137
203
 
138
204
  protected
139
205
 
140
206
  ##
141
- # Converts the given `input` to an integer suitable for use with RSA
142
- # primitives.
143
- #
144
- # @param [Integer, String, IO] input
145
- # @return [Integer]
146
- def convert_to_integer(input)
147
- case input
148
- when Integer then input
149
- when String then PKCS1.os2ip(input)
150
- when IO, StringIO then PKCS1.os2ip(input.read)
151
- else raise ArgumentError, input.inspect # FIXME
152
- end
207
+ # @private
208
+ def encrypt_integer(plaintext, options = {})
209
+ PKCS1.rsaep(public_key, plaintext)
210
+ end
211
+
212
+ ##
213
+ # @private
214
+ def decrypt_integer(ciphertext, options = {})
215
+ PKCS1.rsadp(private_key, ciphertext)
216
+ end
217
+
218
+ ##
219
+ # @private
220
+ def sign_integer(plaintext, options = {})
221
+ PKCS1.rsasp1(private_key, plaintext)
222
+ end
223
+
224
+ ##
225
+ # @private
226
+ def verify_integer(signature, plaintext, options = {})
227
+ PKCS1.rsavp1(public_key, signature).eql?(plaintext)
153
228
  end
154
229
  end # class KeyPair
155
230
  end # module RSA
@@ -30,8 +30,8 @@ module RSA
30
30
  # This is equivalent to `base**exponent % modulus` but much faster for
31
31
  # large exponents.
32
32
  #
33
- # This is presently a semi-naive implementation. Don't rely on it for
34
- # very large exponents.
33
+ # The running time of the used algorithm, the right-to-left binary
34
+ # method, is O(log _exponent_).
35
35
  #
36
36
  # @example
37
37
  # RSA::Math.modpow(5, 3, 13) #=> 8
@@ -43,9 +43,13 @@ module RSA
43
43
  # @return [Integer]
44
44
  # @see http://en.wikipedia.org/wiki/Modular_exponentiation
45
45
  def self.modpow(base, exponent, modulus)
46
- 1.upto(exponent).inject(1) do |c, e|
47
- (c * base) % modulus
46
+ result = 1
47
+ while exponent > 0
48
+ result = (base * result) % modulus unless (exponent & 1).zero?
49
+ base = (base * base) % modulus
50
+ exponent >>= 1
48
51
  end
52
+ result
49
53
  end
50
54
 
51
55
  ##
@@ -2,7 +2,7 @@ module RSA
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 0
5
+ TINY = 1
6
6
  EXTRA = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Arto Bendiken