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	. "gnark-ed25519/field"
 5
 6	"github.com/consensys/gnark/frontend"
 7)
 8
 9type QuadraticExtensionAPI struct {
10	field frontend.API
11
12	W             F
13	DTH_ROOT      F
14	ZERO_F        F
15	DEGREE_BITS_F F
16
17	ONE            QuadraticExtension
18	DEGREE_BITS_QE QuadraticExtension
19}
20
21func NewQuadraticExtensionAPI(field frontend.API, degreeBits uint64) *QuadraticExtensionAPI {
22	// TODO:  Should degreeBits be verified that it fits within the field?
23
24	return &QuadraticExtensionAPI{
25		field: field,
26
27		W:             NewFieldElement(7),
28		DTH_ROOT:      NewFieldElement(18446744069414584320),
29		ZERO_F:        NewFieldElement(0),
30		DEGREE_BITS_F: NewFieldElement(degreeBits),
31
32		ONE:            QuadraticExtension{NewFieldElement(1), NewFieldElement(0)},
33		DEGREE_BITS_QE: QuadraticExtension{NewFieldElement(degreeBits), NewFieldElement(0)},
34	}
35}
36
37func (c *QuadraticExtensionAPI) SquareExtension(a QuadraticExtension) QuadraticExtension {
38	return c.MulExtension(a, a)
39}
40
41func (c *QuadraticExtensionAPI) MulExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
42	c_0 := c.field.Add(c.field.Mul(a[0], b[0]).(F), c.field.Mul(c.W, a[1], b[1])).(F)
43	c_1 := c.field.Add(c.field.Mul(a[0], b[1]).(F), c.field.Mul(a[1], b[0])).(F)
44	return QuadraticExtension{c_0, c_1}
45}
46
47func (c *QuadraticExtensionAPI) AddExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
48	c_0 := c.field.Add(a[0], b[0]).(F)
49	c_1 := c.field.Add(a[1], b[1]).(F)
50	return QuadraticExtension{c_0, c_1}
51}
52
53func (c *QuadraticExtensionAPI) SubExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
54	c_0 := c.field.Sub(a[0], b[0]).(F)
55	c_1 := c.field.Sub(a[1], b[1]).(F)
56	return QuadraticExtension{c_0, c_1}
57}
58
59func (c *QuadraticExtensionAPI) DivExtension(a QuadraticExtension, b QuadraticExtension) QuadraticExtension {
60	return c.MulExtension(a, c.InverseExtension(b))
61}
62
63// TODO: Instead of calculating the inverse within the circuit, can witness the
64// inverse and assert that a_inverse * a = 1.  Should reduce # of constraints.
65func (c *QuadraticExtensionAPI) InverseExtension(a QuadraticExtension) QuadraticExtension {
66	// First assert that a doesn't have 0 value coefficients
67	a0_is_zero := c.field.IsZero(a[0])
68	a1_is_zero := c.field.IsZero(a[1])
69
70	// assert that a0_is_zero OR a1_is_zero == false
71	c.field.AssertIsEqual(c.field.Mul(a0_is_zero, a1_is_zero).(F), c.ZERO_F)
72
73	a_pow_r_minus_1 := QuadraticExtension{a[0], c.field.Mul(a[1], c.DTH_ROOT).(F)}
74	a_pow_r := c.MulExtension(a_pow_r_minus_1, a)
75	return c.ScalarMulExtension(a_pow_r_minus_1, c.field.Inverse(a_pow_r[0]).(F))
76}
77
78func (c *QuadraticExtensionAPI) ScalarMulExtension(a QuadraticExtension, scalar F) QuadraticExtension {
79	return QuadraticExtension{c.field.Mul(a[0], scalar).(F), c.field.Mul(a[1], scalar).(F)}
80}