{"record":{"id":"18910916c5a4a14c","repo":"golang/go","slug":"input-overflows-the-modulus","errorCode":null,"errorMessage":"input overflows the modulus","messagePattern":"input overflows the modulus","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/bigmod/nat.go","lineNumber":188,"sourceCode":"\t\t\tlimb >>= 8\n\t\t}\n\t}\n\treturn bytes\n}\n\n// SetBytes assigns x = b, where b is a slice of big-endian bytes.\n// SetBytes returns an error if b >= m.\n//\n// The output will be resized to the size of m and overwritten.\n//\n//go:norace\nfunc (x *Nat) SetBytes(b []byte, m *Modulus) (*Nat, error) {\n\tx.resetFor(m)\n\tif err := x.setBytes(b); err != nil {\n\t\treturn nil, err\n\t}\n\tif x.cmpGeq(m.nat) == yes {\n\t\treturn nil, errors.New(\"input overflows the modulus\")\n\t}\n\treturn x, nil\n}\n\n// SetOverflowingBytes assigns x = b, where b is a slice of big-endian bytes.\n// SetOverflowingBytes returns an error if b has a longer bit length than m, but\n// reduces overflowing values up to 2^⌈log2(m)⌉ - 1.\n//\n// The output will be resized to the size of m and overwritten.\nfunc (x *Nat) SetOverflowingBytes(b []byte, m *Modulus) (*Nat, error) {\n\tx.resetFor(m)\n\tif err := x.setBytes(b); err != nil {\n\t\treturn nil, err\n\t}\n\t// setBytes would have returned an error if the input overflowed the limb\n\t// size of the modulus, so now we only need to check if the most significant\n\t// limb of x has more bits than the most significant limb of the modulus.\n\tif bitLen(x.limbs[len(x.limbs)-1]) > bitLen(m.nat.limbs[len(m.nat.limbs)-1]) {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/bigmod/nat.go#L170-L206","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nnat, err := bigmod.NewNat().SetBytes(rawScalar, curveOrder)\nif err != nil { /* may be 'input overflows the modulus' */ }\n\n// after: tolerate values that may equal/exceed the order but fit its bit length\nnat, err := bigmod.NewNat().SetOverflowingBytes(rawScalar, curveOrder)","handlingStrategy":"validation","validationCode":"// Ensure b is canonical (< m) before SetBytes.\n// For byte slices, a quick necessary check is length vs m.Size();\n// a sufficient check needs a value comparison.\nif len(b) > m.Size() {\n    return fmt.Errorf(\"input longer than modulus (%d > %d)\", len(b), m.Size())\n}\n// Prefer SetOverflowingBytes if b may be in [m, 2^bitlen(m)).\n_, err := bigmod.NewNat().SetOverflowingBytes(b, m)\nif err != nil { return err }","typeGuard":"// validForModulus checks the easy, structural precondition.\nfunc validForModulus(b []byte, m *bigmod.Modulus) bool {\n    return len(b) <= m.Size()\n}","tryCatchPattern":"v, err := bigmod.NewNat().SetBytes(b, m)\nif err != nil {\n    // fall back to the overflowing variant only if bit-length permits\n    v, err = bigmod.NewNat().SetOverflowingBytes(b, m)\n    if err != nil { return err }\n}","preventionTips":["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."],"tags":["go","crypto","fips","bigmod","modular-arithmetic","input-validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}