Skip to content

Instantly share code, notes, and snippets.

@udonchan
Created July 28, 2010 13:16
楕円曲線上の法の有限体で足し算とかけ算
module ECC
class ECC_Point
def initialize(x, y)
@x = reduce(x, MOD)
@y = reduce(y, MOD)
end
def zero?
(@x == 0 && @y == 0)
end
def validPoint?
EC_func::l(@y) % MOD == EC_func::r(@x) % MOD
end
def multipl(k)
bin = reduce(k, ORD).to_s(2)
rev = bin.reverse
res = (rev[0].chr == '1') ? self : ECC::ECC_Point.new(0, 0)
w = [self]
(1..(rev.size-1)).each do |i|
w[i] = w[i-1].add(w[i-1])
res = res.add(w[i]) if rev[i].chr == '1'
end
res
end
def to_s
"#{@x}, #{@y}"
end
def rev(n)
raise "bud input" if n % MOD == 0
r = [MOD, reduce(n, MOD)]
q = [0, 0]
x = [1, 0]
y = [0, 1]
(2..99).each do |i|
r[i] = r[i-2] % r[i-1]
return reduce( y[i-1] , MOD) if r[i] == 0
q[i] = ( r[i-2] - r[i] ) / r[i-1]
x[i] = x[i-2] - q[i] * x[i-1]
y[i] = y[i-2] - q[i] * y[i-1]
end
raise 'loop too short'
end
def add(other)
return self if other.zero?
return other if zero?
raise "something wrong" if @x == other.x && @y != other.y
if @x == other.x && @y == other.y
return ECC::ECC_Point.new(0, 0) if (@y * 2) % MOD == 0
l = EC_func.dif_r(@x) * rev(EC_func.dif_l(@y))
else
l = (other.y - @y) * rev(other.x - @x)
end
tx = (l % MOD)**2 - @x - other.x
ECC::ECC_Point.new(reduce(tx, MOD), reduce(l * (@x-tx) - @y, MOD))
end
def reduce(n, mod)
return n % mod if n >= 0
return ((n.abs/mod).ceil * mod + n) % mod
end
attr_reader:x
attr_reader:y
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment