Created
February 9, 2019 20:04
-
-
Save narukami894/5cf894eb1fa4177a63f365c597ffd89c to your computer and use it in GitHub Desktop.
なんちゃってRSA暗号実装
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "inline" | |
require "prime" | |
class RSA | |
class << self | |
def generate | |
p, q = generate_unique_primes | |
n = p * q | |
e = (p - 1) * (q - 1) - 1 | |
d = generate_secret_key(e, (p - 1) * (q - 1)) | |
puts "Public Key: '#{n}:#{e}'" | |
puts "Secret Key: '#{d}'" # TODO 1: eとdの値が一緒になってしまう | |
end | |
def encrypt(message, public_key) | |
m = message # TODO 2: 文字列を数値に変換できるようにする | |
n = public_key.split(":").first.to_i | |
e = public_key.split(":").last.to_i | |
puts "Code: '#{(m ** e) % n}'" | |
# TODO 3: 数が大きいとべき乗で warning: in a**b, b may be too big のエラーが出る | |
end | |
def decrypt(code, public_key, secret_key) | |
c = code | |
n = public_key.split(":").first.to_i | |
d = secret_key.to_i | |
puts "Message: '#{(c ** d) % n}'" | |
end | |
private | |
def generate_unique_primes | |
p, q = 0, 0 | |
loop do | |
p = Random.new.rand(100...1000) | |
break if p.prime? | |
end | |
loop do | |
q = Random.new.rand(100...1000) | |
break if q.prime? && p != q | |
end | |
[p, q] | |
end | |
def generate_secret_key(e, _i) | |
# TODO 4: 秘密鍵生成のもっとスマートなやりかたがあるはず | |
::GenerateSecretKey.new.execute(e, _i) | |
end | |
end | |
end | |
class GenerateSecretKey | |
inline do |builder| | |
builder.include "<math.h>" | |
builder.c %q{ | |
long execute(long e, long _i) { | |
long d = 0; | |
while (d * e % _i != 1 % _i) { d++; } | |
return d; | |
} | |
} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment