syntax = "proto3";
package meesign;

service MPC {
  rpc GetServerInfo(ServerInfoRequest) returns (ServerInfo);
  rpc Register(RegistrationRequest) returns (RegistrationResponse);
  rpc Sign(SignRequest) returns (Task);
  rpc Group(GroupRequest) returns (Task);
  rpc GetTask(TaskRequest) returns (Task);
  rpc UpdateTask(TaskUpdate) returns (Resp); // auth required
  rpc DecideTask(TaskDecision) returns (Resp); // auth required
  rpc AcknowledgeTask(TaskAcknowledgement) returns (Resp); // auth required
  rpc GetTasks(TasksRequest) returns (Tasks);
  rpc GetGroups(GroupsRequest) returns (Groups);
  rpc GetDevices(DevicesRequest) returns (Devices);
  rpc Log(LogRequest) returns (Resp); // auth optional
  rpc SubscribeUpdates(SubscribeRequest) returns (stream Task); // auth required
}

message ServerInfoRequest {}

message ServerInfo {
  string version = 1;
}

enum ProtocolType {
  GG18 = 0;
}

enum KeyType {
  SignPDF = 0;
  SignChallenge = 1;
}

enum TaskType {
  GROUP = 0;
  SIGN_PDF = 1;
  SIGN_CHALLENGE = 2;
}

message RegistrationRequest {
  string name = 1;
  bytes csr = 2; // CSR in DER format
}

message RegistrationResponse {
  bytes device_id = 1;
  bytes certificate = 2; // cert in DER format
}

message GroupRequest {
  string name = 1;
  repeated bytes device_ids = 2;
  uint32 threshold = 3;
  ProtocolType protocol = 4;
  KeyType key_type = 5;
}

message Group {
  bytes identifier = 1;
  string name = 2;
  uint32 threshold = 3;
  ProtocolType protocol = 4;
  KeyType key_type = 5;
  repeated bytes device_ids = 6;
}

message DevicesRequest {
  // Protocol
}

message Devices {
  repeated Device devices = 1;
}

message Device {
  bytes identifier = 1;
  string name = 2;
  bytes certificate = 3;
  uint64 last_active = 4;
}

message SignRequest {
  string name = 1;
  bytes group_id = 2;
  bytes data = 3;
}

message TaskRequest {
  bytes task_id = 1;
  optional bytes device_id = 2;
}

message Task {
  bytes id = 1;
  TaskType type = 2;
  enum TaskState {
    CREATED = 0;
    RUNNING = 1;
    FINISHED = 2;
    FAILED = 3;
  }
  TaskState state = 3;
  uint32 round = 4;
  uint32 attempt = 5;
  uint32 accept = 6; // Number of task accepts
  uint32 reject = 7; // Number of task rejects
  optional bytes data = 8; // If present, the task is waiting for recipient's action
  optional bytes request = 9; // Serialized SignRequest or TaskRequest; present only when queried directly
}

message TaskUpdate {
  bytes task = 1;
  bytes data = 2;
  uint32 attempt = 3;
}

message TasksRequest {
  optional bytes device_id = 1;
}

message Tasks {
  repeated Task tasks = 1;
}

message GroupsRequest {
  optional bytes device_id = 1;
}

message Groups {
  repeated Group groups = 1;
}

message Resp {
  string message = 1;
}

message TaskDecision {
  bytes task = 1;
  bool accept = 2;
};

message TaskAcknowledgement {
  bytes task_id = 1;
};

message LogRequest {
  string message = 1;
};

message SubscribeRequest {};

message GG18KeyGenInit {
  uint32 index = 1;
  uint32 parties = 2;
  uint32 threshold = 3;
}

message GG18SignInit {
  repeated uint32 indices = 1;
  uint32 index = 2;
  bytes hash = 3;
}

message GG18Message {
  repeated bytes message = 1;
}