You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: STRANDLOCK_PROTOCOL.md
+46-41Lines changed: 46 additions & 41 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,48 +29,48 @@ If Both `KEMs`, and `xChaCha20Poly1305` are compromised in future, as long as `O
29
29
30
30
For clarity, the following terms are used consistently throughout this specification:
31
31
32
-
#####Request
32
+
#### Request
33
33
A generic protocol message sent from one party to another. A Request is not bound to `HTTP` or any specific transport mechanism; it may be carried over `TCP`, `UDP`, `sockets`, `pipes`, or any `communication medium`.
34
34
35
-
#####Response
35
+
#### Response
36
36
The reply to a Request, carrying the necessary protocol data to complete or continue a Strandlock operation.
37
37
We use term "Response" and "Request" interchangably. A response is a request.
38
38
39
-
#####Session
39
+
#### Session
40
40
A logical state maintained between two parties that tracks shared secrets, nonces, and protocol progress. A session may span multiple Requests and Responses. Only one session is allowed per-contact. This protocol does not (and will not) support multi-devices, nor multi-session per same contact.
41
41
42
-
#####Strand Nonce
42
+
#### Strand Nonce
43
43
A cryptographically secure random value used for entropy injection, whitening, and rotation. Strand nonces are exclusively used for `xChaCha20Poly1305` wrapping encryption. Every request contains the next nonce that will be used for the next request. Such nonces we call "Strand Nonces". Alice and Bob both save each other strand nonces.
44
44
45
-
#####Strand Key
45
+
#### Strand Key
46
46
Any key material derived, rotated, or combined from multiple primitives within Strandlock. Strand Key is fed to `xChaCha20Poly1305` to "wrap encrypt" everything. Applies to PFS, MSGS requests and responses, but not SMP. SMP process uses a temporary key simply dubbed "Temporary xChaCha key" or "SMP key"
47
47
48
48
49
-
#####SMP (Socialist Millionaire Protocol)
49
+
#### SMP (Socialist Millionaire Protocol)
50
50
An authentication mechanism used to confirm shared knowledge between two parties without revealing the secret itself.
51
51
It does not refer to vanilla SMP, but refers to Off-the-record messaging-style `SMP`.
52
52
53
-
#####OTP Batch
53
+
#### OTP Batch
54
54
A collection of one-time pad material derived from multiple primitives and signed before being used for message encryption.
55
55
56
56
### 2. General Protocol Features
57
57
58
-
#####Request Types:
58
+
#### Request Types:
59
59
Every request includes a message type identifier, which may be visible only in the very first `SMP` stage request. For all other requests that come afterwards, the type is encrypted within the payload.
60
60
61
-
#####Nonces:
61
+
#### Nonces:
62
62
Each request contains a `24-bytes nonce` immediately following the `type` field. These `nonces` are meant to be used for the next request to prevent metadata leakage, replay attacks, and on the small off-chance that a randomly generated nonce repeats twice, network adversaries wouldn't know a nonce reuse occured.
63
63
64
64
Additionally, while all public security proofs of `xChaCha20Poly1305` assume nonce is public, encrypting and or hiding the `nonce` might actually "future-proof" `xChaCha20Poly1305` against potentinal future attacks, leaving only open window through pure dumb brute-forcing of `32 bytes` key space.
65
65
66
-
#####Encryption:
66
+
#### Encryption:
67
67
All payloads are encrypted with `XChaCha20Poly1305`, except for the `SMP` initiation stage.
68
68
69
-
#####Human Verification:
69
+
#### Human Verification:
70
70
`SMP` enforces a human-verifiable question-and-answer process before any chat communication. This prevents "trust on first use"-style attacks that plagues other encrypted protocols.
71
71
72
-
### 3. SMP (Socialist Millionaire Protocol)
73
-
#####3.1 Initialization (Alice -> Bob)
72
+
### 3. Socialist Millionaire Protocol (`SMP`)
73
+
#### 3.1 Initialization (`Alice` -> `Bob`)
74
74
75
75
`Alice` selects an `SMP` question and answer and stores them locally.
76
76
@@ -82,7 +82,7 @@ All payloads are encrypted with `XChaCha20Poly1305`, except for the `SMP` initia
82
82
83
83
The `payload` is prefixed with `SMP_TYPE = 0x00`.
84
84
85
-
#####3.2 Response (Bob -> Alice)
85
+
#### 3.2 Initialization response (`Bob`)
86
86
87
87
`Bob` generates a shared secret using `Alice’s``ML-KEM-1024` public key (this is called temporary xchacha key, only used for `SMP` encryption).
`Bob` saves `Alice` to his contact list locally, however `Bob`**must** flag `Alice` as `unverified` or `pending_verification`.
108
108
`Bob` also stores all `nonces` and the `temporary XChaCha key` for this `SMP` session.
109
109
110
-
#####3.3 Proof 1 (`Alice's` proof of `Bob's` public-key)
110
+
#### 3.3 Proof 1 (`Alice's` proof of `Bob's` public-key)
111
111
112
112
`Alice` decapsulates the KEM ciphertext, derives shared secret to get the "temporary xChaCha key", then she decrypts the `XChaCha` ciphertext using the `temporary xChaCha key`.
`Bob` then saves the new keys, and marks `Alice` as `SMP` verified.
202
202
203
-
#####3.5 Final Verification (`Alice`):
203
+
#### 3.5 Final Verification (`Alice`):
204
204
205
205
`Alice` decrypts `Bob’s``SMP` payload and verifies `Bob’s` proof.
206
206
@@ -210,7 +210,7 @@ If valid, she applies the same `XOR` transformation to the `Strand Keys`, and sa
210
210
211
211
`Alice` sends her first PFS keys.
212
212
213
-
#####3.6. Notes on SMP:
213
+
#### 3.6. Notes on SMP:
214
214
215
215
Step 1: No encryption
216
216
@@ -225,6 +225,8 @@ Do not confuse `Strand Nonces` with `SMP Nonces`, the latter is only used for SM
225
225
226
226
The security of the `SMP` process depends entirely on the entropy of the user-provided `answer`, we use extreme `Argon2id` parameters to protect against a *"god-like"* adversary with virtually *unlimited* computing power, and we salt the answer to prevent *Rainbow-style* attacks. **However**, if `answer` is *low-entropy*, even such measures cannot completely prevent the cracking of the answer.
227
227
228
+
Answers don't have to be uncrackable forever, just uncrackable for a reasonable duration (minimum 1 week to months), our extreme `Argon2id` parameters achieve just that.
229
+
228
230
We highly recommend implementations to only allow user to set a `8+ character` answer, and to check the entropy of provided answer (is all lowercase, is all uppercase, is only digits, etc), and to warn (or prevent) the user from continuing.
229
231
230
232
Even though the `question` is encrypted, an active *Man-in-the-middle* adversary **can still retrieve it**. The verification would fail, but the adversary would have the `question` plaintext.
@@ -234,45 +236,48 @@ The question **must not** contain any senstive data. And it must not contain any
234
236
Implementations **must** check `answer` and `question` in initation stage, to ensure neither contain the other.
235
237
236
238
237
-
### 4. Perfect Forward Secrecy (PFS)
238
-
##### 4.1 Key Rotation
239
-
240
-
Alice checks if a saved ALICE_KEYS_HASH_CHAIN exists:
241
-
242
-
If not, she generates a new hash chain of size KEYS_HASH_CHAIN_LEN.
243
-
244
-
Otherwise, she advances the hash chain using SHA3-512.
239
+
### 4. Perfect Forward Secrecy (`PFS`)
240
+
#### 4.1 Key Rotation (`Alice`)
245
241
246
-
Alice generates new ML-KEM-1024 key pairs.
242
+
`Alice` checks if a saved `ALICE_KEYS_HASH_CHAIN` exists:
243
+
- If not, she generates a new hash chain of size `KEYS_HASH_CHAIN_LEN` (default `64 bytes`).
244
+
- Otherwise, she advances the hash chain by hashing the previous hash chain with `SHA3-512`, then output truncating to `KEYS_HASH_CHAIN_LEN`.
247
245
248
-
Alice checks if McEliece keys need rotation (after 10 OTP batches or if never sent before).
246
+
`Alice` generates new `ML-KEM-1024` key pairs.
249
247
250
-
Alice constructs publickeys_hashchain:
248
+
`Alice` checks if `Classic-McEliece` keys need rotation (by checking some `rotation_counter` and when it reaches a specific number, say `10`, it means its time to rotate, or, if `Alice` never sent any keys before).
`Alice` then encrypts the `PFS_PAYLOAD`, with `xChaCha20Poly1305` using her `ALICE_STRAND_KEY` key, and using previous `ALICE_NEXT_STRAND_NONCE` as nonce.
261
265
266
+
#### 4.2 Receiving PFS Keys (`Bob`)
262
267
263
-
Encrypted using previous ALICE_NEXT_STRAND_NONCE.
268
+
`Bob` decrypts strand wrapper encryption with `xChaCha20Poly1305`using `ALICE_STRAND_KEY` as key, and `ALICE_NEXT_STRAND_NONCE` as nonce.
264
269
265
-
4.2 Receiving PFS Keys (Bob)
270
+
`Bob` updates `ALICE_NEXT_STRAND_NONCE` with `ALICE_NEW_STRAND_NONCE`.
266
271
267
-
Bob decrypts using ALICE_STRAND_KEY and ALICE_NEXT_STRAND_NONCE.
272
+
`Bob`*verifies* hash chain and signature using `Alice` signing public-key.
268
273
269
-
Bob updates ALICE_NEXT_STRAND_NONCE.
274
+
`Bob` determines which keys were sent (`ML-KEM-1024` only or `ML-KEM-1024` + `Classic-McEliece-8192128`), and saves them.
270
275
271
-
Bob verifies hash chain and signature.
276
+
`Bob` then checks if he already sent keys to `Alice`, if he never sent any keys before to `Alice`, he performs the `4.1. Key Rotation` as well.
272
277
273
-
Bob determines which keys were sent (ML-KEM-1024 only or ML-KEM + McEliece) and saves them.
278
+
#### 4.3. PFS Notes:
279
+
Even though the use of hash-chains and signatures may appear redundant here, as we already wrap everything in `xChaCha20Poly1305`, and we encrypt its nonce, which serves as a replay protection, and tamper protection, the use of hash-chains here ensures that even if `xChaCha20Poly1305` is broken, PFS keys cannot be replayed, nor tampered with.
274
280
275
-
If Bob has no new keys to send, he generates them similarly.
0 commit comments