go-snark/bn128/fq.go
bn128/fq.goRaw
1package bn128
2
3import (
4 "bytes"
5 "math/big"
6)
7
8// Fq is the Z field over modulus Q
9type Fq struct {
10 Q *big.Int // Q
11}
12
13// NewFq generates a new Fq
14func NewFq(q *big.Int) Fq {
15 return Fq{
16 q,
17 }
18}
19
20// Zero returns a Zero value on the Fq
21func (fq Fq) Zero() *big.Int {
22 return big.NewInt(int64(0))
23}
24
25// One returns a One value on the Fq
26func (fq Fq) One() *big.Int {
27 return big.NewInt(int64(1))
28}
29
30// Add performs an addition on the Fq
31func (fq Fq) Add(a, b *big.Int) *big.Int {
32 r := new(big.Int).Add(a, b)
33 // return new(big.Int).Mod(r, fq.Q)
34 return r
35}
36
37// Double performs a doubling on the Fq
38func (fq Fq) Double(a *big.Int) *big.Int {
39 r := new(big.Int).Add(a, a)
40 // return new(big.Int).Mod(r, fq.Q)
41 return r
42}
43
44// Sub performs a subtraction on the Fq
45func (fq Fq) Sub(a, b *big.Int) *big.Int {
46 r := new(big.Int).Sub(a, b)
47 // return new(big.Int).Mod(r, fq.Q)
48 return r
49}
50
51// Neg performs a negation on the Fq
52func (fq Fq) Neg(a *big.Int) *big.Int {
53 m := new(big.Int).Neg(a)
54 // return new(big.Int).Mod(m, fq.Q)
55 return m
56}
57
58// Mul performs a multiplication on the Fq
59func (fq Fq) Mul(a, b *big.Int) *big.Int {
60 m := new(big.Int).Mul(a, b)
61 return new(big.Int).Mod(m, fq.Q)
62 // return m
63}
64
65func (fq Fq) MulScalar(base, e *big.Int) *big.Int {
66 return fq.Mul(base, e)
67}
68
69// Inverse returns the inverse on the Fq
70func (fq Fq) Inverse(a *big.Int) *big.Int {
71 return new(big.Int).ModInverse(a, fq.Q)
72 // q := bigCopy(fq.Q)
73 // t := big.NewInt(int64(0))
74 // r := fq.Q
75 // newt := big.NewInt(int64(0))
76 // newr := fq.Affine(a)
77 // for !bytes.Equal(newr.Bytes(), big.NewInt(int64(0)).Bytes()) {
78 // q := new(big.Int).Div(bigCopy(r), bigCopy(newr))
79 //
80 // t = bigCopy(newt)
81 // newt = fq.Sub(t, fq.Mul(q, newt))
82 //
83 // r = bigCopy(newr)
84 // newr = fq.Sub(r, fq.Mul(q, newr))
85 // }
86 // if t.Cmp(big.NewInt(0)) == -1 { // t< 0
87 // t = fq.Add(t, q)
88 // }
89 // return t
90}
91
92// Square performs a square operation on the Fq
93func (fq Fq) Square(a *big.Int) *big.Int {
94 m := new(big.Int).Mul(a, a)
95 return new(big.Int).Mod(m, fq.Q)
96}
97
98func (fq Fq) IsZero(a *big.Int) bool {
99 return bytes.Equal(a.Bytes(), fq.Zero().Bytes())
100}
101
102func (fq Fq) Copy(a *big.Int) *big.Int {
103 return new(big.Int).SetBytes(a.Bytes())
104}
105
106func (fq Fq) Affine(a *big.Int) *big.Int {
107 nq := fq.Neg(fq.Q)
108
109 aux := a
110 if aux.Cmp(big.NewInt(int64(0))) == -1 { // negative value
111 if aux.Cmp(nq) != 1 { // aux less or equal nq
112 aux = new(big.Int).Mod(aux, fq.Q)
113 }
114 if aux.Cmp(big.NewInt(int64(0))) == -1 { // negative value
115 aux = new(big.Int).Add(aux, fq.Q)
116 }
117 } else {
118 if aux.Cmp(fq.Q) != -1 { // aux greater or equal nq
119 aux = new(big.Int).Mod(aux, fq.Q)
120 }
121 }
122 return aux
123}
124
125func (fq Fq) Equal(a, b *big.Int) bool {
126 aAff := fq.Affine(a)
127 bAff := fq.Affine(b)
128 return bytes.Equal(aAff.Bytes(), bAff.Bytes())
129}