Guest User

Untitled

a guest
Apr 24th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.85 KB | None | 0 0
  1. class String
  2. # Convert String to a string of binary digits, similar to Integer.to_s(2).
  3. def to_bin
  4. n = self.to_str
  5.  
  6. s = ''
  7.  
  8. n.each_byte do |b|
  9. s << b.to_s(2)
  10. end
  11.  
  12. s
  13. end
  14.  
  15. # Do I need a Integer#to_integer and a String.to_integer? Strings should be
  16. # allowed as inputs to a lot of the crypto APIs, but they will be treated as
  17. # integers, internally! How to deal with this?
  18. def to_integer
  19. Integer.from_unsigned_bytes(self)
  20. end
  21.  
  22. def to_bytes
  23. self
  24. end
  25. end
  26.  
  27. class Integer
  28. # +bytes+ is a sequence of octets in network byte order (most significant
  29. # byte first) that comprises an unsigned integer.
  30. def self.from_unsigned_bytes(bytes)
  31. bytes = bytes.to_str
  32. n = 0
  33. bytes.each_byte do |b|
  34. n <<= 8
  35. n |= b
  36. end
  37. n
  38. end
  39.  
  40. # Return self as a String of bytes in network byte order.
  41. def to_bytes
  42. a = []
  43. n = self.to_int
  44.  
  45. while n != 0
  46. a.unshift( (n & 0xff).chr )
  47. n >>= 8
  48. end
  49. a.join
  50. end
  51.  
  52. # Return self.
  53. #
  54. # Purpose is to allow a set of classes to declare themselves to be "duck-typed"
  55. # to Integer. This set of classes includes String, see String#to_integer.
  56. def to_integer
  57. self
  58. end
  59.  
  60. # Why isn't this a standard ruby method?
  61. def []=(position, value)
  62. bit = 2 ** position
  63. i = self.to_int
  64. if value
  65. i |= bit
  66. else
  67. i &= ~bit
  68. end
  69. i
  70. end
  71.  
  72. # Determine size of +self+ in bits.
  73. def bit_size
  74. i = self.to_int
  75.  
  76. hibit = i.size * 8 - 1
  77.  
  78. while( i[hibit] == 0 ) do
  79. hibit = hibit - 1
  80.  
  81. break if hibit < 0
  82. end
  83.  
  84. hibit + 1
  85. end
  86. end
  87.  
  88. class Integer
  89. # Calculate the inverse of an Integer modulo +n+. The modular inverse of +a mod n+,
  90. # +a^-1 mod n+, is a number +a^-1+ such that:
  91. #
  92. # a^-1 * a = 1 mod n
  93. #
  94. # There may not be such a number, in which case a RangeError is raised.
  95. #
  96. # Uses the 'Extended Euclidean Algorithm' implementation
  97. # from Figure 4.1, +Cryptography Theory and Practice+, Stinson.
  98. def modular_inverse(n)
  99. n = n.to_int
  100. b = self.to_int
  101. n0 = n
  102. b0 = b
  103. t0 = 0
  104. t = 1
  105. q = (n0/b0).floor
  106. r = n0 - q * b0
  107. while r > 0 do
  108. temp = t0 - q * t
  109. if temp > 0 then temp = temp.modulo(n); end
  110. if temp < 0 then temp = n - ((-temp).modulo(n)); end
  111. t0 = t
  112. t = temp
  113. n0 = b0
  114. b0 = r
  115. q = (n0/b0).floor
  116. r = n0 - q * b0
  117. end
  118.  
  119. if b0 != 1
  120. raise RangeError, "#{b} has no inverse modulo #{n}"
  121. else
  122. t.modulo(n)
  123. end
  124. end
  125.  
  126. # Calculate +self+ ** +exp+ modulo +n+.
  127. #
  128. # This method uses the "square and multiply" approach. Why should be fairly
  129. # obvious from the code, see +Cryptography Theory and Practice+, Stinson,
  130. # Chapter 4.4 for a description of the method.
  131. def modular_exp(exp, n)
  132. # x ** b mod n
  133. x = self.to_int
  134. b = exp.to_int
  135. n = n.to_int
  136.  
  137. z = 1
  138.  
  139. (n.bit_size - 1).downto(0) do |i|
  140. z = z ** 2 % n
  141.  
  142. if b[i] == 1 then
  143. z = z * x % n
  144. end
  145. end
  146.  
  147. z
  148. end
  149.  
  150.  
  151. # Return whether +self+ is even, that is, evenly divisible by 2.
  152. def even?
  153. self[0] == 0
  154. end
  155.  
  156. # True if +self+ is probably prime, false otherwise. Probabalistic primality
  157. # test is the Miller-Rabin algorithm, aka "strong pseudo-prime test".
  158. #
  159. # +accuracy+ is the number of times to try the test, and error probablity
  160. # will be aproximately 1 time out of 4**+accuracy+. Default is 10, wich gives
  161. # an error rate of 1 in 1,048,076.
  162. def prime?(accuracy = 10)
  163. miller_rabin_prime?(accuracy)
  164. end
  165.  
  166. # Determines if an odd number is prime, with an error probability of 1/4, at
  167. # most. Implementation from Stinson, Figure 4.9.
  168. def miller_rabin_prime?(accuracy)
  169. # Two is prime
  170. return true if self == 2
  171. # Not prime if its even!
  172. return false if self.even?
  173.  
  174. n = self.to_int
  175.  
  176. # Find k, m such that n - 1 = (2 ** k) * m, where m is odd
  177.  
  178. m = n - 1
  179. k = 0
  180.  
  181. # Since n is odd, n-1 is even, and this will loop at least once
  182. while m.even?
  183. m >>= 1
  184. k += 1
  185. end
  186.  
  187. # Answers of 'composite' are always correct - n is not prime. Answers of
  188. # 'prime' are not necessarily true, so we try again. If we answered 'prime'
  189. # accuracy number of times, then maybe it is prime.
  190. accuracy.times do
  191.  
  192. catch(:isprime) do
  193. # Choose a, 1 <= a <= n - 1
  194. a = Kernel.rand(n - 1) # 0..(n-2)
  195. a = a + 1 # 1..n-1
  196.  
  197. # Compute b = a ** m mod n
  198. b = a.modular_exp(m, n)
  199.  
  200. # puts "n #{n} m #{m} k #{k} a #{a} b #{b}"
  201.  
  202. # If b == 1 mod n, n is prime
  203. if( b == 1 )
  204. throw :isprime
  205. end
  206.  
  207. # For i = 0 to k - 1 do
  208. k.times do
  209. # if b == -1 (mod n), n is prime
  210. if( b == (n - 1) )
  211. throw :isprime
  212. else
  213. b = b.modular_exp(2, n)
  214. end
  215. end
  216.  
  217. # It's composite.
  218. return false
  219. end
  220.  
  221. end
  222.  
  223. return true
  224. end
  225.  
  226. end
Add Comment
Please, Sign In to add comment