arnaucube
arnaucube/go-snarkPublic Self-hosted repository
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}