Skip to content

Instantly share code, notes, and snippets.

@azuchi
Created January 8, 2021 08:56
Show Gist options
  • Save azuchi/58799e1307b9e0bf56a2ef853662a751 to your computer and use it in GitHub Desktop.
Save azuchi/58799e1307b9e0bf56a2ef853662a751 to your computer and use it in GitHub Desktop.
射影座標を使ったスカラー倍算サンプル
require 'ecdsa'
class ProjectivePoint
attr_reader :x
attr_reader :y
attr_reader :z
attr_reader :field
def initialize(x, y ,z)
@x =x
@y = y
@z = z
@field = ECDSA::Group::Secp256k1.field
end
# Convert coordinate from affine
def self.from_affine(x, y)
new(x, y, 1)
end
def self.infinity
new(0, 1, 0)
end
def infinity?
x == 0 && z == 0
end
def add(other)
return other if infinity?
t0 = field.mod(y * other.z)
t1 = field.mod(other.y * z)
u0 = field.mod(x * other.z)
u1 = field.mod(other.x * z)
return double if u0 == u1 && t0 == t1
t = field.mod(t0 - t1)
u = field.mod(u0 - u1)
u2 = field.mod(u * u)
v = field.mod(z * other.z)
w = field.mod(t * t* v - u2 * (u0 + u1))
u3 = field.mod(u * u2)
new_x = field.mod(u * w)
new_y = field.mod(t * (u0 * u2 - w) - t0 * u3)
new_z = field.mod(u3 * v)
ProjectivePoint.new(new_x, new_y, new_z)
end
def double
w = field.mod(3 * x**2)
s = field.mod(y * z)
b = field.mod(s * x * y)
h = field.mod(w**2 - 8 * b)
new_x = field.mod(2 * h * s)
new_y = field.mod(w * (4 * b - h) - 8 * y**2 * s**2)
new_z = field.mod(8 * s**3)
ProjectivePoint.new(new_x, new_y, new_z)
end
def to_affine
ECDSA::Point.new(ECDSA::Group::Secp256k1, field.mod(x * field.inverse(z)), field.mod(y * field.inverse(z)))
end
def multiply_by_scalar(x)
q = ProjectivePoint.infinity
v = self
i = x
while i > 0
q = q.add(v) if i.odd?
v = v.double
i >>= 1
end
q
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment