diff --git a/Cryptotools/Groups/curve.py b/Cryptotools/Groups/curve.py
new file mode 100644
index 0000000..0cb697e
--- /dev/null
+++ b/Cryptotools/Groups/curve.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+
+from Cryptotools.Groups.elliptic import Point
+import numpy as np
+from math import sqrt
+
+
+class Curve:
+ # Curve
+ WEIERSTRASS = 0
+ MONTGOMERY = 1
+
+
+ def __init__(self, a, b, t):
+ self._a = a
+ self._b = b
+
+ if t not in (Curve.WEIERSTRASS, Curve.MONTGOMERY):
+ raise Exception(f"The type of the curve is not recognized")
+
+ self._type = t
+ self._xtmp = np.linspace(-5, 5, 500).tolist()
+ self._x = list()
+ self._y = list()
+ self._yn = list()
+ self._points = list()
+ self._pointsSym = list()
+
+ def f(self, x):
+ if self._type == Curve.WEIERSTRASS:
+ y = pow(x, 3) + (self._a * x) + self._b
+ if self._type == Curve.MONTGOMERY:
+ y = pow(x, 3) + (3 * pow(x, 2)) + x
+ if y > 0:
+ return sqrt(y)
+ return None
+
+ def generatePoints(self):
+ for x in self._xtmp:
+ y = self.f(x)
+ if y is None:
+ continue
+
+ self._x.append(x)
+ self._y.append(y)
+ self._yn.append(-y)
+ self._points.append(Point(
+ x,
+ y
+ ))
+ self._pointsSym.append(Point(
+ x,
+ -y
+ ))
+
+ @property
+ def x(self):
+ return self._x
+
+ @property
+ def y(self):
+ return self._y
+
+ @property
+ def yn(self):
+ return self._yn
+
+ def getPoints(self):
+ return self._points
+
+ def getPointsSym(self):
+ return self._pointsSym
+
+ def add(self, P, Q) -> Point:
+ """
+ This function operathe addition operation on two points P and Q
+
+ Args:
+ P (Object): The first Point on the curve
+ Q (Object): The second Point on the curve
+
+ Returns:
+ Return the Point object R
+ """
+
+ ## Check if P or Q are infinity
+ if (P.x, P.y) == (0, 0) and (Q.x, Q.y) == (0, 0):
+ return Point(0, 0)
+ elif (P.x, P.y) == (0, 0):
+ return Point(Q.x, Q.y)
+ elif (Q.x, Q.y) == (0, 0):
+ return Point(P.x, P.y)
+
+ # point doubling
+ if P.x == Q.x:
+ # Infinity
+ if P.y != Q.y or Q.y == 0:
+ return Point(0, 0)
+
+ # Point doubling
+ try:
+ inv = pow(2 * P.y, -1); # It's working with the inverse modular, WHY ???
+ m = ((3 * pow(P.x, 2)) + self._a) * inv
+ except ValueError:
+ return Point(0, 0)
+
+ else:
+ try:
+ inv = pow(Q.x - P.x, -1)
+ m = (Q.y - P.y) * inv
+ except ValueError:
+ # May call this Exception: base is not invertible for the given modulus
+ # I return an Infinity point until I fixed that
+ return Point(0, 0)
+
+ xr = (pow(m, 2) - P.x - Q.x)
+
+ yr = (m * (P.x - xr)) - P.y
+ return Point(xr, yr)
+
+ def scalar(self, P, n) -> Point:
+ """
+ This function compute a Scalar Multiplication of P, n time. This algorithm is also known as Double and Add.
+
+ Args:
+ P (point): the Point to multiplication
+ n (Integer): multiplicate n time P
+
+ Returns:
+ Return the result of the Scalar multiplication
+ """
+ binary = bin(n)[2:]
+ binary = binary[::-1] # We need to reverse the binary
+
+ nP = Point(0, 0)
+ Rtmp = P
+
+ for b in binary:
+ if b == '1':
+ nP = self.add(nP, Rtmp)
+ Rtmp = self.add(Rtmp, Rtmp) # Double P
+
+ return nP
+
+ def find_reverse(self, P):
+ """
+ This function return the reverse of the Point P
+ Args:
+ P (Point): Point object to find
+
+ Returns:
+ Return the object Pr, which is the reverse point of P
+ """
+ Pr = None
+ for p in self._pointsSym:
+ if P.x == p.x and -P.y == p.y:
+ Pr = Point(p.x, p.y)
+ break
+ return Pr
diff --git a/Cryptotools/Groups/point.py b/Cryptotools/Groups/point.py
new file mode 100644
index 0000000..0ed5c7c
--- /dev/null
+++ b/Cryptotools/Groups/point.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+
+class Point:
+ """
+ This simple class represent the Point at the coordinate x and y in a plan
+
+ Attributes:
+ x (Integer): Position at the x
+ y (Integer): Position at the y
+ """
+ def __init__(self, x, y):
+ self._x = x
+ self._y = y
+
+ @property
+ def x(self):
+ return self._x
+
+ @property
+ def y(self):
+ return self._y
+
+ @x.setter
+ def x(self, x):
+ self._x = x
+
+ @y.setter
+ def y(self, y):
+ self._y = y
+
+ def __eq__(self, other):
+ print(self._x, other.x)
+ return self._x == other.x and self._y == other.y
diff --git a/docs/curves.md b/docs/curves.md
new file mode 100644
index 0000000..608143e
--- /dev/null
+++ b/docs/curves.md
@@ -0,0 +1,6 @@
+# Elliptic Curves
+## Points
+::: Cryptotools.Groups.point
+
+## Curves
+::: Cryptotools.Groups.curve
diff --git a/docs/example-curves.md b/docs/example-curves.md
new file mode 100644
index 0000000..42382ef
--- /dev/null
+++ b/docs/example-curves.md
@@ -0,0 +1,30 @@
+# Generating Elliptic Curves
+
+In the following section, we are going to see how to generate Elliptic Curves and draw the curve with Python.
+
+## A Weierstrass Curve
+The python code below draw a Weierstrass Curve:
+
+```
+#!/usr/bin/env python3
+
+import matplotlib.pyplot as plt
+from Cryptotools.Groups.curve import Curve
+
+
+a = 3
+b = 8
+
+curve = Curve(a, b, Curve.WEIERSTRASS)
+x = curve.x
+curve.generatePoints()
+y = curve.y
+yn = curve.yn
+points = curve.getPoints()
+
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, color='b', label=f'$y^2 = x^3 + {a}x + {b}$')
+plt.plot(x, yn, color='b', )
+plt.legend()
+plt.show()
+```
diff --git a/docs/examples-rsa-keys.md b/docs/example-rsa-keys.md
similarity index 100%
rename from docs/examples-rsa-keys.md
rename to docs/example-rsa-keys.md
diff --git a/docs/index.md b/docs/index.md
index f434fae..5e9e02b 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -5,11 +5,12 @@
* Low-Level Cryptographic
* [Number Theory](/number-theory)
* [Group Theory](/group-theory)
+ * [Curves](/curves)
* Public Keys:
* [RSA](/rsa)
* Utils
* [Utils](/utils)
* Examples:
- * [Generating RSA keys](/examples-rsa-keys)
-
+ * [Generating RSA keys](/example-rsa-keys)
+ * [Generate curves](/example-curves)
diff --git a/examples/elliptic/curve.py b/examples/elliptic/curve.py
new file mode 100644
index 0000000..05fbfcc
--- /dev/null
+++ b/examples/elliptic/curve.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+
+import matplotlib.pyplot as plt
+from Cryptotools.Groups.curve import Curve
+
+
+a = 3
+b = 8
+
+curve = Curve(a, b, Curve.WEIERSTRASS)
+x = curve.x
+curve.generatePoints()
+y = curve.y
+yn = curve.yn
+points = curve.getPoints()
+
+#print(x)
+#print(y)
+
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, color='b', label=f'$y^2 = x^3 + {a}x + {b}$')
+plt.plot(x, yn, color='b', )
+plt.legend()
+plt.show()
diff --git a/examples/elliptic/curve_add.py b/examples/elliptic/curve_add.py
new file mode 100644
index 0000000..de70dd9
--- /dev/null
+++ b/examples/elliptic/curve_add.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+
+import matplotlib.pyplot as plt
+from Cryptotools.Groups.curve import Curve
+
+
+a = 3
+b = 8
+
+curve = Curve(a, b, Curve.WEIERSTRASS)
+x = curve.x
+curve.generatePoints()
+y = curve.y
+yn = curve.yn
+points = curve.getPoints()
+
+P = points[10]
+Q = points[55]
+R = points[247]
+#print(f"{P.x} {P.y}")
+#print(f"{Q.x} {Q.y}")
+
+# Make an addition
+Rp = curve.add(P, Q)
+#print(f"{Rp.x} {Rp.y}")
+
+#print(yn)
+#print(x)
+#print(y)
+
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, color='b', label=f'$y^2 = x^3 + {a}x + {b}$')
+plt.plot(x, yn, color='b', )
+plt.plot(P.x, P.y, marker='o', color="red")
+plt.annotate('P', (P.x, P.y + 0.5))
+
+plt.plot(Q.x, Q.y, marker='o', color="red")
+plt.annotate('Q', (Q.x, Q.y + 0.5))
+
+plt.plot(R.x, R.y, marker='o', color="red")
+plt.annotate('R', (R.x - 0.2, R.y + 0.5))
+
+plt.plot(Rp.x, Rp.y, marker='o', color="red")
+plt.annotate('R\'', (Rp.x - 0.2, Rp.y + 0.5))
+plt.axline([P.x, P.y], [Q.x, Q.y], color="red")
+plt.axline([R.x, R.y], [Rp.x, Rp.y], linestyle="--", color="red")
+plt.legend()
+plt.show()
diff --git a/examples/elliptic/curve_scalar.py b/examples/elliptic/curve_scalar.py
new file mode 100644
index 0000000..6f1d893
--- /dev/null
+++ b/examples/elliptic/curve_scalar.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+
+import matplotlib.pyplot as plt
+from Cryptotools.Groups.curve import Curve
+from Cryptotools.Groups.point import Point
+
+
+a = 3
+b = 8
+
+curve = Curve(a, b, Curve.WEIERSTRASS)
+x = curve.x
+curve.generatePoints()
+y = curve.y
+yn = curve.yn
+points = curve.getPoints()
+
+P = points[10]
+nP = curve.scalar(P, 5)
+print(f"{nP.x} {nP.y}")
+
+# For testing, we may add n times with the addition operation for the Scalar Multiplication
+tmp = Point(0, 0)
+for i in range(5):
+ tmp = curve.add(P, tmp)
+
+# Unfortunately, the result is approximatively the same
+# the multiplication need to be more accurate
+# if tmp == nP:
+# print(True)
+
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, color='b', label=f'$y^2 = x^3 + {a}x + {b}$')
+plt.plot(x, yn, color='b', )
+plt.plot(P.x, P.y, marker='o', color="red")
+plt.annotate('P', (P.x, P.y + 0.5))
+
+plt.plot(nP.x, nP.y, marker='o', color="red")
+plt.annotate('nP', (nP.x, nP.y + 0.5))
+
+
+
+plt.legend()
+plt.show()
diff --git a/examples/elliptic/point_at_infinity.py b/examples/elliptic/point_at_infinity.py
new file mode 100644
index 0000000..40b9e09
--- /dev/null
+++ b/examples/elliptic/point_at_infinity.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+
+from Cryptotools.Groups.point import Point
+from Cryptotools.Groups.curve import Curve
+import numpy as np
+import matplotlib.pyplot as plt
+from math import sqrt
+
+
+a = 3
+b = 8
+
+curve = Curve(a, b, Curve.WEIERSTRASS)
+x = curve.x
+curve.generatePoints()
+y = curve.y
+yn = curve.yn
+points = curve.getPoints()
+pointsReverse = curve.getPointsSym()
+
+P = points[10]
+Q = curve.find_reverse(P)
+
+# We made the addition
+# The result is the point at infinity
+R = curve.add(P, Q)
+print(f"{R.x} {R.y}")
+
+
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, color='b', label=f'$y^2 = x^3 + {a}x + {b}$')
+plt.plot(x, yn, color='b', )
+plt.plot(P.x, P.y, marker='o', color="red")
+plt.annotate('P', (P.x, P.y + 0.5))
+
+plt.plot(Q.x, Q.y, marker='o', color="red")
+plt.text(-1 , 11, f"R = infinity")
+plt.annotate('Q', (Q.x, Q.y + 0.5))
+
+
+plt.axline([P.x, P.y], [Q.x, Q.y], color="red")
+plt.legend()
+plt.show()
diff --git a/mkdocs.yml b/mkdocs.yml
index f04ea4d..ca3986a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -11,9 +11,11 @@ nav:
- Low-level cryptographic:
- Number theory: number-theory.md
- Group theory: group-theory.md
+ - Curves: curves.md
- Public Keys:
- RSA: rsa.md
- Utils:
- Utils: utils.md
- Examples:
- - Generating RSA Keys: examples-rsa-keys.md
+ - Generating RSA Keys: example-rsa-keys.md
+ - Generating Curves: example-curves.md
diff --git a/site/404.html b/site/404.html
index 7a70374..45594df 100644
--- a/site/404.html
+++ b/site/404.html
@@ -43,15 +43,24 @@
Group theory
+ Curves
+
Public Keys
+ Utils
+
Examples
diff --git a/site/curves/index.html b/site/curves/index.html
new file mode 100644
index 0000000..bef9f0d
--- /dev/null
+++ b/site/curves/index.html
@@ -0,0 +1,1096 @@
+
+
+
+
+
+
+
+ Curves - CryptoTools documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CryptoTools documentation
+
+
+
+
+
+
+ Low-level cryptographic
+ Curves
+
+
+
+
+
+
+
+
+
Elliptic Curves
+
Points
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This simple class represent the Point at the coordinate x and y in a plan
+
+
+
+
+
+
+
+
+
+ Attributes:
+
+
+
+ x
+ (Integer )
+ –
+
+
+
+ y
+ (Integer )
+ –
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Groups/point.py
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34 class Point :
+ """
+ This simple class represent the Point at the coordinate x and y in a plan
+
+ Attributes:
+ x (Integer): Position at the x
+ y (Integer): Position at the y
+ """
+ def __init__ ( self , x , y ):
+ self . _x = x
+ self . _y = y
+
+ @property
+ def x ( self ):
+ return self . _x
+
+ @property
+ def y ( self ):
+ return self . _y
+
+ @x . setter
+ def x ( self , x ):
+ self . _x = x
+
+ @y . setter
+ def y ( self , y ):
+ self . _y = y
+
+ def __eq__ ( self , other ):
+ print ( self . _x , other . x )
+ return self . _x == other . x and self . _y == other . y
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Curves
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Groups/curve.py
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159 class Curve :
+ # Curve
+ WEIERSTRASS = 0
+ MONTGOMERY = 1
+
+
+ def __init__ ( self , a , b , t ):
+ self . _a = a
+ self . _b = b
+
+ if t not in ( Curve . WEIERSTRASS , Curve . MONTGOMERY ):
+ raise Exception ( f "The type of the curve is not recognized" )
+
+ self . _type = t
+ self . _xtmp = np . linspace ( - 5 , 5 , 500 ) . tolist ()
+ self . _x = list ()
+ self . _y = list ()
+ self . _yn = list ()
+ self . _points = list ()
+ self . _pointsSym = list ()
+
+ def f ( self , x ):
+ if self . _type == Curve . WEIERSTRASS :
+ y = pow ( x , 3 ) + ( self . _a * x ) + self . _b
+ if self . _type == Curve . MONTGOMERY :
+ y = pow ( x , 3 ) + ( 3 * pow ( x , 2 )) + x
+ if y > 0 :
+ return sqrt ( y )
+ return None
+
+ def generatePoints ( self ):
+ for x in self . _xtmp :
+ y = self . f ( x )
+ if y is None :
+ continue
+
+ self . _x . append ( x )
+ self . _y . append ( y )
+ self . _yn . append ( - y )
+ self . _points . append ( Point (
+ x ,
+ y
+ ))
+ self . _pointsSym . append ( Point (
+ x ,
+ - y
+ ))
+
+ @property
+ def x ( self ):
+ return self . _x
+
+ @property
+ def y ( self ):
+ return self . _y
+
+ @property
+ def yn ( self ):
+ return self . _yn
+
+ def getPoints ( self ):
+ return self . _points
+
+ def getPointsSym ( self ):
+ return self . _pointsSym
+
+ def add ( self , P , Q ) -> Point :
+ """
+ This function operathe addition operation on two points P and Q
+
+ Args:
+ P (Object): The first Point on the curve
+ Q (Object): The second Point on the curve
+
+ Returns:
+ Return the Point object R
+ """
+
+ ## Check if P or Q are infinity
+ if ( P . x , P . y ) == ( 0 , 0 ) and ( Q . x , Q . y ) == ( 0 , 0 ):
+ return Point ( 0 , 0 )
+ elif ( P . x , P . y ) == ( 0 , 0 ):
+ return Point ( Q . x , Q . y )
+ elif ( Q . x , Q . y ) == ( 0 , 0 ):
+ return Point ( P . x , P . y )
+
+ # point doubling
+ if P . x == Q . x :
+ # Infinity
+ if P . y != Q . y or Q . y == 0 :
+ return Point ( 0 , 0 )
+
+ # Point doubling
+ try :
+ inv = pow ( 2 * P . y , - 1 ); # It's working with the inverse modular, WHY ???
+ m = (( 3 * pow ( P . x , 2 )) + self . _a ) * inv
+ except ValueError :
+ return Point ( 0 , 0 )
+
+ else :
+ try :
+ inv = pow ( Q . x - P . x , - 1 )
+ m = ( Q . y - P . y ) * inv
+ except ValueError :
+ # May call this Exception: base is not invertible for the given modulus
+ # I return an Infinity point until I fixed that
+ return Point ( 0 , 0 )
+
+ xr = ( pow ( m , 2 ) - P . x - Q . x )
+
+ yr = ( m * ( P . x - xr )) - P . y
+ return Point ( xr , yr )
+
+ def scalar ( self , P , n ) -> Point :
+ """
+ This function compute a Scalar Multiplication of P, n time. This algorithm is also known as Double and Add.
+
+ Args:
+ P (point): the Point to multiplication
+ n (Integer): multiplicate n time P
+
+ Returns:
+ Return the result of the Scalar multiplication
+ """
+ binary = bin ( n )[ 2 :]
+ binary = binary [:: - 1 ] # We need to reverse the binary
+
+ nP = Point ( 0 , 0 )
+ Rtmp = P
+
+ for b in binary :
+ if b == '1' :
+ nP = self . add ( nP , Rtmp )
+ Rtmp = self . add ( Rtmp , Rtmp ) # Double P
+
+ return nP
+
+ def find_reverse ( self , P ):
+ """
+ This function return the reverse of the Point P
+ Args:
+ P (Point): Point object to find
+
+ Returns:
+ Return the object Pr, which is the reverse point of P
+ """
+ Pr = None
+ for p in self . _pointsSym :
+ if P . x == p . x and - P . y == p . y :
+ Pr = Point ( p . x , p . y )
+ break
+ return Pr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This function operathe addition operation on two points P and Q
+
+
+
+
+
+
+
+
+
+ Parameters:
+
+
+
+ P
+ (Object )
+ –
+
+
The first Point on the curve
+
+
+
+ Q
+ (Object )
+ –
+
+
The second Point on the curve
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Returns:
+
+
+
+ Point
+ –
+
+
Return the Point object R
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Groups/curve.py
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119 def add ( self , P , Q ) -> Point :
+ """
+ This function operathe addition operation on two points P and Q
+
+ Args:
+ P (Object): The first Point on the curve
+ Q (Object): The second Point on the curve
+
+ Returns:
+ Return the Point object R
+ """
+
+ ## Check if P or Q are infinity
+ if ( P . x , P . y ) == ( 0 , 0 ) and ( Q . x , Q . y ) == ( 0 , 0 ):
+ return Point ( 0 , 0 )
+ elif ( P . x , P . y ) == ( 0 , 0 ):
+ return Point ( Q . x , Q . y )
+ elif ( Q . x , Q . y ) == ( 0 , 0 ):
+ return Point ( P . x , P . y )
+
+ # point doubling
+ if P . x == Q . x :
+ # Infinity
+ if P . y != Q . y or Q . y == 0 :
+ return Point ( 0 , 0 )
+
+ # Point doubling
+ try :
+ inv = pow ( 2 * P . y , - 1 ); # It's working with the inverse modular, WHY ???
+ m = (( 3 * pow ( P . x , 2 )) + self . _a ) * inv
+ except ValueError :
+ return Point ( 0 , 0 )
+
+ else :
+ try :
+ inv = pow ( Q . x - P . x , - 1 )
+ m = ( Q . y - P . y ) * inv
+ except ValueError :
+ # May call this Exception: base is not invertible for the given modulus
+ # I return an Infinity point until I fixed that
+ return Point ( 0 , 0 )
+
+ xr = ( pow ( m , 2 ) - P . x - Q . x )
+
+ yr = ( m * ( P . x - xr )) - P . y
+ return Point ( xr , yr )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This function return the reverse of the Point P
+Args:
+ P (Point): Point object to find
+
+
+
+
+
+
+
+
+
+ Returns:
+
+
+
+ –
+
+
Return the object Pr, which is the reverse point of P
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Groups/curve.py
+ 145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159 def find_reverse ( self , P ):
+ """
+ This function return the reverse of the Point P
+ Args:
+ P (Point): Point object to find
+
+ Returns:
+ Return the object Pr, which is the reverse point of P
+ """
+ Pr = None
+ for p in self . _pointsSym :
+ if P . x == p . x and - P . y == p . y :
+ Pr = Point ( p . x , p . y )
+ break
+ return Pr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This function compute a Scalar Multiplication of P, n time. This algorithm is also known as Double and Add.
+
+
+
+
+
+
+
+
+
+ Parameters:
+
+
+
+ P
+ (point )
+ –
+
+
the Point to multiplication
+
+
+
+ n
+ (Integer )
+ –
+
+
multiplicate n time P
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Returns:
+
+
+
+ Point
+ –
+
+
Return the result of the Scalar multiplication
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Groups/curve.py
+ 121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143 def scalar ( self , P , n ) -> Point :
+ """
+ This function compute a Scalar Multiplication of P, n time. This algorithm is also known as Double and Add.
+
+ Args:
+ P (point): the Point to multiplication
+ n (Integer): multiplicate n time P
+
+ Returns:
+ Return the result of the Scalar multiplication
+ """
+ binary = bin ( n )[ 2 :]
+ binary = binary [:: - 1 ] # We need to reverse the binary
+
+ nP = Point ( 0 , 0 )
+ Rtmp = P
+
+ for b in binary :
+ if b == '1' :
+ nP = self . add ( nP , Rtmp )
+ Rtmp = self . add ( Rtmp , Rtmp ) # Double P
+
+ return nP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/examples-rsa-keys/index.html b/site/example-rsa-keys/index.html
similarity index 87%
rename from site/examples-rsa-keys/index.html
rename to site/example-rsa-keys/index.html
index af1636d..3e520fd 100644
--- a/site/examples-rsa-keys/index.html
+++ b/site/example-rsa-keys/index.html
@@ -14,7 +14,7 @@
@@ -50,18 +50,27 @@
Group theory
+ Curves
+
Public Keys
+ Utils
+
Examples
@@ -116,7 +125,7 @@ print(f"Plaintext: {plaintext}")
@@ -139,7 +148,7 @@ print(f"Plaintext: {plaintext}")
- « Previous
+ « Previous
diff --git a/site/group-theory/index.html b/site/group-theory/index.html
index 98bd03c..a0ac51e 100644
--- a/site/group-theory/index.html
+++ b/site/group-theory/index.html
@@ -120,15 +120,24 @@
+ Curves
+
Public Keys
+ Utils
+
Examples
@@ -3015,7 +3024,7 @@ In Group Theory, an identity element is an element in the group which do not cha
@@ -3041,7 +3050,7 @@ In Group Theory, an identity element is an element in the group which do not cha
« Previous
- Next »
+ Next »
diff --git a/site/index.html b/site/index.html
index 87dfc67..ad14e96 100644
--- a/site/index.html
+++ b/site/index.html
@@ -50,15 +50,24 @@
Group theory
+ Curves
+
Public Keys
+ Utils
+
Examples
@@ -91,14 +100,20 @@
Low-Level Cryptographic
Public Keys:
+Utils
+
Examples:
@@ -144,5 +159,5 @@
diff --git a/site/installation/index.html b/site/installation/index.html
index 0af617d..30b6377 100644
--- a/site/installation/index.html
+++ b/site/installation/index.html
@@ -54,15 +54,24 @@
Group theory
+ Curves
+
Public Keys
+ Utils
+
Examples
diff --git a/site/introduction/index.html b/site/introduction/index.html
index 245b451..709a9af 100644
--- a/site/introduction/index.html
+++ b/site/introduction/index.html
@@ -52,15 +52,24 @@
Group theory
+ Curves
+
Public Keys
+ Utils
+
Examples
diff --git a/site/number-theory/index.html b/site/number-theory/index.html
index ea4c227..5a60e36 100644
--- a/site/number-theory/index.html
+++ b/site/number-theory/index.html
@@ -80,15 +80,24 @@
Group theory
+ Curves
+
Public Keys
+ Utils
+
Examples
diff --git a/site/objects.inv b/site/objects.inv
index 429a915..20fc800 100644
Binary files a/site/objects.inv and b/site/objects.inv differ
diff --git a/site/rsa/index.html b/site/rsa/index.html
index 4ac228f..4a88df3 100644
--- a/site/rsa/index.html
+++ b/site/rsa/index.html
@@ -50,6 +50,8 @@
Group theory
+ Curves
+
Public Keys
+ Utils
+
Examples
@@ -1041,8 +1050,8 @@ The key is a tuple of the key and the modulus n
@@ -1065,10 +1074,10 @@ The key is a tuple of the key and the modulus n
- « Previous
+ « Previous
- Next »
+ Next »
diff --git a/site/sitemap.xml.gz b/site/sitemap.xml.gz
index a7f3a5c..0ced834 100644
Binary files a/site/sitemap.xml.gz and b/site/sitemap.xml.gz differ
diff --git a/site/utils/index.html b/site/utils/index.html
new file mode 100644
index 0000000..bf4409d
--- /dev/null
+++ b/site/utils/index.html
@@ -0,0 +1,561 @@
+
+
+
+
+
+
+
+ Utils - CryptoTools documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CryptoTools documentation
+
+
+
+
+
+
+
+
CryptoTools provides several utils function wich can be used for cryptography purposes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This function perform an binary exponentiation, also known as Exponentiation squaring.
+A binary exponentiation is the process for computing an integer power of a number, such as a ** n.
+For doing that, the first step is to convert the exponent into a binary representation
+And for each 1 bit, we compute the exponent.
+
+
+
+
+
+
+
+
+
+ Parameters:
+
+
+
+ n
+ (Integer )
+ –
+
+
+
+ e
+ (Integer )
+ –
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Returns:
+
+
+
+ int
+ –
+
+
Return the result of the exponentation of n ** e
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Utils/utils.py
+ 35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62 def bin_expo ( n , e ) -> int :
+ """
+ This function perform an binary exponentiation, also known as Exponentiation squaring.
+ A binary exponentiation is the process for computing an integer power of a number, such as a ** n.
+ For doing that, the first step is to convert the exponent into a binary representation
+ And for each 1 bit, we compute the exponent.
+
+ Args:
+ n (Integer): it's the base
+ e (Integer): it's the exponent
+
+ Returns:
+ Return the result of the exponentation of n ** e
+
+ """
+ binary = bin ( e )[ 2 :] # Remove the prefix 0b
+
+ r = 1
+ exp = 1
+ # We need to reverse, and to start from the right to left
+ # Otherwise, we do on left to the right
+ # It's dirty, maybe we can find another way to do that
+ for b in binary [:: - 1 ]:
+ if b == '1' :
+ r *= n ** exp
+ print ( n ** exp , exp )
+ exp *= 2
+ return r
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This function compute the Extended Euclidean algorithm
+https://user.eng.umd.edu/~danadach/Cryptography_20/ExtEuclAlg.pdf
+https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
+
+
+
+
+
+
+
+
+
+ Parameters:
+
+
+
+ a
+ (Integer )
+ –
+
+
+
+ b
+ (Integer )
+ –
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Utils/utils.py
+ 18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33 def egcd ( a , b ):
+ """
+ This function compute the Extended Euclidean algorithm
+ https://user.eng.umd.edu/~danadach/Cryptography_20/ExtEuclAlg.pdf
+ https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
+
+ Args:
+ a (Integer): the number a
+ b (Integer): the number b
+ """
+ if a == 0 :
+ return b , 0 , 1
+ gcd , x1 , y1 = egcd ( b % a , a )
+ x = y1 - ( b // a ) * x1
+ y = x1
+ return gcd , x , y
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This function perform an exponentiation squaring, which compute an integer power of a number based on the following algorithm:
+ n ** e = {
+ 1 # if n is 0
+ (n ** (e / 2)) ** 2 # if n is even
+ ((n ** (e - 1 / 2)) ** 2) * n # if n is odd
+ }
+
+
+
+
+
+
+
+
+
+ Parameters:
+
+
+
+ n
+ (Integer )
+ –
+
+
n is the base of n ** e
+
+
+
+ e
+ (Integer )
+ –
+
+
+
+
+
+
+
+
+
+ Source code in Cryptotools/Utils/utils.py
+ 64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84 def exponent_squaring ( n , e ):
+ """
+ This function perform an exponentiation squaring, which compute an integer power of a number based on the following algorithm:
+ n ** e = {
+ 1 # if n is 0
+ (n ** (e / 2)) ** 2 # if n is even
+ ((n ** (e - 1 / 2)) ** 2) * n # if n is odd
+ }
+
+ Args:
+ n (Integer): n is the base of n ** e
+ e (Integer): e is the exponent
+ """
+ if e < 0 :
+ return exponent_squaring ( 1 / n , - e )
+ elif e == 0 :
+ return 1
+ elif e % 2 == 1 : # n is odd
+ return exponent_squaring ( n * n , ( e - 1 ) / 2 ) * n
+ elif e % 2 == 0 : # n is even
+ return exponent_squaring ( n * n , e / 2 )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This function calculate the GCD (Greatest Common Divisor of the number a of b
+Args:
+ a (Integer): the number a
+ b (integer): the number b
+
+
+
+ Return
+ the GCD
+
+
+
+ Source code in Cryptotools/Utils/utils.py
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16 def gcd ( a , b ):
+ """
+ This function calculate the GCD (Greatest Common Divisor of the number a of b
+ Args:
+ a (Integer): the number a
+ b (integer): the number b
+
+ Return:
+ the GCD
+ """
+
+ if b == 0 :
+ return a
+ return gcd ( b , a % b )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+