diff --git a/uint256.go b/uint256.go index 20b08e6c..65a4f4bf 100644 --- a/uint256.go +++ b/uint256.go @@ -182,14 +182,14 @@ func (z *Int) Add(x, y *Int) *Int { return z } -// AddOverflow sets z to the sum x+y, and returns whether overflow occurred -func (z *Int) AddOverflow(x, y *Int) bool { +// AddOverflow sets z to the sum x+y, and returns z and whether overflow occurred +func (z *Int) AddOverflow(x, y *Int) (*Int, bool) { var carry uint64 z[0], carry = bits.Add64(x[0], y[0], 0) z[1], carry = bits.Add64(x[1], y[1], carry) z[2], carry = bits.Add64(x[2], y[2], carry) z[3], carry = bits.Add64(x[3], y[3], carry) - return carry != 0 + return z, carry != 0 } // AddMod sets z to the sum ( x+y ) mod m, and returns z @@ -197,7 +197,7 @@ func (z *Int) AddMod(x, y, m *Int) *Int { if z == m { // z is an alias for m // TODO: Understand why needed and add tests for all "division" methods. m = m.Clone() } - if overflow := z.AddOverflow(x, y); overflow { + if _, overflow := z.AddOverflow(x, y); overflow { sum := [5]uint64{z[0], z[1], z[2], z[3], 1} var quot [5]uint64 rem := udivrem(quot[:], sum[:], m) @@ -239,14 +239,14 @@ func (z *Int) SubUint64(x *Int, y uint64) *Int { return z } -// SubOverflow sets z to the difference x-y and returns true if the operation underflowed -func (z *Int) SubOverflow(x, y *Int) bool { +// SubOverflow sets z to the difference x-y and returns z and true if the operation underflowed +func (z *Int) SubOverflow(x, y *Int) (*Int, bool) { var carry uint64 z[0], carry = bits.Sub64(x[0], y[0], 0) z[1], carry = bits.Sub64(x[1], y[1], carry) z[2], carry = bits.Sub64(x[2], y[2], carry) z[3], carry = bits.Sub64(x[3], y[3], carry) - return carry != 0 + return z, carry != 0 } // Sub sets z to the difference x-y @@ -333,11 +333,11 @@ func (z *Int) Mul(x, y *Int) *Int { return z.Set(&res) } -// MulOverflow sets z to the product x*y, and returns whether overflow occurred -func (z *Int) MulOverflow(x, y *Int) bool { +// MulOverflow sets z to the product x*y, and returns z and whether overflow occurred +func (z *Int) MulOverflow(x, y *Int) (*Int, bool) { p := umul(x, y) copy(z[:], p[:4]) - return (p[4] | p[5] | p[6] | p[7]) != 0 + return z, (p[4] | p[5] | p[6] | p[7]) != 0 } func (z *Int) squared() { diff --git a/uint256_test.go b/uint256_test.go index 255d2709..cbd35143 100644 --- a/uint256_test.go +++ b/uint256_test.go @@ -137,6 +137,7 @@ func randNums() (*big.Int, *Int, error) { err := checkOverflow(b, f, overflow) return b, f, err } + func randHighNums() (*big.Int, *Int, error) { //How many bits? 0-256 nbits := int64(256) @@ -184,6 +185,7 @@ func testRandomOp(t *testing.T, nativeFunc func(a, b, c *Int), bigintFunc func(a } } } + func TestRandomSubOverflow(t *testing.T) { for i := 0; i < 10000; i++ { b, f1, err := randNums() @@ -195,7 +197,7 @@ func TestRandomSubOverflow(t *testing.T) { t.Fatal(err) } f1a, f2a := f1.Clone(), f2.Clone() - overflow := f1.SubOverflow(f1, f2) + _, overflow := f1.SubOverflow(f1, f2) b.Sub(b, b2) if err := checkUnderflow(b, f1, overflow); err != nil { t.Fatal(err) @@ -205,6 +207,7 @@ func TestRandomSubOverflow(t *testing.T) { } } } + func TestRandomSub(t *testing.T) { testRandomOp(t, func(f1, f2, f3 *Int) { @@ -226,6 +229,7 @@ func TestRandomAdd(t *testing.T) { }, ) } + func TestRandomMul(t *testing.T) { testRandomOp(t, @@ -237,6 +241,7 @@ func TestRandomMul(t *testing.T) { }, ) } + func TestRandomMulOverflow(t *testing.T) { for i := 0; i < 10000; i++ { b, f1, err := randNums() @@ -248,7 +253,7 @@ func TestRandomMulOverflow(t *testing.T) { t.Fatal(err) } f1a, f2a := f1.Clone(), f2.Clone() - overflow := f1.MulOverflow(f1, f2) + _, overflow := f1.MulOverflow(f1, f2) b.Mul(b, b2) if err := checkOverflow(b, f1, overflow); err != nil { t.Fatal(err) @@ -258,6 +263,7 @@ func TestRandomMulOverflow(t *testing.T) { } } } + func TestRandomSquare(t *testing.T) { testRandomOp(t, func(f1, f2, f3 *Int) { @@ -268,6 +274,7 @@ func TestRandomSquare(t *testing.T) { }, ) } + func TestRandomDiv(t *testing.T) { testRandomOp(t, func(f1, f2, f3 *Int) { @@ -297,6 +304,7 @@ func TestRandomMod(t *testing.T) { }, ) } + func TestRandomSMod(t *testing.T) { testRandomOp(t, func(f1, f2, f3 *Int) {