Task: Elliptic curve arithmetic




Go: package main

import (
    "fmt"
    "math"
)

const bCoeff = 7

type pt struct{ x, y float64 }

func zero() pt {
    return pt{math.Inf(1), math.Inf(1)}
}

func is_zero(p pt) bool {
    return p.x > 1e20 || p.x < -1e20
}

func neg(p pt) pt {
    return pt{p.x, -p.y}
}

func dbl(p pt) pt {
    if is_zero(p) {
        return p
    }
    L := (3 * p.x * p.x) / (2 * p.y)
    x := L*L - 2*p.x
    return pt{
        x: x,
        y: L*(p.x-x) - p.y,
    }
}

func add(p, q pt) pt {
    if p.x == q.x && p.y == q.y {
        return dbl(p)
    }
    if is_zero(p) {
        return q
    }
    if is_zero(q) {
        return p
    }
    L := (q.y - p.y) / (q.x - p.x)
    x := L*L - p.x - q.x
    return pt{
        x: x,
        y: L*(p.x-x) - p.y,
    }
}

func mul(p pt, n int) pt {
    r := zero()
    for i := 1; i <= n; i <<= 1 {
        if i&n != 0 {
            r = add(r, p)
        }
        p = dbl(p)
    }
    return r
}

func show(s string, p pt) {
    fmt.Printf("%s", s)
    if is_zero(p) {
        fmt.Println("Zero")
    } else {
        fmt.Printf("(%.3f, %.3f)\n", p.x, p.y)
    }
}

func from_y(y float64) pt {
    return pt{
        x: math.Cbrt(y*y - bCoeff),
        y: y,
    }
}
    
func main() {
    a := from_y(1)
    b := from_y(2)
    show("a = ", a)
    show("b = ", b)
    c := add(a, b)
    show("c = a + b = ", c)
    d := neg(c)
    show("d = -c = ", d)
    show("c + d = ", add(c, d))
    show("a + b + d = ", add(a, add(b, d)))
    show("a * 12345 = ", mul(a, 12345))
}




Python: 

class Point:
    b = 7
    def __init__(self, x=float('inf'), y=float('inf')):
        self.x = x
        self.y = y

    def copy(self):
        return Point(self.x, self.y)

    def is_zero(self):
        return self.x > 1e20 or self.x < -1e20

    def neg(self):
        return Point(self.x, -self.y)

    def dbl(self):
        if self.is_zero():
            return self.copy()
        try:
            L = (3 * self.x * self.x) / (2 * self.y)
        except ZeroDivisionError:
            return Point()
        x = L * L - 2 * self.x
        return Point(x, L * (self.x - x) - self.y)

    def add(self, q):
        if self.x == q.x and self.y == q.y:
            return self.dbl()
        if self.is_zero():
            return q.copy()
        if q.is_zero():
            return self.copy()
        try:
            L = (q.y - self.y) / (q.x - self.x)
        except ZeroDivisionError:
            return Point()
        x = L * L - self.x - q.x
        return Point(x, L * (self.x - x) - self.y)

    def mul(self, n):
        p = self.copy()
        r = Point()
        i = 1
        while i <= n:
            if i&n:
                r = r.add(p)
            p = p.dbl()
            i <<= 1
        return r

    def __str__(self):
        return "({:.3f}, {:.3f})".format(self.x, self.y)

def show(s, p):
    print(s, "Zero" if p.is_zero() else p)

def from_y(y):
    n = y * y - Point.b
    x = n**(1./3) if n>=0 else -((-n)**(1./3))
    return Point(x, y)


a = from_y(1)
b = from_y(2)
show("a =", a)
show("b =", b)
c = a.add(b)
show("c = a + b =", c)
d = c.neg()
show("d = -c =", d)
show("c + d =", c.add(d))
show("a + b + d =", a.add(b.add(d)))
show("a * 12345 =", a.mul(12345))