Skip to content

Instantly share code, notes, and snippets.

@kuboon
Created April 10, 2018 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kuboon/d1b0e9dab163f0da11eda1c79c625efd to your computer and use it in GitHub Desktop.
Save kuboon/d1b0e9dab163f0da11eda1c79c625efd to your computer and use it in GitHub Desktop.
matrix encryption protocol (cayley hamilton safe!)
require 'matrix'
gem 'ruby-numtheory'
require 'numtheory'
def IntegerModRing(mod)
class_name = "IntegerModRing#{mod}"
return Kernel.const_get class_name rescue nil
cls = Class.new do |cls|
define_method :initialize do |int|
@int = int % mod
end
def to_i
@int
end
def abs
@int
end
define_method :to_s do
"#{@int}" # (mod #{mod})"
end
def ==(other)
@int == other.to_i
end
def +(other)
new(@int + other.to_i)
end
def -(other)
new(@int - other.to_i)
end
def *(other)
new(@int * other.to_i)
end
def **(other)
new(@int * other.to_i)
end
define_method :quo do |other|
return self if @int.zero?
case other
when Integer, cls
new(@int * other.to_i.inverse(mod))
when Rational
new(@int * other.denominator * other.numerator.inverse(mod) )
else
raise "not impl #{other.class}"
end
rescue ArgumentError => e
raise "#{e} #{other} mod #{mod}"
end
alias_method :/, :quo
define_method :coerce do |other|
case other
when Integer
[new(other), self]
when Rational
[new(other.numerator).quo(other.denominator), self]
else
raise "not impl #{other}"
end
end
private
def new(int)
self.class.new(int)
end
end
Kernel.const_set(class_name, cls)
cls
end
def randInt
n = 2^256
rand(n/10..n)
end
def randMatrix
Matrix.build(3){IntegerModRing(9011).new(randInt)}
end
class Alice
def initialize
@a = randInt
@b = randInt
@c = randInt
@d = randInt
@A = randMatrix
end
def public_keys
@X = randMatrix()
@Y = @X**@a * @A**@c * @X**-@a
@Z = @X**@b * @A**(@c * @d) * @X**-@b
[@X, @Y, @Z]
end
def decode(_C1, _MC2)
_C2 = @X**(@b - @a) * _C1**@d * @X**(@a - @b)
_MC2 * _C2**-1
end
end
class Bob
def initialize(x, y, z)
@X = x
@Y = y
@Z = z
end
def encode(_M)
r = randInt
s = randInt
_C1 = @X**r * @Y**s * @X**-r
_C2 = @X**r * @Z**s * @X**-r
[_C1, _M*_C2]
end
end
if caller.length == 0
_M = randMatrix
alice = Alice.new
pub_keys = alice.public_keys()
puts pub_keys
bob = Bob.new(*pub_keys)
_C1, _MC2 = bob.encode(_M)
puts _C1, _MC2
_M2 = alice.decode(_C1, _MC2)
puts _M2
if _M == _M2
puts('success')
else
puts('fail')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment