arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/plonky2_verifier/quadratic_extension.go
plonky2_verifier/quadratic_extension.goRaw
 1package plonky2_verifier
 2
 3import (
 4	"fmt"
 5	. "gnark-ed25519/field"
 6
 7	"github.com/consensys/gnark/frontend"
 8)
 9
10type QuadraticExtensionAPI struct {
11	fieldAPI frontend.API
12
13	W        F
14	DTH_ROOT F
15	ZERO_F   F
16
17	ONE     QuadraticExtension
18	ZERO_QE QuadraticExtension
19}
20
21func NewQuadraticExtensionAPI(fieldAPI frontend.API, degreeBits uint64) *QuadraticExtensionAPI {
22	// TODO:  Should degreeBits be verified that it fits within the field and that degree is within uint64?
23
24	return &QuadraticExtensionAPI{
25		fieldAPI: fieldAPI,
26
27		W:        NewFieldElement(7),
28		DTH_ROOT: NewFieldElement(18446744069414584320),
29
30		ONE:     QuadraticExtension{ONE_F, ZERO_F},
31		ZERO_QE: QuadraticExtension{ZERO_F, ZERO_F},
32	}
33}
34
35func (c *QuadraticExtensionAPI) SquareExtension(a QuadraticExtension) QuadraticExtension {
36	return c.MulExtension(a, a)
37}
38
39func (c *QuadraticExtensionAPI) MulExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
40	c_0 := c.fieldAPI.Add(c.fieldAPI.Mul(a[0], b[0]).(F), c.fieldAPI.Mul(c.W, a[1], b[1])).(F)
41	c_1 := c.fieldAPI.Add(c.fieldAPI.Mul(a[0], b[1]).(F), c.fieldAPI.Mul(a[1], b[0])).(F)
42	return QuadraticExtension{c_0, c_1}
43}
44
45func (c *QuadraticExtensionAPI) AddExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
46	c_0 := c.fieldAPI.Add(a[0], b[0]).(F)
47	c_1 := c.fieldAPI.Add(a[1], b[1]).(F)
48	return QuadraticExtension{c_0, c_1}
49}
50
51func (c *QuadraticExtensionAPI) SubExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
52	c_0 := c.fieldAPI.Sub(a[0], b[0]).(F)
53	c_1 := c.fieldAPI.Sub(a[1], b[1]).(F)
54	return QuadraticExtension{c_0, c_1}
55}
56
57func (c *QuadraticExtensionAPI) DivExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
58	return c.MulExtension(a, c.InverseExtension(b))
59}
60
61// TODO: Instead of calculating the inverse within the circuit, can witness the
62// inverse and assert that a_inverse * a = 1.  Should reduce # of constraints.
63func (c *QuadraticExtensionAPI) InverseExtension(a QuadraticExtension) QuadraticExtension {
64	// First assert that a doesn't have 0 value coefficients
65	a0_is_zero := c.fieldAPI.IsZero(a[0])
66	a1_is_zero := c.fieldAPI.IsZero(a[1])
67
68	// assert that a0_is_zero OR a1_is_zero == false
69	c.fieldAPI.AssertIsEqual(c.fieldAPI.Mul(a0_is_zero, a1_is_zero).(F), c.ZERO_F)
70
71	a_pow_r_minus_1 := QuadraticExtension{a[0], c.fieldAPI.Mul(a[1], c.DTH_ROOT).(F)}
72	a_pow_r := c.MulExtension(a_pow_r_minus_1, a)
73	return c.ScalarMulExtension(a_pow_r_minus_1, c.fieldAPI.Inverse(a_pow_r[0]).(F))
74}
75
76func (c *QuadraticExtensionAPI) ScalarMulExtension(a QuadraticExtension, scalar F) QuadraticExtension {
77	return QuadraticExtension{c.fieldAPI.Mul(a[0], scalar).(F), c.fieldAPI.Mul(a[1], scalar).(F)}
78}
79
80func (c *QuadraticExtensionAPI) FieldToQE(a F) QuadraticExtension {
81	return QuadraticExtension{a, c.ZERO_F}
82}
83
84func (c *QuadraticExtensionAPI) Println(a QuadraticExtension) {
85	fmt.Print("Degree 0 coefficient")
86	c.fieldAPI.Println(a[0])
87
88	fmt.Print("Degree 1 coefficient")
89	c.fieldAPI.Println(a[1])
90}