Feature/mimc7 gofffeature/bbjj-goff v0.0.3
@ -1,152 +0,0 @@ |
|||||
// code originally taken from https://github.com/arnaucube/go-snark (https://github.com/arnaucube/go-snark/blob/master/fields/fq.go), pasted here to ensure compatibility among future changes
|
|
||||
|
|
||||
package field |
|
||||
|
|
||||
import ( |
|
||||
"bytes" |
|
||||
"crypto/rand" |
|
||||
"math/big" |
|
||||
) |
|
||||
|
|
||||
// Fq is the Z field over modulus Q
|
|
||||
type Fq struct { |
|
||||
Q *big.Int // Q
|
|
||||
} |
|
||||
|
|
||||
// NewFq generates a new Fq
|
|
||||
func NewFq(q *big.Int) Fq { |
|
||||
return Fq{ |
|
||||
q, |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Zero returns a Zero value on the Fq
|
|
||||
func (fq Fq) Zero() *big.Int { |
|
||||
return big.NewInt(int64(0)) |
|
||||
} |
|
||||
|
|
||||
// One returns a One value on the Fq
|
|
||||
func (fq Fq) One() *big.Int { |
|
||||
return big.NewInt(int64(1)) |
|
||||
} |
|
||||
|
|
||||
// Add performs an addition on the Fq
|
|
||||
func (fq Fq) Add(a, b *big.Int) *big.Int { |
|
||||
r := new(big.Int).Add(a, b) |
|
||||
return new(big.Int).Mod(r, fq.Q) |
|
||||
} |
|
||||
|
|
||||
// Double performs a doubling on the Fq
|
|
||||
func (fq Fq) Double(a *big.Int) *big.Int { |
|
||||
r := new(big.Int).Add(a, a) |
|
||||
return new(big.Int).Mod(r, fq.Q) |
|
||||
} |
|
||||
|
|
||||
// Sub performs a subtraction on the Fq
|
|
||||
func (fq Fq) Sub(a, b *big.Int) *big.Int { |
|
||||
r := new(big.Int).Sub(a, b) |
|
||||
return new(big.Int).Mod(r, fq.Q) |
|
||||
} |
|
||||
|
|
||||
// Neg performs a negation on the Fq
|
|
||||
func (fq Fq) Neg(a *big.Int) *big.Int { |
|
||||
m := new(big.Int).Neg(a) |
|
||||
return new(big.Int).Mod(m, fq.Q) |
|
||||
} |
|
||||
|
|
||||
// Mul performs a multiplication on the Fq
|
|
||||
func (fq Fq) Mul(a, b *big.Int) *big.Int { |
|
||||
m := new(big.Int).Mul(a, b) |
|
||||
return new(big.Int).Mod(m, fq.Q) |
|
||||
} |
|
||||
|
|
||||
func (fq Fq) MulScalar(base, e *big.Int) *big.Int { |
|
||||
return fq.Mul(base, e) |
|
||||
} |
|
||||
|
|
||||
// Inverse returns the inverse on the Fq
|
|
||||
func (fq Fq) Inverse(a *big.Int) *big.Int { |
|
||||
return new(big.Int).ModInverse(a, fq.Q) |
|
||||
} |
|
||||
|
|
||||
// Div performs the division over the finite field
|
|
||||
func (fq Fq) Div(a, b *big.Int) *big.Int { |
|
||||
d := fq.Mul(a, fq.Inverse(b)) |
|
||||
return new(big.Int).Mod(d, fq.Q) |
|
||||
} |
|
||||
|
|
||||
// Square performs a square operation on the Fq
|
|
||||
func (fq Fq) Square(a *big.Int) *big.Int { |
|
||||
m := new(big.Int).Mul(a, a) |
|
||||
return new(big.Int).Mod(m, fq.Q) |
|
||||
} |
|
||||
|
|
||||
// Exp performs the exponential over Fq
|
|
||||
func (fq Fq) Exp(base *big.Int, e *big.Int) *big.Int { |
|
||||
res := fq.One() |
|
||||
rem := fq.Copy(e) |
|
||||
exp := base |
|
||||
|
|
||||
for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) { |
|
||||
if BigIsOdd(rem) { |
|
||||
res = fq.Mul(res, exp) |
|
||||
} |
|
||||
exp = fq.Square(exp) |
|
||||
rem = new(big.Int).Rsh(rem, 1) |
|
||||
} |
|
||||
return res |
|
||||
} |
|
||||
|
|
||||
func (fq Fq) Rand() (*big.Int, error) { |
|
||||
|
|
||||
maxbits := fq.Q.BitLen() |
|
||||
b := make([]byte, (maxbits/8)-1) |
|
||||
_, err := rand.Read(b) |
|
||||
if err != nil { |
|
||||
return nil, err |
|
||||
} |
|
||||
r := new(big.Int).SetBytes(b) |
|
||||
rq := new(big.Int).Mod(r, fq.Q) |
|
||||
|
|
||||
// r over q, nil
|
|
||||
return rq, nil |
|
||||
} |
|
||||
|
|
||||
func (fq Fq) IsZero(a *big.Int) bool { |
|
||||
return bytes.Equal(a.Bytes(), fq.Zero().Bytes()) |
|
||||
} |
|
||||
|
|
||||
func (fq Fq) Copy(a *big.Int) *big.Int { |
|
||||
return new(big.Int).SetBytes(a.Bytes()) |
|
||||
} |
|
||||
|
|
||||
func (fq Fq) Affine(a *big.Int) *big.Int { |
|
||||
nq := fq.Neg(fq.Q) |
|
||||
|
|
||||
aux := a |
|
||||
if aux.Cmp(big.NewInt(int64(0))) == -1 { // negative value
|
|
||||
if aux.Cmp(nq) != 1 { // aux less or equal nq
|
|
||||
aux = new(big.Int).Mod(aux, fq.Q) |
|
||||
} |
|
||||
if aux.Cmp(big.NewInt(int64(0))) == -1 { // negative value
|
|
||||
aux = new(big.Int).Add(aux, fq.Q) |
|
||||
} |
|
||||
} else { |
|
||||
if aux.Cmp(fq.Q) != -1 { // aux greater or equal nq
|
|
||||
aux = new(big.Int).Mod(aux, fq.Q) |
|
||||
} |
|
||||
} |
|
||||
return aux |
|
||||
} |
|
||||
|
|
||||
func (fq Fq) Equal(a, b *big.Int) bool { |
|
||||
aAff := fq.Affine(a) |
|
||||
bAff := fq.Affine(b) |
|
||||
return bytes.Equal(aAff.Bytes(), bAff.Bytes()) |
|
||||
} |
|
||||
|
|
||||
func BigIsOdd(n *big.Int) bool { |
|
||||
one := big.NewInt(int64(1)) |
|
||||
and := new(big.Int).And(n, one) |
|
||||
return bytes.Equal(and.Bytes(), big.NewInt(int64(1)).Bytes()) |
|
||||
} |
|
@ -1,39 +0,0 @@ |
|||||
// code originally taken from https://github.com/arnaucube/go-snark (https://github.com/arnaucube/go-snark/blob/master/fields/fq.go), pasted here to ensure compatibility among future changes
|
|
||||
|
|
||||
package field |
|
||||
|
|
||||
import ( |
|
||||
"math/big" |
|
||||
"testing" |
|
||||
|
|
||||
"github.com/stretchr/testify/assert" |
|
||||
) |
|
||||
|
|
||||
func iToBig(a int) *big.Int { |
|
||||
return big.NewInt(int64(a)) |
|
||||
} |
|
||||
|
|
||||
func TestFq1(t *testing.T) { |
|
||||
fq1 := NewFq(iToBig(7)) |
|
||||
|
|
||||
res := fq1.Add(iToBig(4), iToBig(4)) |
|
||||
assert.Equal(t, iToBig(1), fq1.Affine(res)) |
|
||||
|
|
||||
res = fq1.Double(iToBig(5)) |
|
||||
assert.Equal(t, iToBig(3), fq1.Affine(res)) |
|
||||
|
|
||||
res = fq1.Sub(iToBig(5), iToBig(7)) |
|
||||
assert.Equal(t, iToBig(5), fq1.Affine(res)) |
|
||||
|
|
||||
res = fq1.Neg(iToBig(5)) |
|
||||
assert.Equal(t, iToBig(2), fq1.Affine(res)) |
|
||||
|
|
||||
res = fq1.Mul(iToBig(5), iToBig(11)) |
|
||||
assert.Equal(t, iToBig(6), fq1.Affine(res)) |
|
||||
|
|
||||
res = fq1.Inverse(iToBig(4)) |
|
||||
assert.Equal(t, iToBig(2), res) |
|
||||
|
|
||||
res = fq1.Square(iToBig(5)) |
|
||||
assert.Equal(t, iToBig(4), res) |
|
||||
} |
|