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.
Problem
The 0.7.0 signing-host responder fills both V2 handshake fields from the
RFC-0022 SSO encryption identity:
That is not the deployed native ownership contract.
deviceEncPubKeyis aseparate, persisted, host/device-owned X25519 public key used by multidevice
chat/envelope encryption:
DeviceEncryptionKeyManager.getPublicKey()and encodesit in
HandshakeSuccessV2: payload factory,persisted key manager.
OurDeviceKeypairProvider.publicKey()and encodesit in
HandshakeSuccessPayload: handshake use case,persisted provider.
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_keyonly 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:
The handshake test should also use a deliberately different
ssoEncPubKeyand assert that SCALE encode/decode preserves both exact 32-byte values
independently.
Acceptance criteria
device_enc_pub_keycomes from the host provider, not an RFC-0022 identityderivation.
aliasing.
output.
Brevity is keeping multidevice/device-route chat disabled until this seam
exists; this does not block its current identity-only V1 chat support.