Assessment reports>Brevis>Informational findings>Number of limbs of ,Uint521, not enforced
Category: Coding Mistakes

Number of limbs of Uint521 not enforced

Informational Severity
Informational Impact
N/A Likelihood

Description

The sdk's Uint521 type uses gnark's standard library implementation for emulated fields, in a configuration in which elements are stored in six limbs of 96 bits each:

var u521Field *emulated.Field[Uint521Field]

type Uint521Field struct{}

func (f Uint521Field) NbLimbs() uint { return 6 }

func (f Uint521Field) BitsPerLimb() uint { return 96 }

type Uint521 struct {
	*emulated.Element[Uint521Field]
}

However, the Values and FromValues implementations do not verify the number of limbs. Thus, FromValues accepts arbitrary numbers of arguments, using them as limbs, even less or more than six, and Values similarly does not check how many limbs it is returning:

func (v Uint521) Values() []frontend.Variable {
	u521Field.Reduce(v.Element)
	return v.Limbs
}

func (v Uint521) FromValues(vs ...frontend.Variable) CircuitVariable {
	n := emulated.ValueOf[Uint521Field](0)
	n.Limbs = vs
	return newU521(&n)
}

Based on a cursory look into gnark's emulated.Field implementation as used by Uint521, it appears that a variable number of limbs generally seems to be supported.

However, lack of limb-number checks means that Values does not always return a list of the same length. This can cause problems for example when attempting to use Uint521 as components of List or TupleN types; see Discussion point ref.

Impact

As a constant length of the return value of Values is not ensured, using Uint521 within the SDK's list or tuple types may cause crashes or panics or lead to unintended behavior (e.g., limbs of three Uint521s being split up among two Uint521s instead).

While it appears as though emulated.Field can handle elements with nonstandard numbers of limbs, we have not fully checked emulated.Field to make sure this is the case. As usage with nonstandard number of limbs is not explicitly documented as being supported, it may thus be safer to ensure a standard number of limbs for Uint521.

Recommendations

We recommend to check that len(vs) is equal to NumVars() in FromValues and that len(v.Limbs) is equal to NumVars() just before the return in Values.

Remediation

This issue has been acknowledged by Brevis, and fixes were implemented in the following commits:

Zellic © 2025Back to top ↑