v0.0.13: Sender Keys for efficient group encryption
Protocol (sender_keys.rs): - SenderKey: symmetric key with chain ratchet (forward secrecy per chain) - generate(), rotate(), encrypt(), decrypt() - SenderKeyDistribution: share key via 1:1 encrypted channel - SenderKeyMessage: encrypted group message (O(1) instead of O(N)) - Chain key ratchets forward on each message (HKDF) - Generation counter for key rotation tracking - 4 tests: basic, multi-message, rotation, old-key rejection WireMessage: - GroupSenderKey variant: encrypted group message - SenderKeyDistribution variant: key sharing Server: dedup handles new variants. CLI TUI + recv: stub handlers for new message types. 23/23 protocol tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -123,6 +123,12 @@ pub async fn run(server_url: &str, identity: &IdentityKeyPair) -> Result<()> {
|
||||
Ok(WireMessage::FileChunk { filename, chunk_index, total_chunks, sender_fingerprint, .. }) => {
|
||||
println!(" [file chunk] {} chunk {}/{} of '{}'", sender_fingerprint, chunk_index + 1, total_chunks, filename);
|
||||
}
|
||||
Ok(WireMessage::GroupSenderKey { sender_fingerprint, group_name, .. }) => {
|
||||
println!(" [group] {} sent to #{}", sender_fingerprint, group_name);
|
||||
}
|
||||
Ok(WireMessage::SenderKeyDistribution { sender_fingerprint, group_name, .. }) => {
|
||||
println!(" [sender key] received key from {} for #{}", sender_fingerprint, group_name);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!(" failed to deserialize message: {}", e);
|
||||
}
|
||||
|
||||
@@ -1340,6 +1340,38 @@ fn process_wire_message(
|
||||
// Received chunk without header — ignore
|
||||
}
|
||||
}
|
||||
WireMessage::GroupSenderKey {
|
||||
id: _,
|
||||
sender_fingerprint,
|
||||
group_name,
|
||||
generation: _,
|
||||
counter: _,
|
||||
ciphertext: _,
|
||||
} => {
|
||||
// TODO: decrypt with stored sender key for this sender+group
|
||||
messages.lock().unwrap().push(ChatLine {
|
||||
sender: sender_fingerprint[..sender_fingerprint.len().min(12)].to_string(),
|
||||
text: format!("[group #{} sender-key message — key setup needed]", group_name),
|
||||
is_system: false,
|
||||
is_self: false,
|
||||
message_id: None,
|
||||
});
|
||||
}
|
||||
WireMessage::SenderKeyDistribution {
|
||||
sender_fingerprint,
|
||||
group_name,
|
||||
chain_key: _,
|
||||
generation: _,
|
||||
} => {
|
||||
// TODO: store this sender key for future group decryption
|
||||
messages.lock().unwrap().push(ChatLine {
|
||||
sender: "system".into(),
|
||||
text: format!("Received sender key from {} for #{}", &sender_fingerprint[..sender_fingerprint.len().min(12)], group_name),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user