rsa 0.1.1 → 0.1.2
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/VERSION +1 -1
- data/lib/rsa/key_pair.rb +11 -0
- data/lib/rsa/math.rb +96 -3
- data/lib/rsa/version.rb +1 -1
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/lib/rsa/key_pair.rb
CHANGED
@@ -87,6 +87,17 @@ module RSA
|
|
87
87
|
end
|
88
88
|
alias_method :n, :modulus
|
89
89
|
|
90
|
+
##
|
91
|
+
# Returns a hash table representation of this key pair.
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# key_pair.to_hash #=> {:n => ..., :d => ..., :e => ...}
|
95
|
+
#
|
96
|
+
# @return [Hash]
|
97
|
+
def to_hash
|
98
|
+
{:n => modulus, :d => private_key ? private_key.exponent : nil, :e => public_key ? public_key.exponent : nil}
|
99
|
+
end
|
100
|
+
|
90
101
|
##
|
91
102
|
# Encrypts the given `plaintext` using the public key from this key
|
92
103
|
# pair.
|
data/lib/rsa/math.rb
CHANGED
@@ -4,6 +4,8 @@ module RSA
|
|
4
4
|
module Math
|
5
5
|
extend ::Math
|
6
6
|
|
7
|
+
class ArithmeticError < ArgumentError; end
|
8
|
+
|
7
9
|
##
|
8
10
|
# Performs a primality test on the integer `n`, returning `true` if it
|
9
11
|
# is a prime.
|
@@ -12,7 +14,7 @@ module RSA
|
|
12
14
|
# 1.upto(10).select { |n| RSA::Math.prime?(n) } #=> [2, 3, 5, 7]
|
13
15
|
#
|
14
16
|
# @param [Integer] n
|
15
|
-
# @return [Boolean]
|
17
|
+
# @return [Boolean] `true` if `n` is a prime number, `false` otherwise
|
16
18
|
# @see http://en.wikipedia.org/wiki/Primality_test
|
17
19
|
# @see http://ruby-doc.org/core-1.9/classes/Prime.html
|
18
20
|
def self.prime?(n)
|
@@ -24,6 +26,97 @@ module RSA
|
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
29
|
+
##
|
30
|
+
# Returns `true` if the integer `a` is coprime (relatively prime) to
|
31
|
+
# integer `b`.
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# RSA::Math.coprime?(6, 35) #=> true
|
35
|
+
# RSA::Math.coprime?(6, 27) #=> false
|
36
|
+
#
|
37
|
+
# @param [Integer] a an integer
|
38
|
+
# @param [Integer] b an integer
|
39
|
+
# @return [Boolean] `true` if `a` and `b` are coprime, `false` otherwise
|
40
|
+
# @see http://en.wikipedia.org/wiki/Coprime
|
41
|
+
# @see http://mathworld.wolfram.com/RelativelyPrime.html
|
42
|
+
def self.coprime?(a, b)
|
43
|
+
gcd(a, b).equal?(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Returns the greatest common divisor (GCD) of the two integers `a` and
|
48
|
+
# `b`. The GCD is the largest positive integer that divides both numbers
|
49
|
+
# without a remainder.
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# RSA::Math.gcd(3, 5) #=> 1
|
53
|
+
# RSA::Math.gcd(8, 12) #=> 4
|
54
|
+
# RSA::Math.gcd(12, 60) #=> 12
|
55
|
+
# RSA::Math.gcd(90, 12) #=> 6
|
56
|
+
#
|
57
|
+
# @param [Integer] a an integer
|
58
|
+
# @param [Integer] b an integer
|
59
|
+
# @return [Integer] the greatest common divisor of `a` and `b`
|
60
|
+
# @see http://en.wikipedia.org/wiki/Greatest_common_divisor
|
61
|
+
# @see http://mathworld.wolfram.com/GreatestCommonDivisor.html
|
62
|
+
def self.gcd(a, b)
|
63
|
+
a.gcd(b)
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Returns the Bezout coefficients of the two nonzero integers `a` and
|
68
|
+
# `b` using the extended Euclidean algorithm.
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# RSA::Math.egcd(120, 23) #=> [-9, 47]
|
72
|
+
# RSA::Math.egcd(421, 111) #=> [-29, 110]
|
73
|
+
# RSA::Math.egcd(93, 219) #=> [33, -14]
|
74
|
+
# RSA::Math.egcd(4864, 3458) #=> [32, -45]
|
75
|
+
#
|
76
|
+
# @param [Integer] a a nonzero integer
|
77
|
+
# @param [Integer] b a nonzero integer
|
78
|
+
# @return [Array(Integer, Integer)] the Bezout coefficients `x` and `y`
|
79
|
+
# @raise [ZeroDivisionError] if `a` or `b` is zero
|
80
|
+
# @see http://en.wikipedia.org/wiki/B%C3%A9zout's_identity
|
81
|
+
# @see http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
|
82
|
+
# @see http://mathworld.wolfram.com/ExtendedGreatestCommonDivisor.html
|
83
|
+
def self.egcd(a, b)
|
84
|
+
if a.modulo(b).zero?
|
85
|
+
[0, 1]
|
86
|
+
else
|
87
|
+
x, y = egcd(b, a.modulo(b))
|
88
|
+
[y, x - y * a.div(b)]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Returns the modular multiplicative inverse of the integer `b` modulo
|
94
|
+
# `m`, where `b <= m`.
|
95
|
+
#
|
96
|
+
# The running time of the used algorithm, the extended Euclidean
|
97
|
+
# algorithm, is on the order of O(log2 _m_).
|
98
|
+
#
|
99
|
+
# @example
|
100
|
+
# RSA::Math.modinv(3, 11) #=> 4
|
101
|
+
# RSA::Math.modinv(6, 35) #=> 6
|
102
|
+
# RSA::Math.modinv(-6, 35) #=> 29
|
103
|
+
# RSA::Math.modinv(6, 36) #=> ArithmeticError
|
104
|
+
#
|
105
|
+
# @param [Integer] b
|
106
|
+
# @param [Integer] m the modulus
|
107
|
+
# @return [Integer] the modular multiplicative inverse
|
108
|
+
# @raise [ArithmeticError] if `m` <= 0, or if `b` not coprime to `m`
|
109
|
+
# @see http://en.wikipedia.org/wiki/Modular_multiplicative_inverse
|
110
|
+
# @see http://mathworld.wolfram.com/ModularInverse.html
|
111
|
+
def self.modinv(b, m)
|
112
|
+
if m > 0 && coprime?(b, m)
|
113
|
+
egcd(b, m).first.modulo(m)
|
114
|
+
else
|
115
|
+
raise ArithmeticError, "modulus #{m} is not positive" if m <= 0
|
116
|
+
raise ArithmeticError, "#{b} is not coprime to #{m}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
27
120
|
##
|
28
121
|
# Performs modular exponentiation in a memory-efficient manner.
|
29
122
|
#
|
@@ -31,7 +124,7 @@ module RSA
|
|
31
124
|
# large exponents.
|
32
125
|
#
|
33
126
|
# The running time of the used algorithm, the right-to-left binary
|
34
|
-
# method, is O(log _exponent_).
|
127
|
+
# method, is on the order of O(log _exponent_).
|
35
128
|
#
|
36
129
|
# @example
|
37
130
|
# RSA::Math.modpow(5, 3, 13) #=> 8
|
@@ -66,7 +159,7 @@ module RSA
|
|
66
159
|
# @see http://en.wikipedia.org/wiki/Euler's_totient_function
|
67
160
|
# @see http://mathworld.wolfram.com/TotientFunction.html
|
68
161
|
def self.phi(n)
|
69
|
-
1 + (2...n).count { |i|
|
162
|
+
1 + (2...n).count { |i| coprime?(n, i) }
|
70
163
|
end
|
71
164
|
|
72
165
|
##
|
data/lib/rsa/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 2
|
9
|
+
version: 0.1.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Arto Bendiken
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-09-
|
17
|
+
date: 2010-09-07 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|