add protocol message protobuf

This commit is contained in:
Pavel Prichodko 2022-06-03 11:15:11 +02:00 committed by Felicio Mununga
parent 1df5721654
commit 4f2581e462
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
2 changed files with 311 additions and 0 deletions

View File

@ -0,0 +1,88 @@
syntax = "proto3";
message SignedPreKey {
bytes signed_pre_key = 1;
uint32 version = 2;
uint32 protocol_version = 3;
}
// X3DH prekey bundle
message Bundle {
// Identity key
bytes identity = 1;
// Installation id
map<string,SignedPreKey> signed_pre_keys = 2;
// Prekey signature
bytes signature = 4;
// When the bundle was created locally
int64 timestamp = 5;
}
message BundleContainer {
reserved 3;
// X3DH prekey bundle
Bundle bundle = 1;
// Private signed prekey
bytes private_signed_pre_key = 2;
}
message DRHeader {
// Current ratchet public key
bytes key = 1;
// Number of the message in the sending chain
uint32 n = 2;
// Length of the previous sending chain
uint32 pn = 3;
// Bundle ID
bytes id = 4;
}
message DHHeader {
// Compressed ephemeral public key
bytes key = 1;
}
message X3DHHeader {
reserved 3;
// Ephemeral key used
bytes key = 1;
// Used bundle's signed prekey
bytes id = 4;
}
// Hash Ratchet Header
message HRHeader {
// community key ID
uint32 key_id = 1;
// Community message number for this key_id
uint32 seq_no = 2;
// Community ID
string group_id = 3;
}
// Direct message value
message EncryptedMessageProtocol {
X3DHHeader X3DH_header = 1;
DRHeader DR_header = 2;
DHHeader DH_header = 101;
HRHeader HR_header = 102;
// Encrypted payload
bytes payload = 3;
}
// Top-level protocol message
message ProtocolMessage {
// The device id of the sender
string installation_id = 2;
// List of bundles
repeated Bundle bundles = 3;
// One to one message, encrypted, indexed by installation_id
// TODO map here is redundant in case of community messages
map<string,EncryptedMessageProtocol> encrypted_message = 101;
// Public chats, not encrypted
bytes public_message = 102;
}

View File

