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 CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -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.
@@ -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| i.gcd(n).eql?(1) }
162
+ 1 + (2...n).count { |i| coprime?(n, i) }
70
163
  end
71
164
 
72
165
  ##
@@ -2,7 +2,7 @@ module RSA
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 1
5
+ TINY = 2
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
- - 1
9
- version: 0.1.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-06 00:00:00 +02:00
17
+ date: 2010-09-07 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency