Skip to content

feat: source V2 deviceEncPubKey from a host-owned device key provider #336

Description

@leonardocustodio

Problem

The 0.7.0 signing-host responder fills both V2 handshake fields from the
RFC-0022 SSO encryption identity:

sso_enc_pub_key: identity.encryption_public_key,
device_enc_pub_key: identity.encryption_public_key,

That is not the deployed native ownership contract. deviceEncPubKey is a
separate, persisted, host/device-owned X25519 public key used by multidevice
chat/envelope encryption:

The identity CHAT key, SSO session key, and device encryption key have
different ownership/lifecycles and must not be aliased.

Requested seam

Add a host-owned callback/provider to the signing-host configuration/platform
surface that returns the current device's raw 32-byte X25519 public key. The V2
responder should source Success.device_enc_pub_key only from that provider.

The provider may be async so Android can load encrypted preferences. It must
expose public material only; private key operations remain in the native key
manager.

When the provider is missing or fails, V2 pairing that would advertise
multidevice capability should fail closed with a stable unavailable error. It
must not fall back to the SSO or CHAT key.

Fixed interoperability vector

Use the existing Android RFC 7748 vector as a cross-language fixture:

device private input (test only):
77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a

deviceEncPubKey / raw X25519 public:
8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a

The handshake test should also use a deliberately different ssoEncPubKey
and assert that SCALE encode/decode preserves both exact 32-byte values
independently.

Acceptance criteria

  • device_enc_pub_key comes from the host provider, not an RFC-0022 identity
    derivation.
  • Provider absence/failure is explicit and fail-closed.
  • Rust, iOS, and Android fixtures encode the same raw 32-byte value.
  • A regression test uses distinct SSO/device keys and rejects accidental
    aliasing.
  • No device private key crosses the host boundary or appears in logs/debug
    output.

Brevity is keeping multidevice/device-route chat disabled until this seam
exists; this does not block its current identity-only V1 chat support.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions