-
Notifications
You must be signed in to change notification settings - Fork 21
/
api.go
149 lines (128 loc) · 5.85 KB
/
api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package goethkzg
import (
"encoding/json"
"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 *kzg.Domain
domainExtended *kzg.Domain
commitKeyLagrange *kzg.CommitKey
commitKeyMonomial *kzg.CommitKey
openKey *kzg.OpeningKey
fk20 *fk20.FK20
dataRecovery *kzgmulti.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")
}
openingKey := kzg.OpeningKey{
GenG1: genG1,
GenG2: genG2,
AlphaG2: alphaGenG2,
G1: setupMonomialG1Points[:len(setupG2Points)],
G2: setupG2Points,
}
domain := kzg.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()
domain.ReverseRoots()
domainExtended := kzg.NewDomain(scalarsPerExtBlob)
domainExtended.ReverseRoots()
fk20 := fk20.NewFK20(commitKeyMonomial.G1, scalarsPerExtBlob, scalarsPerCell)
return &Context{
domain: domain,
domainExtended: domainExtended,
commitKeyLagrange: &commitKeyLagrange,
commitKeyMonomial: &commitKeyMonomial,
openKey: &openingKey,
fk20: &fk20,
// TODO: We compute the extendedDomain again in here.
// TODO: We could pass it in, but it breaks the API.
// TODO: And although its not an issue now because fft uses just the primitiveGenerator, the extended domain
// TODO: that recovery takes is not bit reversed.
dataRecovery: kzgmulti.NewDataRecovery(scalarsPerCell, ScalarsPerBlob, expansionFactor),
}, nil
}