Skip to content

Commit

Permalink
Refactoring in Naive Form
Browse files Browse the repository at this point in the history
  • Loading branch information
Bhargavasomu committed Dec 10, 2018
1 parent 212b193 commit a005da2
Show file tree
Hide file tree
Showing 27 changed files with 987 additions and 1,940 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ chains
# tox/pytest cache
.cache

# mypy
.mypy_cache/

# Test output logs
logs
### JetBrains template
Expand Down
291 changes: 291 additions & 0 deletions py_ecc/BaseCurve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
from abc import (
abstractmethod,
)

from typing import (
cast,
)

from py_ecc.field_elements import (
FQP,
)

from py_ecc.optimized_field_elements import (
FQP as optimized_FQP,
)

from py_ecc.new_typing import (
Field,
GeneralPoint,
Point2D,
)
from py_ecc.new_typing import (
Optimized_Field,
Optimized_Point2D,
Optimized_Point3D,
)


class BaseCurve:
# Name of the curve can be "bn128" or "bls12_381"
curve_name = None
curve_order = None
# Curve is y**2 = x**3 + b
b = None
# Twisted curve over FQ**2
b2 = None
# Extension curve over FQ**12; same b value as over FQ
b12 = None
# Generator for curve over FQ
G1 = None
# Generator for twisted curve over FQ2
G2 = None
# Generator for twisted curve over FQ12
G12 = None
# Point at infinity over FQ
Z1 = None
# Point at infinity for twisted curve over FQ2
Z2 = None

def __init__(self, curve_properties, curve_name):
self.curve_name = curve_name
self.curve_order = curve_properties[curve_name]["curve_order"]
self.b = curve_properties[curve_name]["b"]
self.b2 = curve_properties[curve_name]["b2"]
self.b12 = curve_properties[curve_name]["b12"]
self.G1 = curve_properties[curve_name]["G1"]
self.G2 = curve_properties[curve_name]["G2"]
self.G12 = self.twist(cast(Point2D[FQP], self.G2))
self.Z1 = curve_properties[curve_name]["Z1"]
self.Z2 = curve_properties[curve_name]["Z2"]

def is_inf(self, pt: GeneralPoint[Field]) -> bool:
"""
Check if a point is the point at infinity
"""
return pt is None

def is_on_curve(self, pt: Point2D[Field], b: Field) -> bool:
"""
Check that a point is on the curve
"""
if self.is_inf(pt):
return True
x, y = pt
return y**2 == x**3 + b

def double(self, pt: Point2D[Field]) -> Point2D[Field]:
"""
Elliptic Curve Doubling (P+P).
"""
x, y = pt
m = (3 * x**2) / (2 * y)
newx = m**2 - 2 * x
newy = -m * newx + m * x - y
return (newx, newy)

def add(self,
p1: Point2D[Field],
p2: Point2D[Field]) -> Point2D[Field]:
"""
Elliptic curve addition.
"""
if p1 is None or p2 is None:
return p1 if p2 is None else p2
x1, y1 = p1
x2, y2 = p2
if x2 == x1 and y2 == y1:
return self.double(p1)
elif x2 == x1:
return None
else:
m = (y2 - y1) / (x2 - x1)
newx = m**2 - x1 - x2
newy = -m * newx + m * x1 - y1
assert newy == (-m * newx + m * x2 - y2)
return (newx, newy)

