golang/go · error

input overflows the modulus

Error message

input overflows the modulus

What it means

Thrown by bigmod.(*Nat).SetBytes when the big-endian byte slice b decodes to an integer that is greater than or equal to the modulus m (cmpGeq(m.nat) == yes). SetBytes requires b < m because it stores the value unreduced and only accepts canonical residues. This guards the invariant that a reduced Nat is strictly smaller than its Modulus.

Source

Thrown at src/crypto/internal/fips140/bigmod/nat.go:188

			limb >>= 8
		}
	}
	return bytes
}

// SetBytes assigns x = b, where b is a slice of big-endian bytes.
// SetBytes returns an error if b >= m.
//
// The output will be resized to the size of m and overwritten.
//
//go:norace
func (x *Nat) SetBytes(b []byte, m *Modulus) (*Nat, error) {
	x.resetFor(m)
	if err := x.setBytes(b); err != nil {
		return nil, err
	}
	if x.cmpGeq(m.nat) == yes {
		return nil, errors.New("input overflows the modulus")
	}
	return x, nil
}

// SetOverflowingBytes assigns x = b, where b is a slice of big-endian bytes.
// SetOverflowingBytes returns an error if b has a longer bit length than m, but
// reduces overflowing values up to 2^⌈log2(m)⌉ - 1.
//
// The output will be resized to the size of m and overwritten.
func (x *Nat) SetOverflowingBytes(b []byte, m *Modulus) (*Nat, error) {
	x.resetFor(m)
	if err := x.setBytes(b); err != nil {
		return nil, err
	}
	// setBytes would have returned an error if the input overflowed the limb
	// size of the modulus, so now we only need to check if the most significant
	// limb of x has more bits than the most significant limb of the modulus.
	if bitLen(x.limbs[len(x.limbs)-1]) > bitLen(m.nat.limbs[len(m.nat.limbs)-1]) {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. If the value may legitimately equal or exceed m but fits within the modulus bit-length, use SetOverflowingBytes (which reduces it) instead of SetBytes.
  2. Ensure the byte slice length matches m.Size() and that the decoded value is strictly less than m before calling SetBytes.
  3. If you must use SetBytes, reduce the value mod m upstream so the canonical residue is passed in.

Example fix

// before
nat, err := bigmod.NewNat().SetBytes(rawScalar, curveOrder)
if err != nil { /* may be 'input overflows the modulus' */ }

// after: tolerate values that may equal/exceed the order but fit its bit length
nat, err := bigmod.NewNat().SetOverflowingBytes(rawScalar, curveOrder)
Defensive patterns

Strategy: validation

Validate before calling

// Ensure b is canonical (< m) before SetBytes.
// For byte slices, a quick necessary check is length vs m.Size();
// a sufficient check needs a value comparison.
if len(b) > m.Size() {
    return fmt.Errorf("input longer than modulus (%d > %d)", len(b), m.Size())
}
// Prefer SetOverflowingBytes if b may be in [m, 2^bitlen(m)).
_, err := bigmod.NewNat().SetOverflowingBytes(b, m)
if err != nil { return err }

Type guard

// validForModulus checks the easy, structural precondition.
func validForModulus(b []byte, m *bigmod.Modulus) bool {
    return len(b) <= m.Size()
}

Try / catch

v, err := bigmod.NewNat().SetBytes(b, m)
if err != nil {
    // fall back to the overflowing variant only if bit-length permits
    v, err = bigmod.NewNat().SetOverflowingBytes(b, m)
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling bigmod.NewNat().SetBytes(b, m) where b's value >= m. Happens for: a private scalar not reduced mod n, a signature r/s component that exceeds the curve order, or any byte slice whose decoded magnitude reaches the modulus.

Common situations: Passing raw un-reduced key material from another library, using a hash or random value without masking, or a byte-length mismatch against the curve order (e.g. a 33-byte scalar on P-256 whose value exceeds n).

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/18910916c5a4a14c. Report an issue: GitHub.