golang/go · error
invalid scalar length
Error message
invalid scalar length
What it means
P521Point.ScalarBaseMult computes p = scalar * B (canonical P-521 generator). The scalar must be exactly p521ElementLength bytes (66 bytes) in big-endian order. P-521 field and scalar elements are 521 bits, which requires 66 bytes (with 7 padding bits in the most significant byte). Any other length is rejected.
Source
Thrown at src/crypto/internal/fips140/nistec/p521.go:414
for i := 0; i < p521ElementLength*2; i++ {
p521GeneratorTable[i][0] = NewP521Point().Set(base)
for j := 1; j < 15; j++ {
p521GeneratorTable[i][j] = NewP521Point().Add(p521GeneratorTable[i][j-1], base)
}
base.Double(base)
base.Double(base)
base.Double(base)
base.Double(base)
}
})
return p521GeneratorTable
}
// ScalarBaseMult sets p = scalar * B, where B is the canonical generator, and
// returns p.
func (p *P521Point) ScalarBaseMult(scalar []byte) (*P521Point, error) {
if len(scalar) != p521ElementLength {
return nil, errors.New("invalid scalar length")
}
tables := p.generatorTable()
// This is also a scalar multiplication with a four-bit window like in
// ScalarMult, but in this case the doublings are precomputed. The value
// [windowValue]G added at iteration k would normally get doubled
// (totIterations-k)×4 times, but with a larger precomputation we can
// instead add [2^((totIterations-k)×4)][windowValue]G and avoid the
// doublings between iterations.
t := NewP521Point()
p.Set(NewP521Point())
tableIndex := len(tables) - 1
for _, byte := range scalar {
windowValue := byte >> 4
tables[tableIndex].Select(t, windowValue)
p.Add(p, t)
tableIndex--
View on GitHub (pinned to b6b368adc5)
Solutions
- Pad the scalar to exactly 66 bytes using big.Int.FillBytes(make([]byte, 66))
- Validate len(scalar) == 66 before calling ScalarBaseMult
- Double-check that you are using the correct curve — P-521 scalars are 66 bytes, not 32
Example fix
// before p, err := point.ScalarBaseMult(k.Bytes()) // likely < 66 bytes // after scalar := make([]byte, 66) k.FillBytes(scalar) p, err := point.ScalarBaseMult(scalar)
Defensive patterns
Strategy: validation
Validate before calling
const p521ScalarLen = 66
func validateP521Scalar(b []byte) error {
if len(b) != p521ScalarLen {
return fmt.Errorf("P-521 scalar must be %d bytes, got %d", p521ScalarLen, len(b))
}
return nil
}
if err := validateP521Scalar(scalar); err != nil { return err }
p, err := point.ScalarBaseMult(scalar) Try / catch
p, err := point.ScalarBaseMult(scalar)
if err != nil {
return fmt.Errorf("P-521 ScalarBaseMult failed: %w", err)
} Prevention
- P-521 scalars are 66 bytes (521 bits), not 32 — double-check the curve
- Use big.Int.FillBytes(make([]byte, 66)) for fixed-width encoding
- Keep curve selection centralized in configuration to avoid P-256/P-521 confusion
When it happens
Trigger: Calling p.ScalarBaseMult(scalar) where len(scalar) != 66.
Common situations: Using a 64-byte (512-bit) or 32-byte scalar by mistake; encoding a P-521 private key with big.Int.Bytes() which strips leading zero bytes; passing a P-256-sized scalar to a P-521 operation due to curve confusion.
Related errors
- invalid scalar length
- invalid scalar length
- invalid scalar length
- mlkem: invalid encapsulation key length
- mlkem: invalid ciphertext length
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/c08aab66b4c26909.
Report an issue: GitHub.