canopy-network/canopy · error

all zero shared secret

Error message

all zero shared secret

What it means

Raised in SharedSecret when the X25519 Diffie-Hellman computation yields an all-zero shared secret. This happens with degenerate key inputs (e.g. a low-order or improperly converted Curve25519 public key) and is rejected because an all-zero secret provides zero cryptographic security — it would make encryption trivially breakable.

Source

Thrown at lib/crypto/ecdh.go:34

// SharedSecret function takes ed25519 public and private keys, converts them to Curve25519-compatible keys,
// and performs a Diffie-Hellman-style key exchange with X25519 - meaning both peers compute exact pseudorandom
// bytes from their peersPublicKey and their local private key without transmitting the secret over the wire
func SharedSecret(peerPublicKey, private []byte) ([]byte, error) {
	// convert the peer public key to Curve 25519
	xPub, err := Ed25519PublicKeyToCurve25519(peerPublicKey)
	if err != nil {
		return nil, err
	}
	// convert local private key to Curve 25519
	xPriv := Ed25519PrivateKeyToCurve25519(private)
	// generate a secret from the
	secret, err := curve25519.X25519(xPriv, xPub)
	if err != nil {
		return nil, err
	}
	// ensure the secret isn't an 'all-zero' byte array as this would be a weak or invalid key agreement
	if subtle.ConstantTimeCompare(secret[:], new([32]byte)[:]) == 1 {
		return nil, fmt.Errorf("all zero shared secret")
	}
	// return the diffie hellman secret
	return secret, nil
}

// Ed25519PrivateKeyToCurve25519 hashes the Ed25519 private key seed and extracts the first 32 bytes to form a
// Curve25519 scalar, which is compatible with Curve25519 operations
// This conversion allows the use of a single cryptographic key pair Ed25519 for both signing and key exchange
func Ed25519PrivateKeyToCurve25519(pk ed25519.PrivateKey) []byte {
	h := sha512.New()
	h.Write(pk.Seed())
	out := h.Sum(nil)
	return out[:curve25519.ScalarSize]
}

// Ed25519PublicKeyToCurve25519 interprets the Ed25519 public key as a point on the Edwards25519 curve and converts
// it to a Curve25519 public key in Montgomery form, suitable for X25519 encryption
// This conversion allows the use of a single cryptographic key pair Ed25519 for both signing and key exchange

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Verify the peer's ed25519 public key is valid and correctly converted to Curve25519 before the exchange.
  2. Discard the session and have the peer regenerate its keypair; a zero output indicates a bad peer key.
  3. Clamp private keys as required by X25519 and confirm Ed25519PrivateKeyToCurve25519 conversion is correct.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at lib/crypto/ecdh.go:34 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/f39848bb62358f48. Report an issue: GitHub.