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