Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

BN128 tests do not pass on Python 3.6.6 #11

Description

@alexpArtos

When I run the test_bn128.py file, the tests fail silently: they don't run to the end.

Expected output:

>>> import tests.test_bn128
Starting bn128 tests
FQ works fine
FQ2 works fine
FQ12 works fine
G1 works fine
G2 works fine
G12 works fine
Starting pairing tests
Pairing check against negative in G1 passed
Pairing check against negative in G2 passed
Pairing output has correct order
Pairing bilinearity in G1 passed
Pairing is non-degenerate
Pairing bilinearity in G2 passed
Composite check passed
Total time for pairings: 35.553
FQ works fine
FQ2 works fine
FQ12 works fine
G1 works fine
G2 works fine
G12 works fine
Starting pairing tests
Pairing check against negative in G1 passed
Pairing check against negative in G2 passed
Pairing output has correct order
Pairing bilinearity in G1 passed
Pairing is non-degenerate
Pairing bilinearity in G2 passed
Composite check passed
Total time for pairings: 2.081

Real output:

>>> import tests.test_bn128
Starting bn128 tests
FQ works fine
FQ2 works fine
FQ12 works fine
G1 works fine
G2 works fine
G12 works fine
Starting pairing tests

I found that the problem is in the __pow__ functions which override the ** operator. The tests use realistically big exponents, and the power function in the non optimized bn128 curve is implemented recursively. This means it needs to go down almost 2800 times. But the first test stops in level 1924.

I found a way to fix this is to avoid recursion on the ** operator of the FQP class, by calling a function that does the whole recursion for you:

    def __pow__(self, other):
        return self.pow(other)

    def pow(self, other):
        if other == 0:
            return self.__class__([1] + [0] * (self.degree - 1))
        elif other == 1:
            return self.__class__(self.coeffs)
        elif other % 2 == 0:
            base = self * self
            power = other // 2
            return (base).pow(power)
        else:
            base = self * self
            power = int(other // 2)
            return ((base).pow(power)) * self

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions