Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

syntax = "proto3";

import "google/protobuf/timestamp.proto";

package zero_art_proto;

enum Role {
  READ = 0; // only read permission
	WRITE = 1; // only write
	OWNERSHIP = 2; // owner
	ADMIN = 3; // administrator
}

// User definition
message User {
  string id = 1; // actor id
  string name = 2; // user name
  bytes public_key = 3; // user identity public key
  bytes picture = 4; // user picture
  Role role = 5; // user role
}

enum ContentAttachmentType {
	IMAGE = 0;
	BINARY = 1;
	VIDEO = 2;
}

message ContentAttachment {
	string id = 1;
	ContentAttachmentType type = 2;
	bytes data = 3;
}

// CRDT payload: could be either incremental change or full document
message CRDTPayload {
	oneof payload {
		bytes incremental_change = 1;
		bytes full_document = 2;
		ContentAttachment media_attachment = 3;
	}
}

// Ordinary chat payload: text, image or file
message ChatPayload {
	oneof payload {
		bytes text = 1;
		bytes img = 2;
		bytes file = 3;
	}
}

message GroupInfo {
  string id = 1; // document id
  string name = 2; // document name
  google.protobuf.Timestamp created = 3; // document creation time
  bytes picture = 4;
  repeated User members = 10; // membership list of document
}

// Protected (could be visible only inside group) group actions
message GroupActionPayload {
  oneof action {
	  GroupInfo init = 1; // group init action
	  GroupInfo invite_member = 2; // invite member action
	  User remove_member = 3; // remove member action
	  User join_group = 4; // join group action
	  User change_user = 5; // user changes they metadata
	  GroupInfo change_group = 6; // group metadata change
	  User leave_group = 7; // member leaves group
	  User finalize_removal = 8; // finalize removal of a member
  }
}

// Payload wrapper
message Payload {
  oneof content {
    CRDTPayload crdt = 1;
    ChatPayload chat = 2;
    
    GroupActionPayload action = 10;
  }
}

// High level group operation visible by SP
message GroupOperation {
	oneof operation {
		bytes init = 1; // public art
		bytes add_member = 2; // branch_changes
		bytes remove_member = 3; // branch_changes
		bytes key_update = 4; // branch_changes
		bytes leave_group = 5; // own_node_index
		bytes drop_group = 10; // challenge
	}
}

message FrameTBS {
    string group_id = 1; // group identifier
    uint64 epoch = 2; // epoch number
    bytes nonce = 3; // random 16b nonce for replay attack protection
    GroupOperation group_operation = 5; // group operation
    bytes protected_payload = 6; // encrypted ProtectedPayload message
}

// main transport layer frame [client] -> [SP]
message Frame {
    FrameTBS frame = 1; // frame data included in proof transcript
    bytes proof = 9; // proof of group_operation with included context of frame
}

// transport layer frame [SP] -> [client]
message SPFrame {
    uint64 seq_num = 1; // sequence number set by SP when Frame received from client
    google.protobuf.Timestamp created = 4; // time SP received frame
    Frame frame = 5;
}

// vector of SPFrames for SP
message SPFrames {
    repeated SPFrame sp_frames = 1;
}

message ProtectedPayloadTBS {
    uint64 seq_num = 1; // internal sequence number of message (might not be equal to SPFrame.seq_num)
    oneof sender {
        string user_id = 2; // user identifier (User.id)
        string leaf_id = 3; // leaf identifier (masking user real identity)
        // null if user wants to post in anonymous mode
    }
    google.protobuf.Timestamp created = 4;
    repeated Payload payload = 5;
}

// protected application layer message(decrypted Frame.protected_payload)
message ProtectedPayload {
    ProtectedPayloadTBS payload = 1;
    bytes signature = 9; // signature of payload using method defined in ProtectedPayloadTBS.sender field
}

// auxiliary protected invite data
message ProtectedInviteData {
    string group_id = 1;
    uint64 epoch = 2;
    bytes stage_key = 3;
}

// Invite for some identified user (Q_id, Q_spk)
message IdentifiedInvite {
    bytes identity_public_key = 1; // identity public key of invitee
    bytes spk_public_key = 2; // spk public key of invitee
}

// Invite for unidentified user
message UnidentifiedInvite {
	bytes private_key = 3; // private key of invitee
}

message InviteTbs {
    oneof invite {
        IdentifiedInvite identified_invite = 1;
        UnidentifiedInvite unidentified_invite = 2;
    }
    bytes protected_invite_data = 9; // encrypted on shared secret ProtectedInviteData
    bytes identity_public_key = 10; // public key of invitor
    bytes ephemeral_public_key = 11; // one-time ephemeral public key of invitor
}

message Invite {
    InviteTbs invite = 1;
    bytes signature = 9; // Sign(identity_public_key, invite.serialize())
}