Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FP256BN Plus and math.MaxInt64 #58

Open
ale-linux opened this issue May 18, 2021 · 7 comments
Open

FP256BN Plus and math.MaxInt64 #58

ale-linux opened this issue May 18, 2021 · 7 comments

Comments

@ale-linux
Copy link

The following test

import (
	"math"
	"math/rand"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestMaxInt(t *testing.T) {
	r1 := int(rand.Int63())
	r2 := int(rand.Int63())

	i1 := FP256BN.NewBIGint(math.MaxInt64 - r1)
	i2 := FP256BN.NewBIGint(r1)
	i3 := FP256BN.NewBIGint(math.MaxInt64 - r2)
	i4 := FP256BN.NewBIGint(r2)
	i5 := FP256BN.NewBIGint(2)

	i6 := i1.Plus(i2).Plus(i3).Plus(i4).Plus(i5)

	zero := FP256BN.NewBIGint(0)

	assert.NotEqual(t, zero, i6)
}

fails whereas it looks like it should be succeeding. The test was conducted with go version go1.14.4 linux/amd64 against the curve

32. FP256BN

generated by config64.py (git revision 5387e6a895243dde0).

@ale-linux
Copy link
Author

This is actually related to miracl/core#44 and in fact, the git revision refers to that repo. The issue can be reproduced against both libraries

@mcarrickscott
Copy link
Contributor

mcarrickscott commented May 18, 2021 via email

@ale-linux
Copy link
Author

Thanks @mcarrickscott. We were testing various ECC math/crypto libraries (e.g. miracl/core, https://github.com/ConsenSys/gnark-crypto etc) trying to develop tests asserting basic behaviour across all of them, which is how we stumbled upon this issue.
What are the restrictions on the BIG and its constructors? We were expecting that something like

func TestMaxInt(t *testing.T) {
	i := FP256BN.NewBIGint(1)
	for j := 0; j < 64; j++ {
		i = i.Plus(i)
	}
	zero := FP256BN.NewBIGint(0)
	assert.NotEqual(t, zero, i)
}

would work.
Let us know how we're misusing the library - thanks!

@mcarrickscott
Copy link
Contributor

mcarrickscott commented May 18, 2021 via email

@ale-linux
Copy link
Author

Thanks a lot! So, without the explicit call to normalization the correctness of the result of Plus invocations is not guaranteed?

@mcarrickscott
Copy link
Contributor

mcarrickscott commented May 18, 2021 via email

@ale-linux
Copy link
Author

It is probably best if we implement the norm() inside of Plus() since
Plus() is public and likely to be used as you have used it. So thanks for
bringing this to my attention.

Thank you

But note that this is not a bignum library, and is not expected to be used
as one.

Fair enough; but.. computations over the exponents (e.g. g^{\sum{a_i} mod Q}) are commonplace, and one might chain multiple +'s before calling Mod(q) (which iiuc calls norm()). So for example

func TestMaxInt(t *testing.T) {
	i := FP256BN.NewBIGint(1)
	q := FP256BN.NewBIGints(FP256BN.CURVE_Order)

	for j := 0; j < 64; j++ {
		i = i.Plus(i)
	}

	i.Mod(q)
	zero := FP256BN.NewBIGint(0)
	assert.NotEqual(t, zero, i)
}

one might assume this would work (I did notice that calling mod after every Plus seems to produce the right result).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants