Skip to content

Commit 01c5fc9

Browse files
authored
Update PROTOCOL.md
1 parent 7a93eb3 commit 01c5fc9

File tree

1 file changed

+85
-7
lines changed

1 file changed

+85
-7
lines changed

PROTOCOL.md

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,15 @@ Server only relays encrypted data between clients, deleting data after delivery.
5252

5353
*All* requests payloads and responses are sent & received in `JSON` format, unless expliclity stated otherwise.
5454

55+
*ALL* code displayed in this documented is purely pseudocode.
56+
5557
## 2. Cryptographic Primitives
5658

5759
### 2.1. Authentication:
5860

5961
Long-term Identity Key: `ML-DSA-87` (`Dilithium5`) signature key pair
6062

61-
Per-contact Verification Keys: `ML-DSA-87` key pair generated for each contact
63+
Per-contact Keys: `ML-DSA-87` key pair generated for each contact
6264

6365
Identity Verification: Custom `Socialist Millionaire Problem` (`SMP`) human-language variant.
6466

@@ -70,6 +72,21 @@ MAC: `HMAC-SHA3-512`
7072

7173
Password-based KDF: `Argon2id` with `Memory_cost` set to `256MB`, `iterations` set to `3` and `salt_length` set to `32`.
7274

75+
### 2.3. Perfect Forward Secrecy:
76+
77+
Rotation key(s): Ephemeral `ML-KEM-1024` (`Kyber1024`) *Key Encapsulation Mechanism* (`KEM`) key pair
78+
79+
Rotation key signing keys: Pre-contact keys (`ML-DSA-87`) to sign Ephemeral keys
80+
81+
### 2.4. Symmetric algorithms
82+
`OTP` (One-Time-Pads): Used for encrypting messages
83+
84+
`AES-256-GCM` (Advanced Encryption Standard with 256-bit key length operating in Galois/Counter mode): Used for encrypting & decrypting local storage.
85+
86+
### 2.5. Asymmetric algorithms
87+
`ML-DSA-87`: Used for authenticating to server and signing ephemeral `PFS` (Perfect Forward Secrecy) keys
88+
89+
`ML-KEM-1024` Used as ephemeral `PFS` keys that are rotated
7390

7491
## 3. Authentication Flow
7592

@@ -104,8 +121,8 @@ Server *verifies* signature:
104121

105122
## 4. SMP verification
106123

107-
ColdWire uses a human-language variant of *Socialist Millionaire Problem* (`SMP`) to verify per-contact keys.
108-
Server does not store any contact relationships; all verification state is local to the clients.
124+
ColdWire uses a human-language variant of *Socialist Millionaire Problem* (`SMP`) to verify `per-contact keys`.
125+
Server does not store any contact relationships, all verification state is local to the clients.
109126

110127

111128
### 4.1. Assumptions:
@@ -133,7 +150,7 @@ POST /smp/initiate
133150

134151
### 4.3. SMP STEP 2 (Bob -> Alice)
135152

136-
`Bob` generates per-contact `ML-DSA-8`7 key pair (`PK_B`, `SK_B`).
153+
`Bob` generates per-contact `ML-DSA-87` key pair (`PK_B`, `SK_B`).
137154

138155
`Bob` reads question, inputs answer.
139156

@@ -201,13 +218,74 @@ Verification security depends on entropy of the answer, `SMP` verification must
201218

202219
Server remains unaware of trust relationships. Server is not aware of verification success. Verification is end-to-end.
203220

204-
The reason we use `per-contact keys` instead of our main identity keys is for **plausible deniability**, because `per-contact keys` are only exchanged *briefly*.
221+
The reason we use `per-contact keys` instead of our main identity keys is for **plausible unlinkability**, because `per-contact keys` are only exchanged *briefly*.
205222

206223
Neither `Alice` nor `Bob` can prove each other's ownership defintively.
207224

