From 948f4ad6dedb01b44e279204d8eb30a1eda5a330 Mon Sep 17 00:00:00 2001 From: kaichaosun Date: Wed, 22 Jul 2026 13:01:11 +0800 Subject: [PATCH] feat: account and key bundle registry protobuf definition --- gen/rust/src/lib.rs | 39 ++++++++++++++++ .../src/logoschat/store/logoschat.store.rs | 43 ++++++++++++++++++ protos/store.proto | 44 +++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 gen/rust/src/logoschat/store/logoschat.store.rs create mode 100644 protos/store.proto diff --git a/gen/rust/src/lib.rs b/gen/rust/src/lib.rs index dc32686..7a49c9d 100644 --- a/gen/rust/src/lib.rs +++ b/gen/rust/src/lib.rs @@ -31,6 +31,10 @@ pub mod logoschat { pub mod intro { include!("logoschat/intro/logoschat.intro.rs"); } + + pub mod store { + include!("logoschat/store/logoschat.store.rs"); + } } #[cfg(test)] @@ -38,6 +42,7 @@ mod tests { use super::logoschat::{ encryption::{encrypted_payload::Encryption, EncryptedPayload, Plaintext}, invite::InvitePrivateV1, + store::{AccountSubmissionV1, KeyPackageSubmissionV1}, }; use bytes::Bytes; use prost::Message; @@ -79,4 +84,38 @@ mod tests { assert_eq!(decoded.discriminator, "test_discriminator"); } + + /// The store verifies `signature` over the received `payload` bytes, so + /// both must survive a roundtrip byte-for-byte. + #[test] + fn test_keypackage_submission_roundtrip() { + let submission = KeyPackageSubmissionV1 { + device_id: Bytes::from_static(&[7u8; 32]), + payload: Bytes::from_static(b"timestamp-and-keypackage"), + signature: Bytes::from_static(&[9u8; 64]), + }; + + let mut buf = Vec::new(); + submission.encode(&mut buf).expect("Encoding failed"); + + let decoded = KeyPackageSubmissionV1::decode(&buf[..]).expect("Decoding failed"); + + assert_eq!(decoded, submission); + } + + #[test] + fn test_account_submission_roundtrip() { + let submission = AccountSubmissionV1 { + account_pub: Bytes::from_static(&[3u8; 32]), + payload: Bytes::from_static(b"lamport-and-device-keys"), + signature: Bytes::from_static(&[5u8; 64]), + }; + + let mut buf = Vec::new(); + submission.encode(&mut buf).expect("Encoding failed"); + + let decoded = AccountSubmissionV1::decode(&buf[..]).expect("Decoding failed"); + + assert_eq!(decoded, submission); + } } diff --git a/gen/rust/src/logoschat/store/logoschat.store.rs b/gen/rust/src/logoschat/store/logoschat.store.rs new file mode 100644 index 0000000..8d2ce35 --- /dev/null +++ b/gen/rust/src/logoschat/store/logoschat.store.rs @@ -0,0 +1,43 @@ +// @generated +// This file is @generated by prost-build. +// ///////////////////////////////////////////////////////////////////////////// +// Keypackage + Account Store Submissions +// ///////////////////////////////////////////////////////////////////////////// + +// Submissions published over the delivery network for the keypackage + account +// store to pick up by subscription. +// +// In both messages `payload` is opaque to the store: it verifies `signature` +// over the received `payload` bytes under the advertised key, without decoding +// the payload. The signed bytes and the transmitted bytes are identical, so +// every verifier checks the signature over exactly what it received. + +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct KeyPackageSubmissionV1 { + /// 32-byte Ed25519 device verifying key. Both the verification key and the + /// store's lookup key. + #[prost(bytes="bytes", tag="1")] + pub device_id: ::prost::bytes::Bytes, + /// The signed payload: a timestamp header followed by the key package. + #[prost(bytes="bytes", tag="2")] + pub payload: ::prost::bytes::Bytes, + /// 64-byte Ed25519 signature over `payload`, made by `device_id`'s key. + /// Proof-of-possession: only that key's holder can publish under it. + #[prost(bytes="bytes", tag="3")] + pub signature: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct AccountSubmissionV1 { + /// 32-byte Ed25519 account verifying key. Both the verification key and the + /// store's lookup key. + #[prost(bytes="bytes", tag="1")] + pub account_pub: ::prost::bytes::Bytes, + /// The signed device-list payload: a lamport-timestamped list of device + /// verifying keys, so consumers can detect stale bundles. + #[prost(bytes="bytes", tag="2")] + pub payload: ::prost::bytes::Bytes, + /// 64-byte Ed25519 signature over `payload`, made by the account key. + #[prost(bytes="bytes", tag="3")] + pub signature: ::prost::bytes::Bytes, +} +// @@protoc_insertion_point(module) diff --git a/protos/store.proto b/protos/store.proto new file mode 100644 index 0000000..533fe5d --- /dev/null +++ b/protos/store.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; + +package logoschat.store; + + +/////////////////////////////////////////////////////////////////////////////// +// Keypackage + Account Store Submissions +/////////////////////////////////////////////////////////////////////////////// + +// Submissions published over the delivery network for the keypackage + account +// store to pick up by subscription. +// +// In both messages `payload` is opaque to the store: it verifies `signature` +// over the received `payload` bytes under the advertised key, without decoding +// the payload. The signed bytes and the transmitted bytes are identical, so +// every verifier checks the signature over exactly what it received. + +message KeyPackageSubmissionV1 { + + // 32-byte Ed25519 device verifying key. Both the verification key and the + // store's lookup key. + bytes device_id = 1; + + // The signed payload: a timestamp header followed by the key package. + bytes payload = 2; + + // 64-byte Ed25519 signature over `payload`, made by `device_id`'s key. + // Proof-of-possession: only that key's holder can publish under it. + bytes signature = 3; +} + +message AccountSubmissionV1 { + + // 32-byte Ed25519 account verifying key. Both the verification key and the + // store's lookup key. + bytes account_pub = 1; + + // The signed device-list payload: a lamport-timestamped list of device + // verifying keys, so consumers can detect stale bundles. + bytes payload = 2; + + // 64-byte Ed25519 signature over `payload`, made by the account key. + bytes signature = 3; +}