constantine/sage/ethereum_kzg.sage
Mamy Ratsimbazafy f57d071f11
Ethereum KZG polynomial commitments / EIP-4844 (part 1) (#239)
* common error model for serialization of BLS signatures and KZG objects

* [KZG] add Ethereum's test vectors [skip ci]

* dump progress on KZG

* Stash: trusted setup generator

* implement cache optimized bit-reversal-permutation

* Add generator for the Ethereum test trusted setups

* implement naive deserialization for the trusted setup interchange format

* implement verify_kzg_proof

* Add test skeleton of verify KZG proof

* rebase import fixes
2023-08-13 15:08:04 +02:00

109 lines
3.2 KiB
Python

#!/usr/bin/sage
# vim: syntax=python
# vim: set ts=2 sw=2 et:
# Constantine
# Copyright (c) 2018-2019 Status Research & Development GmbH
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
# ############################################################
#
# Pairing constants
#
# ############################################################
# Imports
# ---------------------------------------------------------
import os
import inspect, textwrap
# Working directory
# ---------------------------------------------------------
os.chdir(os.path.dirname(__file__))
# Sage imports
# ---------------------------------------------------------
# Accelerate arithmetic by accepting probabilistic proofs
from sage.structure.proof.all import arithmetic
arithmetic(False)
load('curves.sage')
# Roots of unity
# ---------------------------------------------------------
def gen_pow2_roots_of_unity(field, num_powers):
"""
Generate the 2^i'th roots of unity
with i in [0, num_powers)
"""
# Find a primitive root of the finite field of modulus q
# i.e. root^k != 1 for all k < q-1 so powers of root generate the field.
# https://crypto.stanford.edu/pbc/notes/numbertheory/gen.html
#
# Usage, see ω usagefor polynomials in evaluation form:
# https://dankradfeist.de/ethereum/2021/06/18/pcs-multiproofs.html
primitive_root = field.multiplicative_generator()
assert primitive_root == 7, (
'The ref implementation c-kzg-4844 uses 7.'
+ ' Any primitive root is correct but the order of coefficients '
+ ' won\'t be the same which makes debugging harder.'
)
return [primitive_root^((field.characteristic()-1)//(1 << i)) for i in range(num_powers)]
# Dump
# ---------------------------------------------------------
def dumpConst(name, inner):
result = f'const {name}* = (\n'
result += inner
result += ')\n'
return result
def dumpRoots(vec):
result = f' # primitive_root⁽ᵐᵒᵈᵘˡᵘˢ⁻¹⁾/⁽²^ⁱ⁾ for i in [0, {len(vec)})\n'
lastRow = len(vec) - 1
for rowID, val in enumerate(vec):
result += ' '
result += f'BigInt[{max(1, int(val).bit_length())}].fromHex"0x{Integer(int(val)).hex()}"'
result += ',\n' if rowID != lastRow else '\n'
return result
# CLI
# ---------------------------------------------------------
if __name__ == "__main__":
with open(f'ethereum_kzg_constants.nim', 'w') as f:
f.write(copyright())
f.write('\n\n')
f.write(inspect.cleandoc(f"""
import
../config/curves,
../io/io_bigints
# Roots of unity
# ------------------------------------------------------------
"""))
f.write('\n\n')
r = Curves['BLS12_381']['field']['order']
Fr = GF(r)
f.write(dumpConst(
'ctt_eth_kzg_bls12_381_fr_pow2_roots_of_unity',
dumpRoots(gen_pow2_roots_of_unity(Fr, 32))
))
f.write('\n\n')