251 lines
4.2 KiB
Ruby
Executable File
251 lines
4.2 KiB
Ruby
Executable File
#!/usr/bin/ruby
|
|
# coding: utf-8
|
|
|
|
#####################################
|
|
#
|
|
# Marcin Woźniak
|
|
# s434812
|
|
#
|
|
#####################################
|
|
|
|
require 'openssl'
|
|
require 'securerandom'
|
|
require 'prime'
|
|
require 'thread'
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def nwd(a, b)
|
|
if a == 0
|
|
return false
|
|
end
|
|
b == 0 ? a : nwd(b, a.modulo(b))
|
|
end
|
|
|
|
####################################
|
|
# Funkcja extended_euklides(a,b)
|
|
#
|
|
# Oblicza rozszerzony algorytm euklidesa
|
|
# zwracajac u,v
|
|
# extended_euklides(10,14) => [3, -2]
|
|
#
|
|
#####################################
|
|
def extended_euklides(a, b)
|
|
return 1, 0 if b == 0
|
|
|
|
q, r = a.divmod b
|
|
s, t = extended_euklides(b, r)
|
|
|
|
return t, s - q * t
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def random_gen_Zn(k,n)
|
|
|
|
if n == 0
|
|
n = 2 ** k
|
|
end
|
|
|
|
if k == 1
|
|
max = 1
|
|
else
|
|
kb = k.to_s(2)
|
|
minimum = []
|
|
minimum << 1
|
|
k = kb.length - 1
|
|
|
|
while (k != 0) do
|
|
j = SecureRandom.random_number(2)
|
|
minimum << j
|
|
k = k - 1
|
|
end
|
|
min = minimum.join.to_i(2)
|
|
max = n - 1
|
|
if min < max
|
|
return SecureRandom.random_number(min..max)
|
|
end
|
|
end
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def reciprocal_Phi_p(n,p)
|
|
u = extended_euklides(n,p)[0]
|
|
v = extended_euklides(n,p)[1]
|
|
|
|
if (u * n % p) == 1
|
|
if u < 0
|
|
return u + p
|
|
end
|
|
return u
|
|
else
|
|
if v < 0
|
|
return v + p
|
|
end
|
|
return v
|
|
end
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def betterExponentiation(x,k,n)
|
|
if n == 0
|
|
return false
|
|
end
|
|
|
|
if x < n && x > 0
|
|
b = k.to_s(2).reverse
|
|
l = b.count "[0-1]"
|
|
y = 1
|
|
i = l - 1
|
|
|
|
while i >= 0
|
|
y = y**2 % n
|
|
if b[i]=="1"
|
|
y = y * x % n
|
|
end
|
|
i = i - 1
|
|
end
|
|
return y
|
|
end
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def remSqEuler(a,p)
|
|
ans = betterExponentiation(a,(p-1)/2,p)
|
|
|
|
if ans == 1 && Prime.prime?(p)
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def squareRootFp(p,b)
|
|
if p % 4 == 3 && remSqEuler(p,b) == true
|
|
a = betterExponentiation(b, (p+1)/4, p)
|
|
return a
|
|
end
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def primalityTest(n)
|
|
if n == 1
|
|
return false
|
|
end
|
|
|
|
if n == 2 || n == 3
|
|
return true
|
|
end
|
|
|
|
counter = 10
|
|
while (counter != 0) do
|
|
b = SecureRandom.random_number(2..n-2) # Tez dziala n-1
|
|
if betterExponentiation(b,n-1,n) != 1
|
|
return false
|
|
end
|
|
counter = counter - 1
|
|
end
|
|
return true
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def specyficPrimaryNumber
|
|
p = 0
|
|
q = 0
|
|
|
|
qThread = Thread.new {
|
|
while true
|
|
q = SecureRandom.random_number(2 ** 256)
|
|
if primalityTest(q)
|
|
break
|
|
end
|
|
end
|
|
}
|
|
|
|
qThread.join
|
|
|
|
while true do
|
|
q = SecureRandom.random_number(2 ** 256)
|
|
p = 2 * q + 1
|
|
if primalityTest(p)
|
|
return p,q
|
|
end
|
|
end
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def generator(p,q)
|
|
while true
|
|
g = SecureRandom.random_number(2..p-2)
|
|
if betterExponentiation(g,q,p) == 1
|
|
next
|
|
else
|
|
return g
|
|
end
|
|
end
|
|
end
|
|
|
|
####################################
|
|
# Funkcja nwd(a,b)
|
|
#
|
|
# Oblicza nwd podanych liczb np
|
|
# nwd(10,14) => 2
|
|
#
|
|
####################################
|
|
def generate(n)
|
|
return `openssl prime -generate -bits '#{n}'`.gsub(/\n$/, '').to_i
|
|
end
|