@ -0,0 +1,223 @@
/* eslint-disable import/export */
/* eslint-disable @typescript-eslint/no-namespace */
import { encodeMessage, decodeMessage, message, bytes, uint32, int64, string } from 'protons-runtime'
import type { Codec } from 'protons-runtime'
export interface SignedPreKey {
signedPreKey: Uint8Array
version: number
protocolVersion: number
}
export namespace SignedPreKey {
export const codec = (): Codec<SignedPreKey> => {
return message<SignedPreKey>({
1: { name: 'signedPreKey', codec: bytes },
2: { name: 'version', codec: uint32 },
3: { name: 'protocolVersion', codec: uint32 }
})
}
export const encode = (obj: SignedPreKey): Uint8Array => {
return encodeMessage(obj, SignedPreKey.codec())
}
export const decode = (buf: Uint8Array): SignedPreKey => {
return decodeMessage(buf, SignedPreKey.codec())
}
}
export interface Bundle {
identity: Uint8Array
signedPreKeys: SignedPreKey
signature: Uint8Array
timestamp: bigint
}
export namespace Bundle {
export const codec = (): Codec<Bundle> => {
return message<Bundle>({
1: { name: 'identity', codec: bytes },
2: { name: 'signedPreKeys', codec: SignedPreKey.codec() },
4: { name: 'signature', codec: bytes },
5: { name: 'timestamp', codec: int64 }
})
}
export const encode = (obj: Bundle): Uint8Array => {
return encodeMessage(obj, Bundle.codec())
}
export const decode = (buf: Uint8Array): Bundle => {
return decodeMessage(buf, Bundle.codec())
}
}
export interface BundleContainer {
bundle: Bundle
privateSignedPreKey: Uint8Array
}
export namespace BundleContainer {
export const codec = (): Codec<BundleContainer> => {
return message<BundleContainer>({
1: { name: 'bundle', codec: Bundle.codec() },
2: { name: 'privateSignedPreKey', codec: bytes }
})
}
export const encode = (obj: BundleContainer): Uint8Array => {
return encodeMessage(obj, BundleContainer.codec())
}
export const decode = (buf: Uint8Array): BundleContainer => {
return decodeMessage(buf, BundleContainer.codec())
}
}
export interface DRHeader {
key: Uint8Array
n: number
pn: number
id: Uint8Array
}
export namespace DRHeader {
export const codec = (): Codec<DRHeader> => {
return message<DRHeader>({
1: { name: 'key', codec: bytes },
2: { name: 'n', codec: uint32 },
3: { name: 'pn', codec: uint32 },
4: { name: 'id', codec: bytes }
})
}
export const encode = (obj: DRHeader): Uint8Array => {
return encodeMessage(obj, DRHeader.codec())
}
export const decode = (buf: Uint8Array): DRHeader => {
return decodeMessage(buf, DRHeader.codec())
}
}
export interface DHHeader {
key: Uint8Array
}
export namespace DHHeader {
export const codec = (): Codec<DHHeader> => {
return message<DHHeader>({
1: { name: 'key', codec: bytes }
})
}
export const encode = (obj: DHHeader): Uint8Array => {
return encodeMessage(obj, DHHeader.codec())
}
export const decode = (buf: Uint8Array): DHHeader => {
return decodeMessage(buf, DHHeader.codec())
}
}
export interface X3DHHeader {
key: Uint8Array
id: Uint8Array
}
export namespace X3DHHeader {
export const codec = (): Codec<X3DHHeader> => {
return message<X3DHHeader>({
1: { name: 'key', codec: bytes },
4: { name: 'id', codec: bytes }
})
}
export const encode = (obj: X3DHHeader): Uint8Array => {
return encodeMessage(obj, X3DHHeader.codec())
}
export const decode = (buf: Uint8Array): X3DHHeader => {
return decodeMessage(buf, X3DHHeader.codec())
}
}
export interface HRHeader {
keyId: number
seqNo: number
groupId: string
}
export namespace HRHeader {
export const codec = (): Codec<HRHeader> => {
return message<HRHeader>({
1: { name: 'keyId', codec: uint32 },
2: { name: 'seqNo', codec: uint32 },
3: { name: 'groupId', codec: string }
})
}
export const encode = (obj: HRHeader): Uint8Array => {
return encodeMessage(obj, HRHeader.codec())
}
export const decode = (buf: Uint8Array): HRHeader => {
return decodeMessage(buf, HRHeader.codec())
}
}
export interface EncryptedMessageProtocol {
X3DHHeader: X3DHHeader
DRHeader: DRHeader
DHHeader: DHHeader
HRHeader: HRHeader
payload: Uint8Array
}
export namespace EncryptedMessageProtocol {
export const codec = (): Codec<EncryptedMessageProtocol> => {
return message<EncryptedMessageProtocol>({
1: { name: 'X3DHHeader', codec: X3DHHeader.codec() },
2: { name: 'DRHeader', codec: DRHeader.codec() },
101: { name: 'DHHeader', codec: DHHeader.codec() },
102: { name: 'HRHeader', codec: HRHeader.codec() },
3: { name: 'payload', codec: bytes }
})
}
export const encode = (obj: EncryptedMessageProtocol): Uint8Array => {
return encodeMessage(obj, EncryptedMessageProtocol.codec())
}
export const decode = (buf: Uint8Array): EncryptedMessageProtocol => {
return decodeMessage(buf, EncryptedMessageProtocol.codec())
}
}
export interface ProtocolMessage {
installationId: string
bundles: Bundle[]
encryptedMessage: EncryptedMessageProtocol
publicMessage: Uint8Array
}
export namespace ProtocolMessage {
export const codec = (): Codec<ProtocolMessage> => {
return message<ProtocolMessage>({
2: { name: 'installationId', codec: string },
3: { name: 'bundles', codec: Bundle.codec(), repeats: true },
101: { name: 'encryptedMessage', codec: EncryptedMessageProtocol.codec() },
102: { name: 'publicMessage', codec: bytes }
})
}
export const encode = (obj: ProtocolMessage): Uint8Array => {
return encodeMessage(obj, ProtocolMessage.codec())
}
export const decode = (buf: Uint8Array): ProtocolMessage => {
return decodeMessage(buf, ProtocolMessage.codec())
}
}