@namespace("keybase.1")

protocol crypto {
  import idl "common.avdl";

  fixed ED25519PublicKey(32);
  fixed ED25519Signature(64);

  record ED25519SignatureInfo {
    // The actual signature.
    ED25519Signature sig;
    // The public key that can verify the signature.
    ED25519PublicKey publicKey;
  }

  /**
    Sign the given message (which should be small) using the device's private
    signing ED25519 key, and return the signature as well as the corresponding
    public key that can be used to verify the signature. The 'reason' parameter
    is used as part of the SecretEntryArg object passed into
    secretUi.getSecret().
    */
  ED25519SignatureInfo signED25519(int sessionID, bytes msg, string reason);

  /**
    Same as the above except a KBFS-specific prefix is added to the payload to be signed.
    */
  ED25519SignatureInfo signED25519ForKBFS(int sessionID, bytes msg, string reason);

  /**
    Same as the above except the full marsheled and encoded NaclSigInfo.
    */
  string signToString(int sessionID, bytes msg, string reason);

  // 32 + fixed-size nacl/box overhead.
  fixed EncryptedBytes32(48);
  fixed BoxNonce(24);
  fixed BoxPublicKey(32);

  /**
    Decrypt exactly 32 bytes using nacl/box with the given nonce, the given
    peer's public key, and the device's private encryption key, and return the
    decrypted data. The 'reason' parameter is used as part of the
    SecretEntryArg object passed into secretUi.getSecret().
    */
  Bytes32 unboxBytes32(int sessionID, EncryptedBytes32 encryptedBytes32, BoxNonce nonce, BoxPublicKey peersPublicKey, string reason);
 
  record CiphertextBundle {
    KID kid;
    EncryptedBytes32 ciphertext;
    BoxNonce nonce;
    BoxPublicKey publicKey;
  }

  record UnboxAnyRes {
    KID kid;                 // the KID that was used for decryption
    Bytes32 plaintext;       // decrypted data
    int index;
  }

  // if promptPaper is set to true and a paper key would work for one of the bundles, 
  // then there will be a prompt for the user to enter it.  If false, no paper key 
  // prompts will happen.
  UnboxAnyRes unboxBytes32Any(int sessionID, array<CiphertextBundle> bundles, string reason, boolean promptPaper);
}
