97 lines
1.8 KiB
Plaintext
97 lines
1.8 KiB
Plaintext
module EC {
|
|
|
|
var A = 0
|
|
var B = 7
|
|
|
|
class Horizon {
|
|
method to_s {
|
|
"EC Point at horizon"
|
|
}
|
|
|
|
method *(_) {
|
|
self
|
|
}
|
|
|
|
method -(_) {
|
|
self
|
|
}
|
|
}
|
|
|
|
class Point(Number x, Number y) {
|
|
method to_s {
|
|
"EC Point at x=#{x}, y=#{y}"
|
|
}
|
|
|
|
method neg {
|
|
Point(x, -y)
|
|
}
|
|
|
|
method -(Point p) {
|
|
self + -p
|
|
}
|
|
|
|
method +(Point p) {
|
|
|
|
if (x == p.x) {
|
|
return (y == p.y ? self*2 : Horizon())
|
|
}
|
|
else {
|
|
var slope = (p.y - y)/(p.x - x)
|
|
var x2 = (slope**2 - x - p.x)
|
|
var y2 = (slope * (x - x2) - y)
|
|
Point(x2, y2)
|
|
}
|
|
}
|
|
|
|
method +(Horizon _) {
|
|
self
|
|
}
|
|
|
|
method *((0)) {
|
|
Horizon()
|
|
}
|
|
|
|
method *((1)) {
|
|
self
|
|
}
|
|
|
|
method *((2)) {
|
|
var l = (3 * x**2 + A)/(2 * y)
|
|
var x2 = (l**2 - 2*x)
|
|
var y2 = (l * (x - x2) - y)
|
|
Point(x2, y2)
|
|
}
|
|
|
|
method *(Number n) {
|
|
2*(self * (n>>1)) + self*(n % 2)
|
|
}
|
|
}
|
|
|
|
class Horizon {
|
|
method +(Point p) {
|
|
p
|
|
}
|
|
}
|
|
|
|
class Number {
|
|
method +(Point p) {
|
|
p + self
|
|
}
|
|
method *(Point p) {
|
|
p * self
|
|
}
|
|
method *(Horizon h) {
|
|
h
|
|
}
|
|
method -(Point p) {
|
|
-p + self
|
|
}
|
|
}
|
|
}
|
|
|
|
say var p = with(1) {|v| EC::Point(v, sqrt(abs(1 - v**3 - EC::A*v - EC::B))) }
|
|
say var q = with(2) {|v| EC::Point(v, sqrt(abs(1 - v**3 - EC::A*v - EC::B))) }
|
|
say var s = (p + q)
|
|
|
|
say ("checking alignment: ", abs((p.x - q.x)*(-s.y - q.y) - (p.y - q.y)*(s.x - q.x)) < 1e-20)
|