syntax = "proto3";

option go_package = "github.com/google/trillian/storage/cloudspanner/spannerpb";

package spannerpb;

import "google/protobuf/any.proto";

// State of the Tree.
// Mirrors trillian.TreeState.
enum TreeState {
  UNKNOWN_TREE_STATE = 0;
  ACTIVE = 1;
  FROZEN = 2;
}

// Type of the Tree.
// Mirrors trillian.TreeType.
enum TreeType {
  UNKNOWN = 0;
  LOG = 1;
  MAP = 2;
}

// Defines the preimage protection used for tree leaves / nodes.
// Eg, RFC6962 dictates a 0x00 prefix for leaves and 0x01 for nodes.
// Mirrors trillian.HashStrategy.
enum HashStrategy {
  UNKNOWN_HASH_STRATEGY = 0;
  RFC_6962 = 1;
  TEST_MAP_HASHER = 2;
  OBJECT_RFC6962_SHA256 = 3;
  CONIKS_SHA512_256 = 4;
}

// Supported hash algorithms.
// The numbering space is the same as for TLS, given in RFC 5246 s7.4.1.4.1. See
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18.
// Mirrors trillian.HashAlgorithm.
enum HashAlgorithm {
  // No hash algorithm is used.
  NONE = 0;
  // SHA256 is used.
  SHA256 = 4;
}

// Supported signature algorithms.
// The numbering space is the same as for TLS, given in RFC 5246 s7.4.1.4.1. See
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-16.
// Mirrors trillian.SignatureAlgorithm.
enum SignatureAlgorithm {
  // Anonymous signature scheme.
  ANONYMOUS = 0;
  // RSA signature scheme.
  RSA = 1;
  // ECDSA signature scheme.
  ECDSA = 3;
}

// SignatureCipherSuite defines the set of algorithms used for signing.
enum SignatureCipherSuite {
  // Signature and hash algorithm are unknown / not set.
  UNKNOWN_CIPHER_SUITE = 0;
  // RSA with SHA256.
  RSA_SHA256 = 1;
  // ECDSA with SHA256.
  ECDSA_SHA256 = 2;
}

// Protocol buffer encoding of the TLS DigitallySigned type, from RFC 5246 §4.7.
message DigitallySigned {
  // hash_algorithm contains the hash algorithm used.
  HashAlgorithm hash_algorithm = 1;
  // signature_algorithm contains the signing algorithm used.
  SignatureAlgorithm signature_algorithm = 2;
  // cipher_suite contains the combination of ciphers used for this signature.
  SignatureCipherSuite signature_cipher_suite = 4;
  // signature contains the object signature.
  bytes signature = 3;
}

// LogStorageConfig holds settings which tune the storage implementation for
// a given log tree.
message LogStorageConfig {
  // num_unseq_buckets defines the length of the unsequenced time ring buffer.
  // This value must *never* be reduced for any provisioned tree.
  //
  // This value should be >= 1, and there's probably not much benefit in
  // raising it past about 4.
  // TODO(al): test what the effects of various values are here.
  int64 num_unseq_buckets = 1;

  // num_merkle_buckets defines the number of individual buckets below each
  // unsequenced ring bucket.
  // This value may be changed at any time (so long as you understand the
  // impact it'll have on integration performace!)
  //
  // This value must lie in the range [1..256]
  int64 num_merkle_buckets = 2;
}

// MapStorageConfig holds settings which tune the storage implementation for
// a given map tree.
message MapStorageConfig {
}

// TreeInfo stores information about a Trillian tree.
message TreeInfo {
  // tree_id is the ID of the tree, and is used as a primary key.
  int64 tree_id = 1;

  // key_id identifies the private key associated with this tree.
  int64 key_id = 2;

  // name is a short name for this tree.
  string name = 3;

  // description is a short free form text describing the tree.
  string description = 4;

  // tree_type identifies whether this is a Log or a Map tree.
  TreeType tree_type = 5;

  // tree_state is the state of the tree.
  TreeState tree_state = 8;

  // hash_strategy is the hashing strategy used by the tree.
  HashStrategy hash_strategy = 9;

  // hash_algorithm is the hash algorithm used by the tree.
  HashAlgorithm hash_algorithm = 10;

  // signature_algorithm is the signature algorithm used by the tree.
  SignatureAlgorithm signature_algorithm = 11;

  reserved 12;

  // create_time_nanos is the creation timestamp of the tree, in nanos since
  // epoch.
  int64 create_time_nanos = 13;

  // update_time_nanos is the last update time of the tree, in nanos since
  // epoch.
  int64 update_time_nanos = 14;

  // private_key should be used to generate signatures for this tree.
  google.protobuf.Any private_key = 15;

  // public_key_der should be used to verify signatures produced by this tree.
  // It is the key in DER-encoded PKIX form.
  bytes public_key_der = 16;

  // config contains the log or map specific tree configuration.
  oneof storage_config {
    LogStorageConfig log_storage_config = 6;
    MapStorageConfig map_storage_config = 7;
  }

  // max_root_duration_millis is the interval after which a new signed root is
  // produced even if there have been no submission.  If zero, this behavior is
  // disabled.
  int64 max_root_duration_millis = 17;

  // If true the tree was soft deleted.
  bool deleted = 18;

  // Time of tree deletion, if any.
  int64 delete_time_nanos = 19;
}

// TreeHead is the storage format for Trillian's commitment to a particular
// tree state.
message TreeHead {
  // tree_id identifies the tree this TreeHead is built from.
  int64 tree_id = 1;

  // ts_nanos is the nanosecond resolution timestamp at which the
  // TreeHead was created.
  int64 ts_nanos = 2;

  // tree_size is the number of entries in the tree.
  int64 tree_size = 3;

  // root_hash is the root of the tree.
  bytes root_hash = 4;

  reserved 5;

  // signature holds a digital signature across the data in this TreeHead.
  DigitallySigned signature = 8;

  // tree_revision identifies the revision at which the TreeHead was created.
  int64 tree_revision = 6;

  // metadata is a blob of opaque data specific to the personality layer that an
  // application associates with each TreeHead, and which must be covered by the
  // tree head signature.  Only used for Maps at present.
  google.protobuf.Any metadata = 7;
}
