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

  1. Retry Sign with a newly generated nonce k
  2. 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)