0

I am trying to implement elliptic curve point with scalar multiplication in Python and have the issue that in some cases I get incorrect results and am struggling to figure out what could be wrong.

Here is the function performing the calculation:

def __mul__(self, other):
    """
    Scalar multiplication of a point with a integer
    The point gets added to itself other times
    This can be efficiently computed using binary
    representation of the scalar

    :param other: int number to multiply the point with
    :return: Point point after applying the multiplication
    """
    if other < 1 or other > self.order():
        raise Exception("Scalar for point mult is out of range")

    # Convert into binary representation
    scalar_bin = str(bin(other))[2:]

    new_point = self.curve().g()
    # Iterate through every bit of the scalar
    # double the current point and if it is a 1 bit
    # we add the generator point
    for i in range(1, len(scalar_bin)):
        new_point = new_point + new_point
        if scalar_bin[i] == "1":
            new_point = new_point + self.curve().g()
    return new_point

I have tested this for mutliple values and sometimes receive correct and sometimes incorrect results. Here are some examples on the secp256k1 curve:

Correct case:

Point: 
x: 55066263022277343669578718895168534326250603453777594175500187360389116729240
y: 32670510020758816978083085130507043184471273380659243275938904335757337482424

Scalar:
24917563387128992525586541072555299775466638713533702470001729610242625242518

Result:
x: 30761640594611050927920473896980176618852175787129035469672454552631110981601
y: 71589730992642335000963807008595655528549796860255114743222783656832671116115

Incorrect case:

Point:
x: 55763821349469695143251444157857527262741225298806100934200365505846997750729
y: 108311437762381308673474438597429390041179265557837286648496266777408263200496

Scalar:
14153923515125836933174734651094672686604752309351060890449588899992278900437

Result:
x: 33276244942913720410563273329803338573012270278748134958920446992664092974057
y: 38066195899997010281080208319525128360573241938488491930954474962286948555539
Jakob Abfalter
  • 4,980
  • 17
  • 54
  • 94

1 Answers1

0

So I figured out the issue and it is hard for anyone to see as the math seems to be correct but instead there was a programming mistake I did which is not easily seen if you look at the function out of context.

The code presented will do a scalar multiplication of the generator point of the curve all the time, but not of the point that self actually refers to. Self is an instance of a point but in the outlined code never directly referenced, instead the curve generator point is multiplied.

new_point = self.curve().g()

should be replaced by

new_point = self

and

new_point = new_point + self.curve().g()

by

new_point = new_point + self

It is still a bit unclear to me how this code could have produced correct examples in some cases.

Jakob Abfalter
  • 4,980
  • 17
  • 54
  • 94