def multiply(self, pt: Point2D[Field], n: int) -> Point2D[Field]:
"""
Elliptic curve point multiplication.
"""
if n == 0:
return None
elif n == 1:
return pt
elif not n % 2:
# print(n//2)
return self.multiply(self.double(pt), n // 2)
else:
# print(n//2)
return self.add(self.multiply(self.double(pt), n // 2), pt)

def eq(self, p1: GeneralPoint[Field], p2: GeneralPoint[Field]) -> bool:
"""
Check if 2 points are equal.
"""
return p1 == p2

def neg(self, pt: Point2D[Field]) -> Point2D[Field]:
"""
Gives the reflection of point wrt x-axis (P => -P).
"""
if pt is None:
return None
x, y = pt
return (x, -y)

@abstractmethod
def twist(self, pt: Point2D[FQP]) -> Point2D[FQP]:
"""
'Twist' a point in E(FQ2) into a point in E(FQ12)
"""
raise NotImplementedError("Must be implemented by subclasses")


class BaseOptimizedCurve:
# Name of the curve can be "bn128" or "bls12_381"
curve_name = None
curve_order = None
# Curve is y**2 = x**3 + b
b = None
# Twisted curve over FQ**2
b2 = None
# Extension curve over FQ**12; same b value as over FQ
b12 = None
# Generator for curve over FQ
G1 = None
# Generator for twisted curve over FQ2
G2 = None
# Generator for curve over FQ12
G12 = None
# Point at infinity over FQ
Z1 = None
# Point at infinity for twisted curve over FQ2
Z2 = None

def __init__(self, curve_properties, curve_name):
self.curve_name = curve_name
self.curve_order = curve_properties[curve_name]["curve_order"]
self.b = curve_properties[curve_name]["b"]
self.b2 = curve_properties[curve_name]["b2"]
self.b12 = curve_properties[curve_name]["b12"]
self.G1 = curve_properties[curve_name]["G1"]
self.G2 = curve_properties[curve_name]["G2"]
self.G12 = self.twist(cast(Optimized_Point3D[optimized_FQP], self.G2))
self.Z1 = curve_properties[curve_name]["Z1"]
self.Z2 = curve_properties[curve_name]["Z2"]

def is_inf(self, pt: Optimized_Point3D[Optimized_Field]) -> bool:
"""
Check if a point is the point at infinity
"""
return pt[-1] == (type(pt[-1]).zero(self.curve_name))

def is_on_curve(self, pt: Optimized_Point3D[Optimized_Field], b: Field) -> bool:
"""
Check that a point is on the curve defined by y**2 == x**3 + b
"""
if self.is_inf(pt):
return True
x, y, z = pt
return y**2 * z == x**3 + (b * z**3)

def double(self, pt: Optimized_Point3D[Optimized_Field]) -> Optimized_Point3D[Optimized_Field]:
"""
Elliptic curve doubling
"""
x, y, z = pt
W = 3 * x * x
S = y * z
B = x * y * S
H = W * W - 8 * B
S_squared = S * S
newx = 2 * H * S
newy = W * (4 * B - H) - 8 * y * y * S_squared
newz = 8 * S * S_squared
return (newx, newy, newz)

def add(self,
p1: Optimized_Point3D[Optimized_Field],
p2: Optimized_Point3D[Optimized_Field]) -> Optimized_Point3D[Optimized_Field]:
"""
Elliptic curve addition
"""
one, zero = type(p1[0]).one(self.curve_name), type(p1[0]).zero(self.curve_name)
if p1[2] == zero or p2[2] == zero:
return p1 if p2[2] == zero else p2
x1, y1, z1 = p1
x2, y2, z2 = p2
U1 = y2 * z1
U2 = y1 * z2
V1 = x2 * z1
V2 = x1 * z2
if V1 == V2 and U1 == U2:
return self.double(p1)
elif V1 == V2:
return (one, one, zero)
U = U1 - U2
V = V1 - V2
V_squared = V * V
V_squared_times_V2 = V_squared * V2
V_cubed = V * V_squared
W = z1 * z2
A = U * U * W - V_cubed - 2 * V_squared_times_V2
newx = V * A
newy = U * (V_squared_times_V2 - A) - V_cubed * U2
newz = V_cubed * W
return (newx, newy, newz)

def multiply(self,
pt: Optimized_Point3D[Optimized_Field],
n: int) -> Optimized_Point3D[Optimized_Field]:
"""
Elliptic curve point multiplication
"""
if n == 0:
return (
type(pt[0]).one(self.curve_name),
type(pt[0]).one(self.curve_name),
type(pt[0]).zero(self.curve_name)
)
elif n == 1:
return pt
elif not n % 2:
return self.multiply(self.double(pt), n // 2)
else:
return self.add(self.multiply(self.double(pt), int(n // 2)), pt)

def eq(self,
p1: Optimized_Point3D[Optimized_Field],
p2: Optimized_Point3D[Optimized_Field]) -> bool:
"""
Check if 2 points are equal.
"""
x1, y1, z1 = p1
x2, y2, z2 = p2
return x1 * z2 == x2 * z1 and y1 * z2 == y2 * z1

def normalize(self,
pt: Optimized_Point3D[Optimized_Field]) -> Optimized_Point2D[Optimized_Field]:
"""
Convert the Jacobian Point to a normal point
"""
x, y, z = pt
return (x / z, y / z)

def neg(self, pt: Optimized_Point3D[Optimized_Field]) -> Optimized_Point3D[Optimized_Field]:
"""
Gives the reflection of point wrt x-axis (P => -P).
"""
if pt is None:
return None
x, y, z = pt
return (x, -y, z)

@abstractmethod
def twist(self, pt: Optimized_Point3D[optimized_FQP]) -> Optimized_Point3D[optimized_FQP]:
"""
'Twist' a point in E(FQ2) into a point in E(FQ12)
"""
raise NotImplementedError("Must be implemented by subclasses")
32 changes: 0 additions & 32 deletions py_ecc/bls12_381/__init__.py

This file was deleted.

Loading

0 comments on commit a005da2

Please sign in to comment.