github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/crypto/kzg4844/kzg4844.go (about) 1 // Copyright 2023 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package kzg4844 implements the KZG crypto for EIP-4844. 18 package kzg4844 19 20 import ( 21 "embed" 22 "errors" 23 "hash" 24 "reflect" 25 "sync/atomic" 26 27 "github.com/ethereum/go-ethereum/common/hexutil" 28 ) 29 30 //go:embed trusted_setup.json 31 var content embed.FS 32 33 var ( 34 blobT = reflect.TypeOf(Blob{}) 35 commitmentT = reflect.TypeOf(Commitment{}) 36 proofT = reflect.TypeOf(Proof{}) 37 ) 38 39 // Blob represents a 4844 data blob. 40 type Blob [131072]byte 41 42 // UnmarshalJSON parses a blob in hex syntax. 43 func (b *Blob) UnmarshalJSON(input []byte) error { 44 return hexutil.UnmarshalFixedJSON(blobT, input, b[:]) 45 } 46 47 // MarshalText returns the hex representation of b. 48 func (b Blob) MarshalText() ([]byte, error) { 49 return hexutil.Bytes(b[:]).MarshalText() 50 } 51 52 // Commitment is a serialized commitment to a polynomial. 53 type Commitment [48]byte 54 55 // UnmarshalJSON parses a commitment in hex syntax. 56 func (c *Commitment) UnmarshalJSON(input []byte) error { 57 return hexutil.UnmarshalFixedJSON(commitmentT, input, c[:]) 58 } 59 60 // MarshalText returns the hex representation of c. 61 func (c Commitment) MarshalText() ([]byte, error) { 62 return hexutil.Bytes(c[:]).MarshalText() 63 } 64 65 // Proof is a serialized commitment to the quotient polynomial. 66 type Proof [48]byte 67 68 // UnmarshalJSON parses a proof in hex syntax. 69 func (p *Proof) UnmarshalJSON(input []byte) error { 70 return hexutil.UnmarshalFixedJSON(proofT, input, p[:]) 71 } 72 73 // MarshalText returns the hex representation of p. 74 func (p Proof) MarshalText() ([]byte, error) { 75 return hexutil.Bytes(p[:]).MarshalText() 76 } 77 78 // Point is a BLS field element. 79 type Point [32]byte 80 81 // Claim is a claimed evaluation value in a specific point. 82 type Claim [32]byte 83 84 // useCKZG controls whether the cryptography should use the Go or C backend. 85 var useCKZG atomic.Bool 86 87 // UseCKZG can be called to switch the default Go implementation of KZG to the C 88 // library if for some reason the user wishes to do so (e.g. consensus bug in one 89 // or the other). 90 func UseCKZG(use bool) error { 91 if use && !ckzgAvailable { 92 return errors.New("CKZG unavailable on your platform") 93 } 94 useCKZG.Store(use) 95 96 // Initializing the library can take 2-4 seconds - and can potentially crash 97 // on CKZG and non-ADX CPUs - so might as well do it now and don't wait until 98 // a crypto operation is actually needed live. 99 if use { 100 ckzgIniter.Do(ckzgInit) 101 } else { 102 gokzgIniter.Do(gokzgInit) 103 } 104 return nil 105 } 106 107 // BlobToCommitment creates a small commitment out of a data blob. 108 func BlobToCommitment(blob *Blob) (Commitment, error) { 109 if useCKZG.Load() { 110 return ckzgBlobToCommitment(blob) 111 } 112 return gokzgBlobToCommitment(blob) 113 } 114 115 // ComputeProof computes the KZG proof at the given point for the polynomial 116 // represented by the blob. 117 func ComputeProof(blob *Blob, point Point) (Proof, Claim, error) { 118 if useCKZG.Load() { 119 return ckzgComputeProof(blob, point) 120 } 121 return gokzgComputeProof(blob, point) 122 } 123 124 // VerifyProof verifies the KZG proof that the polynomial represented by the blob 125 // evaluated at the given point is the claimed value. 126 func VerifyProof(commitment Commitment, point Point, claim Claim, proof Proof) error { 127 if useCKZG.Load() { 128 return ckzgVerifyProof(commitment, point, claim, proof) 129 } 130 return gokzgVerifyProof(commitment, point, claim, proof) 131 } 132 133 // ComputeBlobProof returns the KZG proof that is used to verify the blob against 134 // the commitment. 135 // 136 // This method does not verify that the commitment is correct with respect to blob. 137 func ComputeBlobProof(blob *Blob, commitment Commitment) (Proof, error) { 138 if useCKZG.Load() { 139 return ckzgComputeBlobProof(blob, commitment) 140 } 141 return gokzgComputeBlobProof(blob, commitment) 142 } 143 144 // VerifyBlobProof verifies that the blob data corresponds to the provided commitment. 145 func VerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { 146 if useCKZG.Load() { 147 return ckzgVerifyBlobProof(blob, commitment, proof) 148 } 149 return gokzgVerifyBlobProof(blob, commitment, proof) 150 } 151 152 // CalcBlobHashV1 calculates the 'versioned blob hash' of a commitment. 153 // The given hasher must be a sha256 hash instance, otherwise the result will be invalid! 154 func CalcBlobHashV1(hasher hash.Hash, commit *Commitment) (vh [32]byte) { 155 if hasher.Size() != 32 { 156 panic("wrong hash size") 157 } 158 hasher.Reset() 159 hasher.Write(commit[:]) 160 hasher.Sum(vh[:0]) 161 vh[0] = 0x01 // version 162 return vh 163 } 164 165 // IsValidVersionedHash checks that h is a structurally-valid versioned blob hash. 166 func IsValidVersionedHash(h []byte) bool { 167 return len(h) == 32 && h[0] == 0x01 168 }