gnark icon indicating copy to clipboard operation
gnark copied to clipboard

bug: emulated arithmetic: unable to call IsZero after FromBits if the input is bigger than q

Open hussein-aitlahcen opened this issue 1 year ago • 3 comments

Unsure if it's a bug or not but I hit issues when calling IsZero after FromBits with input bigger than the modulus. I figured that FromBits can generate emulated elements with a number of limbs > NbLimbs param of the curve, is it expected? If so, IsZero should be passing? Please let me know if I am missing something. On the other hand, addition and multiplication are working, here is a strange snippet where IsZero(image) is failing and IsZero(doubleImage) is passing:


const Bytes = 32

type C struct {
	Preimage [Bytes * 8]frontend.Variable
	Image    emulated.Element[emulated.BN254Fp]
	DoubleImage emulated.Element[emulated.BN254Fp]
}

func (c *C) Define(api frontend.API) error {
	field, err := emulated.NewField[emulated.BN254Fp](api)
	if err != nil {
		return err
	}
	image := field.FromBits(c.Preimage[:]...)
	field.AssertIsEqual(image, &c.Image)
	doubleImage := field.Add(image, image)
	field.AssertIsEqual(doubleImage, &c.DoubleImage)
	// Breaks, works with field.IsZero(doubleImage)
	field.IsZero(image)
	return nil
}

func TestBreak(t *testing.T) {
	var value big.Int
	var preimage [Bytes * 8]frontend.Variable
	for i := 0; i < Bytes*8; i++ {
		preimage[i] = 1
		value.SetBit(&value, i, 1)
	}
	var doubleValue big.Int
	doubleValue.Add(&value, &value)
	err := test.IsSolved(
		&C{},
		&C{
			Preimage: preimage,
			Image:    emulated.ValueOf[emulated.BN254Fp](value),
			DoubleImage: emulated.ValueOf[emulated.BN254Fp](doubleValue),
		},
		ecc.BN254.ScalarField(),
	)
	assert.NoError(t, err)
}

hussein-aitlahcen avatar Jan 19 '24 19:01 hussein-aitlahcen