Kickstart fk20

This commit is contained in:
danielsanchezq 2024-06-07 08:22:03 +02:00
parent c9b2c7c5c5
commit d7bafffbdc
6 changed files with 98 additions and 1 deletions

37
da/kzg_rs/fft.py Normal file
View File

@ -0,0 +1,37 @@
def _simple_ft(vals, modulus, roots_of_unity):
L = len(roots_of_unity)
o = []
for i in range(L):
last = 0
for j in range(L):
last += vals[j] * roots_of_unity[(i*j)%L]
o.append(last % modulus)
return o
def _fft(vals, modulus, roots_of_unity):
if len(vals) == 4:
return _simple_ft(vals, modulus, roots_of_unity)
if len(vals) == 1:
return vals
L = _fft(vals[::2], modulus, roots_of_unity[::2])
R = _fft(vals[1::2], modulus, roots_of_unity[::2])
o = [0 for _ in vals]
for i, (x, y) in enumerate(zip(L, R)):
y_times_root = (y*roots_of_unity[i]) % modulus
o[i] = (x+y_times_root) % modulus
o[i+len(L)] = (x-y_times_root+modulus) % modulus
return o
def fft(vals, modulus, root_of_unity):
assert len(vals) == len(root_of_unity)
return _fft(vals, modulus, root_of_unity)
def ifft(vals, modulus, root_of_unity):
assert len(vals) == len(root_of_unity)
# modular inverse
invlen = pow(len(vals), -1, modulus)
return [(x * invlen) % modulus for x in _fft(vals, modulus, list(reversed(root_of_unity)))]

36
da/kzg_rs/fk20.py Normal file
View File

@ -0,0 +1,36 @@
from typing import List, Sequence
from eth2spec.deneb.mainnet import KZGProof as Proof
from da.kzg_rs.common import G1, BLS_MODULUS
from da.kzg_rs.fft import fft
from da.kzg_rs.poly import Polynomial
from da.kzg_rs.utils import is_power_of_two
def toeplitz1(global_parameters: List[G1], roots_of_unity: Sequence[int], polynomial_degree: int) -> List[G1]:
"""
This part can be precomputed for different global_parameters lengths depending on polynomial degree of powers of two.
:param global_parameters:
:param roots_of_unity:
:param polynomial_degree:
:return:
"""
assert len(roots_of_unity) >= 2 * polynomial_degree
assert len(global_parameters) >= polynomial_degree
global_parameters = global_parameters[:polynomial_degree]
# algorithm only works on powers of 2 for dft computations
assert is_power_of_two(len(global_parameters))
roots_of_unity = roots_of_unity[:2*polynomial_degree]
vector_x_extended = global_parameters + [G1(0) for _ in range(len(global_parameters))]
vector_x_extended_fft = fft(vector_x_extended, BLS_MODULUS, roots_of_unity)
return vector_x_extended_fft
def fk20_generate_proofs(polynomial: Polynomial) -> List[Proof]:
# 1 - Build toeplitz matrix for h values
# 1.1 y = dft([s^d-1, s^d-2, ..., s, 1, *[0 for _ in len(polynomial)]])
# 1.2 z = dft([*[0 for _ in len(polynomial)], f1, f2, ..., fd])
# 1.3 u = y * v * roots_of_unity(len(polynomial)*2)
# 2 - Build circulant matrix with the polynomial coefficients (reversed N..n, and padded)
# 3 - Perform fft and nub the tail half as it is padding
pass

13
da/kzg_rs/test_fft.py Normal file
View File

@ -0,0 +1,13 @@
from unittest import TestCase
from da.kzg_rs.common import BLS_MODULUS
from fft import fft, ifft
from eth2spec.eip7594.mainnet import fft_field, BLSFieldElement
class TestFFT(TestCase):
def test_fft_ifft(self):
roots_of_unity = [pow(2, i, BLS_MODULUS) for i in range(8)]
vals = list(BLSFieldElement(x) for x in range(8))
vals_fft = fft_field(vals, roots_of_unity)
self.assertEqual(vals, fft_field(vals_fft, roots_of_unity, inv=True))

5
da/kzg_rs/test_fk20.py Normal file
View File

@ -0,0 +1,5 @@
from unittest import TestCase
import random
class TestFK20(TestCase):
def test_toeplizt1(self):

6
da/kzg_rs/utils.py Normal file
View File

@ -0,0 +1,6 @@
POWERS_OF_2 = {2**i for i in range(1, 8)}
def is_power_of_two(n) -> bool:
return n in POWERS_OF_2

View File

@ -1,4 +1,4 @@
blspy==2.0.2
blspy==2.0.3
cffi==1.16.0
cryptography==41.0.7
numpy==1.26.3