Skip to content

Instantly share code, notes, and snippets.

@cciollaro
Last active May 10, 2016 21:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cciollaro/a18f0b4d3e3a91eecfb6 to your computer and use it in GitHub Desktop.
Save cciollaro/a18f0b4d3e3a91eecfb6 to your computer and use it in GitHub Desktop.
socialist millionaire with tcp sockets
require 'socket'
#http://www.scribd.com/doc/34203336/How-to-Implement-RSA-in-Ruby#download
# Calculate a modular exponentiation eg: b^p mod m
def mod_pow(base, power, mod)
result = 1
while power > 0
result = (result * base) % mod if power & 1 == 1
base = (base * base) % mod
power >>= 1
end
result
end
# Convert a string into a big number
def str_to_bignum(s)
n = 0
s.each_byte {|b|n=n*256+b}
n
end
# Convert a bignum to a string
def bignum_to_str(n)
s=""
while n>0
s = (n&0xff).chr + s
n >>= 8
end
s
end
#http://rosettacode.org/wiki/Modular_inverse#Ruby
#based on pseudo code from http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Iterative_method_2 and from translating the python implementation.
def extended_gcd(a, b)
last_remainder, remainder = a.abs, b.abs
x, last_x, y, last_y = 0, 1, 1, 0
while remainder != 0
last_remainder, (quotient, remainder) = remainder, last_remainder.divmod(remainder)
x, last_x = last_x - quotient*x, x
y, last_y = last_y - quotient*y, y
end
return last_remainder, last_x * (a < 0 ? -1 : 1)
end
def invmod(e, et)
g, x = extended_gcd(e, et)
if g != 1
raise 'Teh maths are broken!'
end
x % et
end
#puts variable name and value
def debug(sym)
puts "#{sym} is #{eval sym.to_s, TOPLEVEL_BINDING}"
end
if ARGV.size < 2
puts "usages: ruby socialist_milli.rb <ip address> <secret> <optional:your port:default 44444> <optional:their_port:default 44444>"
exit 1
end
begin
socket = TCPSocket.new ARGV[0], ARGV[3] || 44444
guy2 = true
rescue
server = TCPServer.new ARGV[2] || 44444
socket = server.accept
guy2 = false
end
# A prime and a generator (primitive root) for that prime.
# Can be same as OTR: http://www.ietf.org/rfc/rfc3526.txt
#prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
prime = 97
h = 5
x = str_to_bignum ARGV[1]
puts "your secret num is #{x}"
a = guy2 ? 4 : 2
alpha = guy2 ? 5 : 3
r = guy2 ? 6 : 9
h_to_the_a = mod_pow(h,a,prime)
socket.puts h_to_the_a
h_to_the_b = socket.gets.to_i
g = mod_pow(h_to_the_b, a, prime)
debug :g
h_to_the_alpha = mod_pow(h,alpha,prime)
socket.puts h_to_the_alpha
h_to_the_beta = socket.gets.to_i
gamma = mod_pow(h_to_the_beta, alpha, prime)
debug :gamma
p = mod_pow(gamma,r,prime)
socket.puts p
q = socket.gets.to_i
debug :p
debug :q
t = q*invmod(p, prime) % prime
debug :t
p_prime = (mod_pow(h,r,prime)*mod_pow(h,x,prime)) % prime
socket.puts p_prime
q_prime = socket.gets.to_i
debug :p_prime
debug :q_prime
p_prime_q_prime_inverse_to_the_alpha = mod_pow(((p_prime*invmod(q_prime, prime)) % prime),alpha, prime)
socket.puts p_prime_q_prime_inverse_to_the_alpha
p_prime_q_prime_inverse_to_the_beta = socket.gets.to_i
debug :p_prime_q_prime_inverse_to_the_beta
c = mod_pow(p_prime_q_prime_inverse_to_the_beta,alpha,prime)
debug :c
puts c == t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment