Files
mev-beta/vendor/github.com/crate-crypto/go-eth-kzg/api.go

150 lines
5.9 KiB
Go

package goethkzg
import (
"encoding/json"
"github.com/crate-crypto/go-eth-kzg/internal/domain"
"github.com/crate-crypto/go-eth-kzg/internal/erasure_code"
"github.com/crate-crypto/go-eth-kzg/internal/kzg"
kzgmulti "github.com/crate-crypto/go-eth-kzg/internal/kzg_multi"
"github.com/crate-crypto/go-eth-kzg/internal/kzg_multi/fk20"
)
// Context holds the necessary configuration needed to create and verify proofs.
//
// Note: We could marshall this object so that clients won't need to process the SRS each time. The time to process is
// about 2-5 seconds.
type Context struct {
domain *domain.Domain
domainExtended *domain.Domain
commitKeyLagrange *kzg.CommitKey
commitKeyMonomial *kzg.CommitKey
openKey4844 *kzg.OpeningKey
openKey7594 *kzgmulti.OpeningKey
fk20 *fk20.FK20
dataRecovery *erasure_code.DataRecovery
}
// BlsModulus is the bytes representation of the bls12-381 scalar field modulus.
//
// It matches [BLS_MODULUS] in the spec.
//
// [BLS_MODULUS]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#constants
var BlsModulus = [32]byte{
0x73, 0xed, 0xa7, 0x53, 0x29, 0x9d, 0x7d, 0x48,
0x33, 0x39, 0xd8, 0x08, 0x09, 0xa1, 0xd8, 0x05,
0x53, 0xbd, 0xa4, 0x02, 0xff, 0xfe, 0x5b, 0xfe,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
}
// PointAtInfinity represents the serialized form of the point at infinity on the G1 group.
//
// It matches [G1_POINT_AT_INFINITY] in the spec.
//
// [G1_POINT_AT_INFINITY]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#constants
var PointAtInfinity = [48]byte{0xc0}
// NewContext4096Secure creates a new context object which will hold the state needed for one to use the KZG
// methods. "4096" denotes that we will only be able to commit to polynomials with at most 4096 evaluations. "Secure"
// denotes that this method is using a trusted setup file that was generated in an official
// ceremony. In particular, the trusted file being used was taken from the ethereum KZG ceremony.
func NewContext4096Secure() (*Context, error) {
if ScalarsPerBlob != 4096 {
// This is a library bug and so we panic.
panic("this method is named `NewContext4096Secure` we expect SCALARS_PER_BLOB to be 4096")
}
parsedSetup := JSONTrustedSetup{}
err := json.Unmarshal([]byte(testKzgSetupStr), &parsedSetup)
if err != nil {
return nil, err
}
if ScalarsPerBlob != len(parsedSetup.SetupG1Lagrange) {
// This is a library method and so we panic
panic("this method is named `NewContext4096Secure` we expect the number of G1 elements in the trusted setup to be 4096")
}
return NewContext4096(&parsedSetup)
}
// NewContext4096 creates a new context object which will hold the state needed for one to use the EIP-4844 methods. The
// 4096 represents the fact that without extra changes to the code, this context will only handle polynomials with 4096
// evaluations (degree 4095).
//
// Note: The G2 points do not have a fixed size. Technically, we could specify it to be 2, as this is the number of G2
// points that are required for KZG. However, the trusted setup in Ethereum has 65 since they want to use it for a
// future protocol: [Full Danksharding]. For this reason, we do not apply a fixed size, allowing the user to pass, say,
// 2 or 65.
//
// To initialize one must pass the parameters generated after the trusted setup, plus the lagrange version of the G1
// points. This function assumes that the G1 and G2 points are in order:
//
// - G1points = {G, alpha * G, alpha^2 * G, ..., alpha^n * G}
// - G2points = {H, alpha * H, alpha^2 * H, ..., alpha^n * H}
// - Lagrange G1Points = {L_0(alpha^0) * G, L_1(alpha) * G, L_2(alpha^2) * G, ..., L_n(alpha^n) * G}
//
// [Full Danksharding]: https://notes.ethereum.org/@dankrad/new_sharding
func NewContext4096(trustedSetup *JSONTrustedSetup) (*Context, error) {
// This should not happen for the ETH protocol
// However since it's a public method, we add the check.
if len(trustedSetup.SetupG2) < 2 {
return nil, kzg.ErrMinSRSSize
}
// Parse the trusted setup from hex strings to G1 and G2 points
genG1, setupMonomialG1Points, setupLagrangeG1Points, setupG2Points := parseTrustedSetup(trustedSetup)
// Get the generator points and the degree-1 element for G2 points
// The generators are the degree-0 elements in the trusted setup
//
// This will never panic as we checked the minimum SRS size is >= 2
// and `ScalarsPerBlob` is 4096
genG2 := setupG2Points[0]
alphaGenG2 := setupG2Points[1]
commitKeyLagrange := kzg.CommitKey{
G1: setupLagrangeG1Points,
}
commitKeyMonomial := kzg.CommitKey{
G1: setupMonomialG1Points,
}
if len(setupG2Points) < scalarsPerCell {
panic("The number of G2 points in the trusted setup is less than the number of scalars per blob")
}
openingKey4844 := kzg.OpeningKey{
GenG1: genG1,
GenG2: genG2,
AlphaG2: alphaGenG2,
}
openingKey7594 := kzgmulti.NewOpeningKey(setupMonomialG1Points[:len(setupG2Points)], setupG2Points, ScalarsPerBlob, scalarsPerExtBlob, scalarsPerCell)
domainBlobLen := domain.NewDomain(ScalarsPerBlob)
// Bit-Reverse the roots and the trusted setup according to the specs
// The bit reversal is not needed for simple KZG however it was
// implemented to make the step for full dank-sharding easier.
commitKeyLagrange.ReversePoints()
domainBlobLen.ReverseRoots()
domainExtended := domain.NewDomain(scalarsPerExtBlob)
domainExtended.ReverseRoots()
fk20 := fk20.NewFK20(commitKeyMonomial.G1, scalarsPerExtBlob, scalarsPerCell)
return &Context{
domain: domainBlobLen,
domainExtended: domainExtended,
commitKeyLagrange: &commitKeyLagrange,
commitKeyMonomial: &commitKeyMonomial,
openKey4844: &openingKey4844,
openKey7594: openingKey7594,
fk20: &fk20,
dataRecovery: erasure_code.NewDataRecovery(scalarsPerCell, ScalarsPerBlob, expansionFactor),
}, nil
}