-
-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
publishBlockWithBlobs implementation. A lot more moon math scaffoldin…
…g that will be removed.
- Loading branch information
Showing
8 changed files
with
320 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
packages/validator/src/util/blobs/bitReversalPermutation.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/polynomial-commitments.md#bit-reversal-permutation | ||
|
||
import {FIELD_ELEMENTS_PER_BLOB} from "@lodestar/params"; | ||
|
||
/* | ||
All polynomials (which are always given in Lagrange form) should be interpreted as being in bit-reversal permutation. In practice, clients can implement this by storing the lists KZG_SETUP_LAGRANGE and ROOTS_OF_UNITY in bit-reversal permutation, so these functions only have to be called once at startup. | ||
*/ | ||
|
||
// def is_power_of_two(value: int) -> bool: | ||
// """ | ||
// Check if ``value`` is a power of two integer. | ||
// """ | ||
// return (value > 0) and (value & (value - 1) == 0) | ||
function isPowerOfTwo(value: number): boolean { | ||
return value > 0 && !(value & (value - 1)); | ||
} | ||
|
||
// def reverse_bits(n: int, order: int) -> int: | ||
// """ | ||
// Reverse the bit order of an integer n | ||
// """ | ||
// assert is_power_of_two(order) | ||
// # Convert n to binary with the same number of bits as "order" - 1, then reverse its bit order | ||
// return int(('{:0' + str(order.bit_length() - 1) + 'b}').format(n)[::-1], 2) | ||
function reverseBits(n: number, _order: number): number { | ||
// TODO: EIP-4844 implement this | ||
// Prysm does: | ||
// bits.Reverse64(uint64(i)) >> (65 - bits.Len64(params.FieldElementsPerBlob)) | ||
return n; | ||
} | ||
|
||
// def bit_reversal_permutation(sequence: Sequence[T]) -> Sequence[T]: | ||
// """ | ||
// Return a copy with bit-reversed permutation. The permutation is an involution (inverts itself). | ||
|
||
// The input and output are a sequence of generic type ``T`` objects. | ||
// """ | ||
// return [sequence[reverse_bits(i, len(sequence))] for i in range(len(sequence))] | ||
export function bitReversalPermutation<T>(sequence: T[]): T[] { | ||
if (!isPowerOfTwo(FIELD_ELEMENTS_PER_BLOB)) { | ||
throw new Error( | ||
`FIELD_ELEMENTS_PER_BLOB must be a power of two. The value FIELD_ELEMENTS_PER_BLOB: ${FIELD_ELEMENTS_PER_BLOB} is not.` | ||
); | ||
} | ||
|
||
const order = sequence.length; | ||
const permutedSequence: T[] = []; | ||
|
||
sequence.forEach((_, index: number) => { | ||
permutedSequence[index] = sequence[reverseBits(index, order)]; | ||
}); | ||
|
||
return permutedSequence; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/polynomial-commitments.md#bls12-381-helpers | ||
|
||
import {KZGCommitment, BLSFieldElement} from "@lodestar/types/eip4844"; | ||
import * as ssz from "@lodestar/types/eip4844/sszTypes"; | ||
import {Bytes32} from "@lodestar/types"; | ||
import {bytesToBigInt, intToBytes, bigIntToBytes} from "@lodestar/utils"; | ||
import {BLS_MODULUS} from "./constants.js"; | ||
|
||
// def bytes_to_bls_field(b: Bytes32) -> BLSFieldElement: | ||
// """ | ||
// Convert bytes to a BLS field scalar. The output is not uniform over the BLS field. | ||
// """ | ||
// return int.from_bytes(b, "little") % BLS_MODULUS | ||
export function bytesToBLSField(b: Bytes32): BLSFieldElement { | ||
return intToBytes(bytesToBigInt(b) % BLS_MODULUS, 32); | ||
} | ||
|
||
// def bls_modular_inverse(x: BLSFieldElement) -> BLSFieldElement: | ||
// """ | ||
// Compute the modular inverse of x | ||
// i.e. return y such that x * y % BLS_MODULUS == 1 and return 0 for x == 0 | ||
// """ | ||
// return pow(x, -1, BLS_MODULUS) if x != 0 else 0 | ||
export function blsModularInverse(x: BLSFieldElement): BLSFieldElement { | ||
// Maybe BLSFieldElement should actually just be "number"? | ||
const value = bytesToBigInt(x); | ||
if (value !== BigInt(0)) { | ||
return intToBytes(value ** BigInt(-1) % BLS_MODULUS, 32); | ||
} | ||
return intToBytes(0, 32); | ||
} | ||
|
||
// def div(x: BLSFieldElement, y: BLSFieldElement) -> BLSFieldElement: | ||
// """Divide two field elements: `x` by `y`""" | ||
// return (int(x) * int(bls_modular_inverse(y))) % BLS_MODULUS | ||
export function div(x: BLSFieldElement, y: BLSFieldElement): BLSFieldElement { | ||
const product = bytesToBigInt(x) * bytesToBigInt(blsModularInverse(y)); | ||
return bigIntToBytes(product % BLS_MODULUS, 32); | ||
} | ||
|
||
// def g1_lincomb(points: Sequence[KZGCommitment], scalars: Sequence[BLSFieldElement]) -> KZGCommitment: | ||
// """ | ||
// BLS multiscalar multiplication. This function can be optimized using Pippenger's algorithm and variants. | ||
// """ | ||
// assert len(points) == len(scalars) | ||
// result = bls.Z1 | ||
// for x, a in zip(points, scalars): | ||
// result = bls.add(result, bls.multiply(bls.bytes48_to_G1(x), a)) | ||
// return KZGCommitment(bls.G1_to_bytes48(result)) | ||
export function g1Lincomb(points: KZGCommitment[], scalars: BLSFieldElement[]): KZGCommitment { | ||
if (points.length !== scalars.length) { | ||
throw new Error("BLS multiscalar multiplication requires points length to match scalars length."); | ||
} | ||
|
||
return ssz.KZGCommitment.defaultValue(); | ||
} | ||
|
||
// def vector_lincomb(vectors: Sequence[Sequence[BLSFieldElement]], | ||
// scalars: Sequence[BLSFieldElement]) -> Sequence[BLSFieldElement]: | ||
// """ | ||
// Given a list of ``vectors``, interpret it as a 2D matrix and compute the linear combination | ||
// of each column with `scalars`: return the resulting vector. | ||
// """ | ||
// result = [0] * len(vectors[0]) | ||
// for v, s in zip(vectors, scalars): | ||
// for i, x in enumerate(v): | ||
// result[i] = (result[i] + int(s) * int(x)) % BLS_MODULUS | ||
// return [BLSFieldElement(x) for x in result] | ||
export function vectorLincomb(_vectors: BLSFieldElement[][], _scalars: BLSFieldElement[]): BLSFieldElement[] { | ||
return []; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Constants | ||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/polynomial-commitments.md#constants | ||
|
||
import {KZGCommitment} from "@lodestar/types/eip4844"; | ||
import {bitReversalPermutation} from "./bitReversalPermutation.js"; | ||
|
||
// Scalar field modulus of BLS12-381 | ||
export const BLS_MODULUS = BigInt("52435875175126190479447740508185965837690552500527637822603658699938581184513"); | ||
|
||
// Roots of unity of order FIELD_ELEMENTS_PER_BLOB over the BLS12-381 field | ||
export const ROOTS_OF_UNITY: KZGCommitment[] = []; | ||
export const KZG_SETUP_LAGRANGE = bitReversalPermutation(ROOTS_OF_UNITY); |
Oops, something went wrong.