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
- If the value may legitimately equal or exceed m but fits within the modulus bit-length, use SetOverflowingBytes (which reduces it) instead of SetBytes.
- Ensure the byte slice length matches m.Size() and that the decoded value is strictly less than m before calling SetBytes.
- 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
- Always derive the modulus from the same curve constant used to size the input.
- Reduce scalars mod n at the point they are generated, not at the point of use.
- Prefer SetOverflowingBytes for values like hashes that may legitimately equal/exceed the order.
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
- input overflows the modulus size
- crypto/ecdh: invalid private key
- ecdsa: hash cannot be empty
- crypto/des: use of DES is not allowed in FIPS 140-only mode
- crypto/des: use of TripleDES is not allowed in FIPS 140-only
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/18910916c5a4a14c.
Report an issue: GitHub.