package main // bigint.go: methods for bigint operation chaining import ( "math/big" ) type bigint struct { v *big.Int } func (x bigint) Add(y bigint) bigint { return bigint{v: new(big.Int).Add(x.v, y.v)} } func (x bigint) AddInt(y int) bigint { return bigint{v: new(big.Int).Add(x.v, big.NewInt(int64(y)))} } func (x bigint) Sub(y bigint) bigint { return bigint{v: new(big.Int).Sub(x.v, y.v)} } func (x bigint) SubInt(y int) bigint { return bigint{v: new(big.Int).Sub(x.v, big.NewInt(int64(y)))} } func (x bigint) Mul(y bigint) bigint { return bigint{v: new(big.Int).Mul(x.v, y.v)} } func (x bigint) MulInt(y int) bigint { return bigint{v: new(big.Int).Mul(x.v, big.NewInt(int64(y)))} } func (x bigint) Div(y bigint) bigint { return bigint{v: new(big.Int).Div(x.v, y.v)} } func (x bigint) DivInt(y int) bigint { return bigint{v: new(big.Int).Div(x.v, big.NewInt(int64(y)))} } func (x bigint) Mod(y bigint) bigint { return bigint{v: new(big.Int).Mod(x.v, y.v)} } func (x bigint) ModInt(y int) bigint { return bigint{v: new(big.Int).Mod(x.v, big.NewInt(int64(y)))} } func (x bigint) Pow(y bigint) bigint { return bigint{v: new(big.Int).Exp(x.v, y.v, nil)} } func (x bigint) PowInt(y int) bigint { return bigint{v: new(big.Int).Exp(x.v, big.NewInt(int64(y)), nil)} } func (x bigint) And(y bigint) bigint { return bigint{v: new(big.Int).And(x.v, y.v)} } func (x bigint) AndInt(y int) bigint { return bigint{v: new(big.Int).And(x.v, big.NewInt(int64(y)))} } func (x bigint) Neg() bigint { return bigint{v: new(big.Int).Neg(x.v)} } func (x bigint) Empty() bool { return x.v == nil || x.v.Sign() == 0 } func (x bigint) ModExp(y, m bigint) bigint { return bigint{v: new(big.Int).Exp(x.v, y.v, m.v)} } func (x bigint) Eq(y bigint) bool { return x.v.Cmp(y.v) == 0 } func (x bigint) EqInt(y int) bool { return x.v.Cmp(big.NewInt(int64(y))) == 0 } func (x bigint) Ne(y bigint) bool { return x.v.Cmp(y.v) != 0 } func (x bigint) NeInt(y int) bool { return x.v.Cmp(big.NewInt(int64(y))) != 0 } func (x bigint) Lt(y bigint) bool { return x.v.Cmp(y.v) < 0 } func (x bigint) LtInt(y int) bool { return x.v.Cmp(big.NewInt(int64(y))) < 0 } func (x bigint) Gt(y bigint) bool { return x.v.Cmp(y.v) > 0 } func (x bigint) GtInt(y int) bool { return x.v.Cmp(big.NewInt(int64(y))) > 0 } func (x bigint) Lte(y bigint) bool { return x.v.Cmp(y.v) <= 0 } func (x bigint) LteInt(y int) bool { return x.v.Cmp(big.NewInt(int64(y))) <= 0 } func (x bigint) Gte(y bigint) bool { return x.v.Cmp(y.v) >= 0 } func (x bigint) GteInt(y int) bool { return x.v.Cmp(big.NewInt(int64(y))) >= 0 } func (x bigint) ToBytes(n int) []byte { res := make([]byte, n) return x.v.FillBytes(res) } func NewBigint(x int) bigint { bi := bigint{} bi.v = big.NewInt(int64(x)) return bi } func NewEmptyBigint() bigint { return bigint{v: nil} } func NewBigintFromString(s string, p int) bigint { bi := bigint{} bi.v, _ = new(big.Int).SetString(s, p) return bi } func NewBigintFromBytes(b []byte) bigint { bi := bigint{} bi.v = new(big.Int).SetBytes(b) return bi }