208-
This **plausible deniability** only occurs if the server wasn't always malicious. (I.e. the server did not log `Alice` nor `Bob` requests containing their public_key).
225+
This **plausible unlinkability** only occurs if the server wasn't always malicious. (I.e. the server did not log `Alice` nor `Bob` requests containing their public_key).
226+
227+
This **plausible unlinkability** only occurs if the server was compromised *After* SMP verification is complete.
228+
229+
Additionally, this **plausible unlinkability** will be the basis on which we build **plausible deniability** later on with `OTP` pads and `PFS`.
230+
231+
`SMP` verification, if done relatively quickly with an answer with sufficent entropy, provides an *unbreakable mathmatical guarantee of authenticity* and integrity for the verification of the keys (Assuming no hash collisions).
232+
233+
## 5. Perfect Forward Secrecy
234+
Perfect Forward Secrecy (PFS) ensure that if a ML-KEM-1024 keypair was compromised, it does not affect keys before, and after it.
235+
236+
### 5.1. Assumptions
237+
`Alice` wants to generate / rotate ephemeral `ML-KEM-1024` (`Kyber1024`) keys with `Bob`.
238+
`Alice` and `Bob` have verified each other's `per-contact` keys using `SMP`
239+
240+
### 5.2. PFS Exchange
241+
`Alice` generates new ephemeral `ML-KEM-1024` keypair and signs them with her `per-contact` keys for `Bob`
242+
243+
`Alice` then checks if she already has a last `hash chain` state for `Bob`, if not, she generates new `hash chain` initial seed:
244+
```python
245+
hash_chain_seed = random_bytes(32)
246+
```
247+
And saves it in her local state file.
248+
249+
250+
Afterwards, `Alice` computes the next hash in the chain:
251+
```python
252+
next_hash_chain = sha3_512(last_hash_chain_state)
253+
```
254+
255+
Then adds `next_hash_chain` to start of her `Kyber` public key
256+
```python
257+
kyber_publickey_hashchain = next_hash_chain + kyber_public_key
258+
```
259+
260+
And then she signs the result with her `per-contact` (`Dilithium5`) key, and sends:
261+
```json
262+
[POST] /pfs/send_keys
263+
264+
{
265+
"kyber_publickey_hashchain": "kyber_publickey_hashchain base64 encoded",
266+
"kyber_hashchain_signature": "the signature of kyber_publickey_hashchain base64 encoded",
267+
"recipient": "Bob's user ID"
268+
}
269+
```
270+
271+
`Bob` receives, base64 decodes, and verifies the signature, and if valid, he first checks if he has a last `hash chain` state for `Alice`, if not, he sets the first `64 bytes` of `kyber_publickey_hashchain` as the last `hash chain` state.
272+
273+
If he already had a last `hash chain` state for `Alice`, he would compute it, and compare it with the hash chain `Alice` bundled in `kyber_publickey_hashchain`, and only proceeds if valid.
274+
275+
`Bob` then saves `Alice`'s ephemeral `Kyber1024` public key by extracting `1568 bytes` starting after the first `64 bytes` of `kyber_publickey_hashchain`.
276+
277+
Then `Bob` does the same as `Alice` did, generating his own `hash chain` seed if needed, generating new ephemeral `Kyber1024` keypair, and sending it back to `Alice`
278+
279+
`Alice` then does the same verification steps `Bob` did, and saves his key.
280+
281+
Now `Alice` and `Bob` both have each other ephemeral public keys, Have successfully rotated their ephemeral keys.
282+
283+
### 5.3. Security notes
284+
We use `hash chain`s for replay protection.
285+
We also use `per-contact` keys for tampering and spoofing protection.
286+
209287

210-
This **plausible deniability** only occurs if the server was compromised *After* SMP verification is complete.
288+
## 6. Messages
211289

212290

213291
## WORK-IN-PROGRESS

0 commit comments

Comments
 (0)