OpenNHP/opennhp · error

full key verification failed

Error message

full key verification failed

What it means

Raised by UserImpl.VerifyFullKey: it encodes the full key's declared public point, computes the identity-and-parameters hash, scales the master public key, adds it to the declared public key, and compares the result with the public key derived from the full private key. The comparison failed, so the full key is internally inconsistent — the private scalar does not correspond to the declared public point under the current system parameters.

Solutions

  1. Regenerate the user full key from fresh KGC and user partial keys
  2. Ensure the KGC instance and parameters (master public key, curve) are identical during issuance and verification
  3. Confirm the key was not truncated or re-encoded (base64 round-trip) before verification
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at endpoints/kgc/user/user.go:166 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/1054e9190150fea5. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/kgc/user/user.go:166

// the public key generated from the private key. It combines user information with system
// parameters to compute a hash, then uses this hash to scale the master public key.
// The scaled key is added to declared public key and compared against the public key
// generated from the full key's private key. Returns an error if verification fails.
func (u *UserImpl) VerifyFullKey(fullKey *UserFullKey, userId string) error {
	declaredUserPubBytes := fullKey.PubX.Bytes()
	declaredUserPubBytes = append(declaredUserPubBytes, fullKey.PubY.Bytes()...)

	declaredPbkBase64 := base64.StdEncoding.EncodeToString(declaredUserPubBytes)

	userPubX, userPubY, err := u.CalculateFullPublicKey(declaredPbkBase64, userId)
	if err != nil {
		return err
	}

	userPubXFromPrk, userPubYFromPrk := u.Curve.ScalarBaseMult(fullKey.PrivateKey.Bytes())

	if userPubX.Cmp(userPubXFromPrk) != 0 || userPubY.Cmp(userPubYFromPrk) != 0 {
		return fmt.Errorf("full key verification failed")
	}

	return nil
}

// Sign generates an ECDSA signature for the given message using the user's private key.
// It returns the signature components (r, s) and any error encountered during signing.
// The signature is computed using the standard ECDSA algorithm:
// 1. Hashes the message
// 2. Generates a random nonce k
// 3. Computes r = (k*G).x mod N
// 4. Computes s = k⁻¹·(e + r·dA) mod N
// where e is the message hash, dA is the private key, and N is the curve order.
func (u *UserImpl) Sign(prkBase64 string, message string) (r, s *big.Int, err error) {
	u.h.Write([]byte(message))
	msgHash := u.h.Sum(nil)
	u.h.Reset()

View on GitHub (pinned to 6e04ca5ff0)