49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
|
import random
|
||
|
from typing import Tuple, Sequence, Generator
|
||
|
from eth2spec.utils import bls
|
||
|
from itertools import accumulate, repeat
|
||
|
|
||
|
|
||
|
def __linear_combination(points, coeffs, zero=bls.Z1()):
|
||
|
o = zero
|
||
|
for point, coeff in zip(points, coeffs):
|
||
|
o = bls.add(o, bls.multiply(point, coeff))
|
||
|
return o
|
||
|
|
||
|
|
||
|
# Verifies the integrity of a setup
|
||
|
def verify_setup(setup) -> bool:
|
||
|
g1_setup, g2_setup = setup
|
||
|
g1_random_coefficients = [random.randrange(2**40) for _ in range(len(g1_setup) - 1)]
|
||
|
g1_lower = __linear_combination(g1_setup[:-1], g1_random_coefficients, bls.Z1())
|
||
|
g1_upper = __linear_combination(g1_setup[1:], g1_random_coefficients, bls.Z1())
|
||
|
g2_random_coefficients = [random.randrange(2**40) for _ in range(len(g2_setup) - 1)]
|
||
|
g2_lower = __linear_combination(g2_setup[:-1], g2_random_coefficients, bls.Z2())
|
||
|
g2_upper = __linear_combination(g2_setup[1:], g2_random_coefficients, bls.Z2())
|
||
|
return (
|
||
|
g1_setup[0] == bls.G1() and
|
||
|
g2_setup[0] == bls.G2() and
|
||
|
bls.pairing_check([[g1_upper, bls.neg(g2_lower)], [g1_lower, g2_upper]])
|
||
|
)
|
||
|
|
||
|
|
||
|
def generate_one_sided_setup(length, secret, generator=bls.G1()):
|
||
|
def __take(gen):
|
||
|
return (next(gen) for _ in range(length))
|
||
|
|
||
|
secrets = repeat(secret)
|
||
|
|
||
|
return __take(accumulate(secrets, bls.multiply, initial=generator))
|
||
|
|
||
|
|
||
|
# Generate a trusted setup with the given secret
|
||
|
def generate_setup(
|
||
|
g1_length,
|
||
|
g2_length,
|
||
|
secret
|
||
|
) -> Tuple[Generator[bls.G1, None, None], Generator[bls.G2, None, None]]:
|
||
|
return (
|
||
|
generate_one_sided_setup(g1_length, secret, bls.G1()),
|
||
|
generate_one_sided_setup(g2_length, secret, bls.G2()),
|
||
|
)
|