golang/go · error
invalid scalar length
Error message
invalid scalar length
What it means
P256Point.ScalarBaseMult computes r = scalar * G (generator). The scalar must be exactly 32 bytes in big-endian order; it is then reduced modulo the group order n before multiplication. Any other length is rejected outright before any computation begins, and the receiver is left unchanged.
Source
Thrown at src/crypto/internal/fips140/nistec/p256_asm.go:421
p256MovCond(&sum, &double, &sum, pointsEqual)
p256MovCond(&sum, r1, &sum, r2IsInfinity)
p256MovCond(&sum, r2, &sum, r1IsInfinity)
return q.Set(&sum)
}
// Double sets q = p + p, and returns q. The points may overlap.
func (q *P256Point) Double(p *P256Point) *P256Point {
var double P256Point
p256PointDoubleAsm(&double, p)
return q.Set(&double)
}
// ScalarBaseMult sets r = scalar * generator, where scalar is a 32-byte big
// endian value, and returns r. If scalar is not 32 bytes long, ScalarBaseMult
// returns an error and the receiver is unchanged.
func (r *P256Point) ScalarBaseMult(scalar []byte) (*P256Point, error) {
if len(scalar) != 32 {
return nil, errors.New("invalid scalar length")
}
scalarReversed := new(p256OrdElement)
p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))
p256OrdReduce(scalarReversed)
r.p256BaseMult(scalarReversed)
return r, nil
}
// ScalarMult sets r = scalar * q, where scalar is a 32-byte big endian value,
// and returns r. If scalar is not 32 bytes long, ScalarBaseMult returns an
// error and the receiver is unchanged.
func (r *P256Point) ScalarMult(q *P256Point, scalar []byte) (*P256Point, error) {
if len(scalar) != 32 {
return nil, errors.New("invalid scalar length")
}
scalarReversed := new(p256OrdElement)
p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))View on GitHub (pinned to b6b368adc5)
Solutions
- Pad the scalar to exactly 32 bytes using big.Int.FillBytes(make([]byte, 32))
- Validate len(scalar) == 32 before calling ScalarBaseMult
- Avoid using binary.Read with variable-length buffers for scalars
Example fix
// before r, err := point.ScalarBaseMult(k.Bytes()) // k.Bytes() may be < 32 bytes // after scalar := make([]byte, 32) k.FillBytes(scalar) // panics if k doesn't fit; use a size check if needed r, err := point.ScalarBaseMult(scalar)
Defensive patterns
Strategy: validation
Validate before calling
func validateScalar32(b []byte) error {
if len(b) != 32 {
return fmt.Errorf("scalar must be 32 bytes, got %d", len(b))
}
return nil
}
if err := validateScalar32(scalar); err != nil { return err }
r, err := point.ScalarBaseMult(scalar) Try / catch
r, err := point.ScalarBaseMult(scalar)
if err != nil {
return fmt.Errorf("ScalarBaseMult failed: %w", err)
} Prevention
- Use big.Int.FillBytes(make([]byte, 32)) to guarantee fixed-width scalars
- Avoid big.Int.Bytes() which strips leading zeros, producing short slices
- Allocate fixed 32-byte buffers when reading scalars from protocol messages
When it happens
Trigger: Calling r.ScalarBaseMult(scalar) where len(scalar) != 32.
Common situations: Passing a nonce or private key that was encoded with variable-length integer serialization (e.g., ASN.1/DER) instead of fixed-width 32-byte big-endian; using a big.Int.Bytes() result which strips leading zero bytes, producing fewer than 32 bytes for small values.
Related errors
- invalid scalar length
- invalid scalar length
- invalid scalar length
- invalid P256 element encoding
- invalid P256 point encoding
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/3c95e6eb3c1bd6fc.
Report an issue: GitHub.