gnark-plonky2-verifier/field/goldilocks.go
field/goldilocks.goRaw
1package field
2
3import (
4 "github.com/consensys/gnark-crypto/ecc"
5 "github.com/consensys/gnark-crypto/field/goldilocks"
6 "github.com/consensys/gnark/frontend"
7 "github.com/consensys/gnark/std/math/emulated"
8)
9
10type EmulatedField = emulated.Goldilocks
11type F = *emulated.Element[EmulatedField]
12type FieldAPI = *emulated.Field[emulated.Goldilocks]
13
14var TEST_CURVE = ecc.BN254
15
16func NewFieldAPI(api frontend.API) FieldAPI {
17 fieldAPI, err := emulated.NewField[EmulatedField](api)
18 if err != nil {
19 panic(err)
20 }
21 return fieldAPI
22}
23
24func NewFieldConst(x uint64) F {
25 val := emulated.ValueOf[EmulatedField](x)
26 return &val
27}
28
29func NewFieldConstFromString(x string) F {
30 val := emulated.ValueOf[EmulatedField](x)
31 return &val
32}
33
34var ONE_F = NewFieldConst(1)
35var ZERO_F = NewFieldConst(0)
36var NEG_ONE_F = NewFieldConst(EmulatedField{}.Modulus().Uint64() - 1)
37
38var GOLDILOCKS_MULTIPLICATIVE_GROUP_GENERATOR = goldilocks.NewElement(7)
39var GOLDILOCKS_TWO_ADICITY = uint64(32)
40var GOLDILOCKS_POWER_OF_TWO_GENERATOR = goldilocks.NewElement(1753635133440165772)
41
42func GoldilocksPrimitiveRootOfUnity(nLog uint64) goldilocks.Element {
43 if nLog > GOLDILOCKS_TWO_ADICITY {
44 panic("nLog is greater than GOLDILOCKS_TWO_ADICITY")
45 }
46
47 res := goldilocks.NewElement(GOLDILOCKS_POWER_OF_TWO_GENERATOR.Uint64())
48 for i := 0; i < int(GOLDILOCKS_TWO_ADICITY-nLog); i++ {
49 res.Square(&res)
50 }
51
52 return res
53}
54
55func TwoAdicSubgroup(nLog uint64) []goldilocks.Element {
56 if nLog > GOLDILOCKS_TWO_ADICITY {
57 panic("nLog is greater than GOLDILOCKS_TWO_ADICITY")
58 }
59
60 var res []goldilocks.Element
61 rootOfUnity := GoldilocksPrimitiveRootOfUnity(nLog)
62 res = append(res, goldilocks.NewElement(1))
63
64 for i := 0; i < (1 << nLog); i++ {
65 lastElement := res[len(res)-1]
66 res = append(res, *lastElement.Mul(&lastElement, &rootOfUnity))
67 }
68
69 return res
70}
71
72func IsZero(api frontend.API, fieldAPI *emulated.Field[emulated.Goldilocks], x F) frontend.Variable {
73 reduced := fieldAPI.Reduce(x)
74 limbs := reduced.Limbs
75
76 isZero := api.IsZero(limbs[0])
77 for i := 1; i < len(limbs); i++ {
78 isZero = api.Mul(isZero, api.IsZero(limbs[i]))
79 }
80
81 return isZero
82
83}