# Elliptic Curves

## Points

## `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

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

## `Curve`

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

### `add(P, Q)`

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)

### `find_reverse(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

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

### `scalar(P, n)`

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

« Previous Next »