arnaucube
arnaucube/go-circom-prover-verifierPublic Self-hosted repository
go-circom-prover-verifier/arithmetic.go
arithmetic.goRaw
 1package gocircomprover
 2
 3import (
 4	"bytes"
 5	"math/big"
 6)
 7
 8func FAdd(a, b *big.Int) *big.Int {
 9	ab := new(big.Int).Add(a, b)
10	return new(big.Int).Mod(ab, R)
11}
12
13func FSub(a, b *big.Int) *big.Int {
14	ab := new(big.Int).Sub(a, b)
15	return new(big.Int).Mod(ab, R)
16}
17
18func FMul(a, b *big.Int) *big.Int {
19	ab := new(big.Int).Mul(a, b)
20	return new(big.Int).Mod(ab, R)
21}
22
23func FDiv(a, b *big.Int) *big.Int {
24	ab := new(big.Int).Mul(a, new(big.Int).ModInverse(b, R))
25	return new(big.Int).Mod(ab, R)
26}
27
28func FNeg(a *big.Int) *big.Int {
29	return new(big.Int).Mod(new(big.Int).Neg(a), R)
30}
31
32func FInv(a *big.Int) *big.Int {
33	return new(big.Int).ModInverse(a, R)
34}
35
36func FExp(base *big.Int, e *big.Int) *big.Int {
37	res := big.NewInt(1)
38	rem := new(big.Int).Set(e)
39	exp := base
40
41	for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
42		// if BigIsOdd(rem) {
43		if rem.Bit(0) == 1 { // .Bit(0) returns 1 when is odd
44			res = FMul(res, exp)
45		}
46		exp = FMul(exp, exp)
47		rem = new(big.Int).Rsh(rem, 1)
48	}
49	return res
50}