diff --git a/arithmetic.go b/arithmetic.go index 583283a..13f89b0 100644 --- a/arithmetic.go +++ b/arithmetic.go @@ -5,6 +5,14 @@ import ( "math/big" ) +func arrayOfZeroes(n int) []*big.Int { + var r []*big.Int + for i := 0; i < n; i++ { + r = append(r, new(big.Int).SetInt64(0)) + } + return r +} + func FAdd(a, b *big.Int) *big.Int { ab := new(big.Int).Add(a, b) return new(big.Int).Mod(ab, R) @@ -48,3 +56,47 @@ func FExp(base *big.Int, e *big.Int) *big.Int { } return res } + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func PolynomialSub(a, b []*big.Int) []*big.Int { + r := arrayOfZeroes(max(len(a), len(b))) + for i := 0; i < len(a); i++ { + r[i] = FAdd(r[i], a[i]) + } + for i := 0; i < len(b); i++ { + r[i] = FSub(r[i], b[i]) + } + return r +} + +func PolynomialMul(a, b []*big.Int) []*big.Int { + r := arrayOfZeroes(len(a) + len(b) - 1) + for i := 0; i < len(a); i++ { + for j := 0; j < len(b); j++ { + r[i+j] = FAdd(r[i+j], FMul(a[i], b[j])) + } + } + return r +} + +func PolynomialDiv(a, b []*big.Int) ([]*big.Int, []*big.Int) { + // https://en.wikipedia.org/wiki/Division_algorithm + r := arrayOfZeroes(len(a) - len(b) + 1) + rem := a + for len(rem) >= len(b) { + l := FDiv(rem[len(rem)-1], b[len(b)-1]) + pos := len(rem) - len(b) + r[pos] = l + aux := arrayOfZeroes(pos) + aux1 := append(aux, l) + aux2 := PolynomialSub(rem, PolynomialMul(b, aux1)) + rem = aux2[:len(aux2)-1] + } + return r, rem +}