nomos-specs/da/kzg_rs/trusted_setup.py

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()),
)