Proven Identity Key Exchange (PIKE)
Two people who want to transact need each other's public key, and sending it over a channel someone could tamper with is a real risk. This uses a short code shared out of band to confirm the key really came from the right person.
Summary
- Why
- A hosted paymail server could be compromised and hand out a fake public key for a contact without either party noticing.
- What
- BRC-85 (Proven Identity Key Exchange, PIKE) is a paymail-based flow for two wallets to exchange public keys and then confirm, using a shared secret and a one time code shared off channel, that the exchange was not tampered with.
- How
- Two wallets swap contact requests and generated public keys through their paymail servers, then each side derives a shared secret from its own private key and the counterparty's public key, generates a Time-based One Time Password (TOTP) from that secret, and the humans read the codes to each other out of band to…
What this lets you do
- Send a contact request to another paymail address
- Accept or reject an incoming contact request
- Derive a shared secret from a private key and a peer's public key
- Generate and compare a TOTP to confirm a key exchange was not tampered with
- Detect a compromised or malicious paymail server before trusting a key
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
Reference for an AI
Everything an assistant needs to answer questions about BRC-85 accurately, including what it depends on.
The specification
Abstract
Allowing humans to securely exchange public keys using web apis and an off channel sharing of TOTPs.
Motivation
When you use hosted servers for payment output generation there's no way to detect if the host has been compromised and is sharing keys not associated with the intended recipient.
BRFCID
A random ID was generated in order to avoid label collisions in the capability document of a paymail server.
brfcid: 8c4ed5ef8ace
title: Proven Identity Key Exchange (PIKE)
author: Darren Kellenschwiler, Damian Orzepowski
version: 1.0.0
Specification
Roughly speaking you create a shared secret between you and the counterparty using their public key and your private key. If you each do this you can arrive at a shared secret. You then derive a time hashed one time pass code to prove you both have the same value - each sharing the TOTP and validating the counterparty's. Thereafter you can use that public key knowing that it really is that counterparty without fear of MITM attacks.
Implementations
Flow
- Sender wallet: generate random hash
- Sender wallet generate public key from private key and random hash
- Sender wallet is sending "add contact request" to Sender BUX containing: a. contact paymail address b. random hash c. generated public key
- Sender BUX is performing Paymail host discovery (which is described on this page: https://tsc.bsvblockchain.org/standards/paymail/#ServiceDiscovery)
- Sender BUX is performing Paymail capability discovery on Receiver BUX by requesting /.well-known/bsvalias
- If Receiver BUX doesn't contain Proven Identity Key Exchange (PIKE) capability, Sender BUX should return an error to Sender Wallet
- else the Sender BUX is sending a "Add a contact" request to Receiver BUX on the endpoint provided in PIKE capability. This request contains: a. sender paymail address b. random hash c. generated public key
- Receiver BUX stores that "contact" as "waiting" in database
- Receiver BUX is answering to Sender BUX with success
- Sender BUX is storing the "contact" as "waiting"
- Receiver Wallet asks Receiver BUX for "waiting" "contact" to confirm or reject
- Receiver BUX is responding with the list of contacts
- If Receiver Wallet reject the contact, then: a. it is sending rejection request to Receiver BUX b. Receiver BUX is removing the contact from database c. In that case the flow ends
- else: Receiver Wallet generate public key from private key and random hash from the contact
- Receiver Wallet is sending the request for Receiver BUX for accepting the contact with informations: a. paymail address for contact to accept b. generated public key
- Receiver BUX is marking a "contact" as "accepted"
- Receiver BUX is sending the "contact accepted" request to Sender BUX with: a. paymail address of Receiver b. generated public key c. random hash
- Sender BUX is validating random hash, and stores received public key in "contact" and marks it as accepted
- Sender Wallet is asking Sender to confirm contact
- Sender asks Receiver for TOTP
- Receiver checks TOTP for Senders paymail in Receiver Wallet
- Receiver Wallet calculates shared secret based on private key and Senders public key
- Receiver Wallet generates TOTP based on shared secret
- Receiver Wallet sends back TOTP to Receiver
- Receiver is responding with TOTP to Sender
- Sender is providing TOTP to Sender Wallet
- Sender Wallet calculates shared secret based on private key and Receiver public key
- Sender Wallet generates TOTP based on shared secret
- Sender Wallet is comparing received TOTP with generated TOTP. If their match then it marks contact as confirmed.
- Sender Wallet is now generating another TOTP and provides to Sender
- Sender is providing TOTP to Receiver
- Receiver is providing TOTP to Receiver Wallet
- Receiver Wallet is generating TOTP and comparing it with received TOTP If their match then it marks contact as confirmed.
sequenceDiagram
actor Sender
participant Sender Wallet
participant Sender BUX
participant Receiver BUX
participant Receiver Wallet
actor Receiver
Sender->>Sender Wallet: Add receiver as contact
activate Sender Wallet
Sender Wallet->>Sender Wallet: Generate random hash
Sender Wallet->>Sender Wallet: Generate public key from private key and random hash
deactivate Sender Wallet
activate Sender Wallet
Sender Wallet->>Sender BUX: Add contact request
activate Sender BUX
Sender BUX->>Sender BUX: Paymail host discovery
Sender BUX->>Receiver BUX: Paymail capability discovery
activate Receiver BUX
Sender BUX->>Receiver BUX: Add a contact request
Receiver BUX->>Receiver BUX: Store contact as "waiting" in database
Receiver BUX->>Sender BUX: Success
deactivate Receiver BUX
Sender BUX->>Sender BUX: Store contact as "waiting"
Sender BUX->>Sender Wallet: success
deactivate Sender BUX
Sender Wallet->>Sender: Display success
deactivate Sender Wallet
Receiver Wallet->>Receiver BUX: Get "waiting" "contact" to confirm or reject
activate Receiver Wallet
activate Receiver BUX
Receiver BUX->>Receiver Wallet: List of contacts
deactivate Receiver BUX
alt reject contatct
Receiver Wallet->>Receiver BUX: Rejection request
activate Receiver BUX
Receiver BUX->>Receiver BUX: Remove contact from database
deactivate Receiver BUX
else accept contact
Receiver Wallet->>Receiver Wallet: Generate public key from private key and random hash
Receiver Wallet->>Receiver BUX: Accept contact request
activate Receiver BUX
Receiver BUX->>Receiver BUX: Mark contact as "accepted"
Receiver BUX->>Sender BUX: Contact accepted request
Sender BUX->>Sender BUX: Validate random hash and store received public key
Sender BUX->>Receiver BUX: success
Receiver BUX->>Receiver Wallet: success
deactivate Receiver BUX
deactivate Receiver Wallet
end
Sender Wallet->>Sender: Confirm contact?
activate Sender
Sender->>Receiver: TOTP request
activate Receiver
activate Receiver
Receiver->>Receiver Wallet: Check TOTP for Senders paymail
activate Receiver Wallet
Receiver Wallet->>Receiver Wallet: Calculate shared secret based on private key and Senders public key
Receiver Wallet->>Receiver Wallet: Generate TOTP based on shared secret
Receiver Wallet->>Receiver: TOTP
deactivate Receiver Wallet
Receiver->>Sender: TOTP
deactivate Receiver
Sender->>Sender Wallet: TOTP
activate Sender
activate Sender Wallet
Sender Wallet->>Sender Wallet: Calculate shared secret based on private key and Receiver public key
Sender Wallet->>Sender Wallet: Generate TOTP based on shared secret
Sender Wallet->>Sender Wallet: Compare received TOTP with generated TOTP
Sender Wallet->>Sender Wallet: Mark contact as confirmed
Sender Wallet->>Sender Wallet: Generate another TOTP
Sender Wallet->>Sender: TOTP
deactivate Sender Wallet
deactivate Sender
Sender->>Receiver: TOTP
deactivate Sender
activate Receiver
Receiver->>Receiver Wallet: TOTP
activate Receiver Wallet
Receiver Wallet->>Receiver Wallet: Generate TOTP and compare it with received TOTP
Receiver Wallet->>Receiver Wallet: Mark contact as confirmed
deactivate Receiver Wallet
deactivate Receiver
deactivate Receiver