From becee4d92a19fa1efd5a5501b282ad13183115a6 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Wed, 22 Mar 2023 22:46:03 +0000 Subject: [PATCH 1/3] add kzg file -- This will now compute the ctx in an init method --- crypto/kzg/kzg.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 crypto/kzg/kzg.go diff --git a/crypto/kzg/kzg.go b/crypto/kzg/kzg.go new file mode 100644 index 000000000000..8cd6146754b8 --- /dev/null +++ b/crypto/kzg/kzg.go @@ -0,0 +1,101 @@ +package kzg + +import ( + "crypto/sha256" + "errors" + "fmt" + "math/big" + + "github.com/crate-crypto/go-proto-danksharding-crypto/api" + "github.com/crate-crypto/go-proto-danksharding-crypto/serialization" +) + +const ( + BlobCommitmentVersionKZG uint8 = 0x01 + FieldElementsPerBlob int = 4096 +) + +type VersionedHash [32]byte +type Root [32]byte +type Slot uint64 + +type BlobsSidecar struct { + BeaconBlockRoot Root + BeaconBlockSlot Slot + Blobs []serialization.Blob + Proofs []serialization.KZGProof +} + +const ( + BlobTxType = 5 + PrecompileInputLength = 192 + BlobVersionedHashesOffset = 258 // position of blob_versioned_hashes offset in a serialized blob tx, see TxPeekBlobVersionedHashes +) + +var ( + errInvalidInputLength = errors.New("invalid input length") +) + +// The value that gets returned when the `verify_kzg_proof“ precompile is called +var precompileReturnValue [64]byte + +// The context object stores all of the necessary configurations +// to allow one to create and verify blob proofs +var CryptoCtx api.Context + +func init() { + // Initialize context to match the configurations that the + // specs are using. + ctx, err := api.NewContext4096Insecure1337() + if err != nil { + panic(fmt.Sprintf("could not create context, err : %v", err)) + } + CryptoCtx = *ctx + // Initialize the precompile return value + new(big.Int).SetUint64(serialization.ScalarsPerBlob).FillBytes(precompileReturnValue[:32]) + copy(precompileReturnValue[32:], api.MODULUS[:]) +} + +// PointEvaluationPrecompile implements point_evaluation_precompile from EIP-4844 +func PointEvaluationPrecompile(input []byte) ([]byte, error) { + if len(input) != PrecompileInputLength { + return nil, errInvalidInputLength + } + // versioned hash: first 32 bytes + var versionedHash [32]byte + copy(versionedHash[:], input[:32]) + + var x, y [32]byte + // Evaluation point: next 32 bytes + copy(x[:], input[32:64]) + // Expected output: next 32 bytes + copy(y[:], input[64:96]) + + // input kzg point: next 48 bytes + var dataKZG [48]byte + copy(dataKZG[:], input[96:144]) + if KZGToVersionedHash(serialization.KZGCommitment(dataKZG)) != VersionedHash(versionedHash) { + return nil, errors.New("mismatched versioned hash") + } + + // Quotient kzg: next 48 bytes + var quotientKZG [48]byte + copy(quotientKZG[:], input[144:PrecompileInputLength]) + + err := CryptoCtx.VerifyKZGProof(dataKZG, quotientKZG, x, y) + if err != nil { + return nil, fmt.Errorf("verify_kzg_proof error: %v", err) + } + + result := precompileReturnValue // copy the value + + return result[:], nil +} + +// KZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844 +func KZGToVersionedHash(kzg serialization.KZGCommitment) VersionedHash { + h := sha256.Sum256(kzg[:]) + h[0] = BlobCommitmentVersionKZG + + return VersionedHash(h) +} From 50010e3be20979324c7c08867e7174b36b272a8f Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Wed, 22 Mar 2023 22:46:14 +0000 Subject: [PATCH 2/3] modify files to use the new kzg file --- core/types/data_blob.go | 12 ++++++------ core/vm/contracts.go | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/types/data_blob.go b/core/types/data_blob.go index bf58ea9ee52d..58bb5e83b390 100644 --- a/core/types/data_blob.go +++ b/core/types/data_blob.go @@ -6,10 +6,10 @@ import ( "fmt" "io" - "github.com/crate-crypto/go-proto-danksharding-crypto/eth" api "github.com/crate-crypto/go-proto-danksharding-crypto/serialization" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto/kzg" "github.com/ethereum/go-ethereum/params" "github.com/protolambda/ztyp/codec" @@ -51,7 +51,7 @@ func (p *KZGCommitment) UnmarshalText(text []byte) error { } func (c KZGCommitment) ComputeVersionedHash() common.Hash { - return common.Hash(eth.KZGToVersionedHash(api.KZGCommitment(c))) + return common.Hash(kzg.KZGToVersionedHash(api.KZGCommitment(c))) } // Compressed BLS12-381 G1 element @@ -266,18 +266,18 @@ func (blobs Blobs) ComputeCommitmentsAndProofs() (commitments []KZGCommitment, v versionedHashes = make([]common.Hash, len(blobs)) for i, blob := range blobs { - commitment, err := eth.CryptoCtx.BlobToKZGCommitment(blob) + commitment, err := kzg.CryptoCtx.BlobToKZGCommitment(blob) if err != nil { return nil, nil, nil, fmt.Errorf("could not convert blob to commitment: %v", err) } - proof, err := eth.CryptoCtx.ComputeBlobKZGProof(blob, commitment) + proof, err := kzg.CryptoCtx.ComputeBlobKZGProof(blob, commitment) if err != nil { return nil, nil, nil, fmt.Errorf("could not compute proof for blob: %v", err) } commitments[i] = KZGCommitment(commitment) proofs[i] = KZGProof(proof) - versionedHashes[i] = common.Hash(eth.KZGToVersionedHash(commitment)) + versionedHashes[i] = common.Hash(kzg.KZGToVersionedHash(commitment)) } return commitments, versionedHashes, proofs, nil @@ -357,7 +357,7 @@ func (b *BlobTxWrapData) validateBlobTransactionWrapper(inner TxData) error { if l1 > params.MaxBlobsPerBlock { return fmt.Errorf("number of blobs exceeds max: %v", l1) } - err := eth.CryptoCtx.VerifyBlobKZGProofBatch(toBlobs(b.Blobs), toProofs(b.Proofs), toComms(b.BlobKzgs)) + err := kzg.CryptoCtx.VerifyBlobKZGProofBatch(toBlobs(b.Blobs), toProofs(b.Proofs), toComms(b.BlobKzgs)) if err != nil { return fmt.Errorf("error during proof verification: %v", err) } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index a5ea25d57fdf..e45ede94cb19 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -22,13 +22,13 @@ import ( "errors" "math/big" - "github.com/crate-crypto/go-proto-danksharding-crypto/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/bls12381" "github.com/ethereum/go-ethereum/crypto/bn256" + "github.com/ethereum/go-ethereum/crypto/kzg" "github.com/ethereum/go-ethereum/params" big2 "github.com/holiman/big" "golang.org/x/crypto/ripemd160" @@ -1080,5 +1080,5 @@ func (c *pointEvaluation) RequiredGas(input []byte) uint64 { } func (c *pointEvaluation) Run(input []byte) ([]byte, error) { - return eth.PointEvaluationPrecompile(input) + return kzg.PointEvaluationPrecompile(input) } From 23b9a14869aa98ec2663bcf107c144c4515d6e3b Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Wed, 22 Mar 2023 22:55:53 +0000 Subject: [PATCH 3/3] remove package rename since serialization is a distinct package from api now --- core/types/data_blob.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/core/types/data_blob.go b/core/types/data_blob.go index ac4d68495665..ca943b052974 100644 --- a/core/types/data_blob.go +++ b/core/types/data_blob.go @@ -6,7 +6,7 @@ import ( "fmt" "io" - api "github.com/crate-crypto/go-proto-danksharding-crypto/serialization" + "github.com/crate-crypto/go-proto-danksharding-crypto/serialization" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto/kzg" @@ -51,7 +51,7 @@ func (p *KZGCommitment) UnmarshalText(text []byte) error { } func (c KZGCommitment) ComputeVersionedHash() common.Hash { - return common.Hash(kzg.KZGToVersionedHash(api.KZGCommitment(c))) + return common.Hash(kzg.KZGToVersionedHash(serialization.KZGCommitment(c))) } // Compressed BLS12-381 G1 element @@ -283,24 +283,24 @@ func (blobs Blobs) ComputeCommitmentsAndProofs() (commitments []KZGCommitment, v return commitments, versionedHashes, proofs, nil } -func toBlobs(_blobs Blobs) []api.Blob { - blobs := make([]api.Blob, len(_blobs)) +func toBlobs(_blobs Blobs) []serialization.Blob { + blobs := make([]serialization.Blob, len(_blobs)) for i, _blob := range _blobs { - blobs[i] = api.Blob(_blob) + blobs[i] = serialization.Blob(_blob) } return blobs } -func toComms(_comms BlobKzgs) []api.KZGCommitment { - comms := make([]api.KZGCommitment, len(_comms)) +func toComms(_comms BlobKzgs) []serialization.KZGCommitment { + comms := make([]serialization.KZGCommitment, len(_comms)) for i, _comm := range _comms { - comms[i] = api.KZGCommitment(_comm) + comms[i] = serialization.KZGCommitment(_comm) } return comms } -func toProofs(_proofs KZGProofs) []api.KZGProof { - proofs := make([]api.KZGProof, len(_proofs)) +func toProofs(_proofs KZGProofs) []serialization.KZGProof { + proofs := make([]serialization.KZGProof, len(_proofs)) for i, _proof := range _proofs { - proofs[i] = api.KZGProof(_proof) + proofs[i] = serialization.KZGProof(_proof) } return proofs }