123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- #!/usr/bin/ruby
- #
- ## https://rosettacode.org/wiki/Elliptic_curve_arithmetic
- #
- 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)
- var bool = (abs((p.x - q.x)*(-s.y - q.y) - (p.y - q.y)*(s.x - q.x)) < 1e-20)
- say "checking alignment: #{bool}"
- assert_eq(bool, true)
|