OpenNHP/opennhp · error
invalid s value
Error message
invalid s value
What it means
Raised at the end of Sign: after computing s = k⁻¹·(e + r·dA) mod N the scalar s came out zero. Like a zero r, this is an extremely rare random-nonce edge case that would produce an invalid signature, so the operation aborts. The freshly generated nonce k is the effective input at fault.
Solutions
- Retry Sign with a newly generated nonce k
- If it recurs, suspect the random number generator and check the system entropy source
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at endpoints/kgc/user/user.go:213 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/1eec0ff1ca27b8ef.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/kgc/user/user.go:213
if r.Sign() == 0 {
return nil, nil, fmt.Errorf("invalid r value")
}
// k⁻¹
kInv := new(big.Int).ModInverse(k, u.Params().N)
prk, err := base64.StdEncoding.DecodeString(prkBase64)
if err != nil {
return nil, nil, err
}
// s = k⁻¹·(e + r·dA) mod n
rda := new(big.Int).Mul(r, new(big.Int).SetBytes(prk))
ePlusRda := new(big.Int).Add(rda, new(big.Int).SetBytes(msgHash))
s = new(big.Int).Mod(new(big.Int).Mul(ePlusRda, kInv), u.Params().N)
if s.Sign() == 0 {
return nil, nil, fmt.Errorf("invalid s value")
}
return r, s, nil
}
// Verify checks the validity of an ECDSA signature (r, s) for the given message using the user's public key.
// It returns true if the signature is valid, false otherwise, and any error encountered during verification.
// The verification is performed using the standard ECDSA algorithm:
// 1. Hashes the message to get e (same hash function as used in signing)
// 2. Checks that r and s are in the range [1, N-1] where N is the curve order
// 3. Computes w = s⁻¹ mod N
// 4. Computes u1 = e·w mod N and u2 = r·w mod N
// 5. Computes (x1, y1) = u1*G + u2*Q where Q is the public key point
// 6. Verifies that r ≡ x1 mod N
// If any step fails, the signature is considered invalid.
func (u *UserImpl) Verify(declaredPbkBase64, userId, message, sigBase64 string) bool {
n := u.Params().N
View on GitHub (pinned to 6e04ca5ff0)