derecalliance / protobufs

The format of DeRec messages.
Apache License 2.0
2 stars 0 forks source link

Helper needs only SecretId, version and share bytes #15

Open jorabin opened 8 months ago

jorabin commented 8 months ago

Currently (0.9) the protobufs for StoreShareRequestMessage involves a whole lot of fields defining the nature of the share, to allow for reconstruction. A helper does not need to know this information and it's potentially undesirable that it should know which share of a secret it is holding.

It's also desirable that a helper should be able to store opaque bytes strings howsoever created.

In addition, in order to allow for a separation of concerns of cryptography and processing of a secret into shares for distribution e.g. by an interface such as that proposed in https://github.com/derecalliance/cryptography/issues/2#issuecomment-1812933026 propose to refactor the StoreShareRequestMessage as follows:

message StoreShareRequestMessage {
  /*
   * The bytes that the sharer is requesting that the helper stores. A helper does not need to know the details of 
   * the algorithm used to construct the share and MUST treat the share as an opaque byte string.
   */
   bytes share = 4;

  /*
   * An identifier for the algorithm used to create the share bytes (field 4). For interoperability purposes there 
   * may be a registry of ids and corresponding protobuf definitions of the contents of the share, if it is desired that 
   * different sharer implementations are able to reconstruct secrets that have been shared by other implementations.
   */
   bytes shareAlgorithm = 5;

  /*
   * The version number of the share (the secretId is given in the containing DeRecMessage)
   */
   int32 version = 6;

  /*
  * All versions that the helper must retain (including this new one).
  * The helper should delete all other versions outside this list.
  */
  repeated int32 keepList = 3;
}

The GetShareResponse message is correspondingly refactored as follows:

message GetShareResponseMessage {
  /* the success or failure of processing the request */
  Result result = 1;

  /* the bytes of the share */
  bytes share = 3;

  /* an identifier for the algorithm used to create the share bytes */
  bytes shareAlgorithm = 4;
}
jorabin commented 8 months ago

I also think there is a strong argument for including "description" so that when listing secrets a human would have some chance of knowing what they are for.

lbaird commented 8 months ago

This information is needed for reconstruction. And we have agreed that it should be possible for a secret created by one piece of software to be recovered by another. So things like the commitment can't be hidden from the helper, since we don't have any key to encrypt them with to hide them. So we won't be able to have more privacy than the current protobufs provide. But we can add more flexibility.

It sounds like the suggestion is that we should also have the ability of a sharer to do less than this, if they want to. It's ok to add that feature, as long as we have comments that discourage apps from doing it (because they become incompatible when recovering). If we wanted to do that, the bytes of the share should come from serializing the CommittedDeRecShare. That could be the algorithm 0, and should be recommended to be supported.

This change slows down processing on both ends, because it means an additional serialization and parsing. It would also expand the message size, because we would need to add the version number outside those bytes that is also stored inside the bytes.

If a description is added, it should be inside the secret itself, to ensure that only the sharer is able to see it. The helper should see only a share of it, which is opaque, so they would not learn anything about the secret.

With all the above changes, the storeshare.proto would continue to have the CommittedDeRecShare and DeRecShare and Secret messages unchanged, and the StoreShareRequest message would be changed to the following:

message StoreShareRequestMessage {
  /*
   * The bytes that the sharer is requesting that the helper stores. A helper does not need to know the details of 
   * the algorithm used to construct the share and MUST treat the share as an opaque byte string.
   */
   bytes share = 1;

  /*
   * An identifier for the algorithm used to create the share bytes (field 4). For interoperability purposes there 
   * may be a registry of ids and corresponding protobuf definitions of the contents of the share, if it is desired that 
   * different sharer implementations are able to reconstruct secrets that have been shared by other implementations.
   * Share algorithm number 0 is the creation of the `share` bytes by serializing the 
   * protobuf message `CommittedDeRecShare`. It is recommended that implementations support at least this 
   * algorithm, to aid in interoperability if a secret is created on one app and recovered using another app.
   */
   bytes shareAlgorithm = 2;

  /*
   * The version number of the share (the secretId is given in the containing DeRecMessage)
   */
   int32 version = 3;

  /*
  * All versions that the helper must retain (including this new one).
  * The helper should delete all other versions outside this list.
  */
  repeated int32 keepList = 4;
}