Skip to content

Latest commit

 

History

History
239 lines (204 loc) · 12 KB

Hooks.md

File metadata and controls

239 lines (204 loc) · 12 KB

Client Library Hooks

Supported Hooks

Crypto Hooks:

  • generateKeyPair[Single]: function(instance)
    • instance: the JIFF instance
    • Return: an object with two attributes: public_key and secret_key. Both keys must be in a format understandable by dumpKey, encryptSign, and decryptSign hooks.
  • dumpKey[Single]: function(instance, public_key)
    • instance: the JIFF instance
    • public_key: the public key (as generated by generateKeyPair) which must be dumped to string.
    • Return: a string representing the public key.
  • parseKey[Single]: function(instance, public_key_string)
    • instance: the JIFF instance
    • public_key_string: string representation of the public key to be parsed (as generated by dumpKey).
    • Return: parsed public key in a format understandable by dumpKey, encryptSign, and decryptSign.
  • encryptSign[Single]: function(instance, message, encryption_public_key, signing_private_key)
    • instance: the JIFF instance
    • message: the message to encrypt always a string
    • encryption_public_key: public key to encrypt with (corresponding to the receiving party)
    • signing_private_key: secret key to sign with (corresponding to this party)
    • Return: the signed cipher with any additional properties desired to be sent with it (tags, meta-info, etc.) as a JavaScript object
  • decryptSign[Single]: function(instance, cipher_text, decryption_secret_key, signing_public_key)
    • instance: the JIFF instance
    • cipher_text: the cipher_text to decrypt, the format and type matches that returned by encryptSign must be a JavaScript object
    • decryption_secret_key: secret key to decrypt with (corresponding to this party)
    • signing_public_key: public key to verify signature with (corresponding to sending party)
    • Throw: if signature did not check out correctly
    • Return: the decrypted message as a string.

Share Hooks:

  • beforeShare[Array]: function(instance, secret, threshold, receivers_list, senders_list, Zp)
    • Initially, parameters are as passed to jiff_instance.share in the client code:
      • instance: the JIFF instance
      • secret: the secret to share
      • threshold: the threshold for sharing
      • receivers_list: array of ids of receiving parties
      • senders_list: array of ids of sending parties (parties that have secrets)
      • Zp: the modulos
    • Return: must return the (possibly modified) secret to share (to be used as the secret for subsequent hooks in the array).
  • computeShares[Single]: function(instance, secret, parties_list, threshold, Zp)
    • instance: the JIFF instance
    • secret: the secret to share
    • parties_list: array of ids of parties for which to create shares of the secret
    • threshold: the threshold for sharing
    • Zp: the modulus
    • Return: must return a map from party_id to its corresponding share value (for every party_id in parties_list).
  • afterComputeShare[Array]: function(instance, shares, threshold, receivers_list, senders_list, Zp)
    • instance: the JIFF instance
    • shares: a map from party_id to the corresponding share value
    • threshold: the threshold for sharing
    • receivers_list: array of ids of receiving parties
    • senders_list: array of ids of sending parties (parties that have secrets)
    • Zp: the modulus
    • Return: must return a map from party_id to its corresponding share value (for every party_id in receivers_list).
  • receiveShare[Array]: function(instance, sender_id, share)
    • instance: the JIFF instance
    • sender_id: party_id of the sender
    • share: the received share (after decryption)
    • Return: the share, possibly modified (this is used as share for the subsequent hooks in the array).

Open Hooks:

  • beforeOpen[Array]: function(instance, share, parties)
    • instance: the JIFF instance
    • share: the share to open {type: secret_share}
    • parties: the parties that will receive the open
    • Return: the share to open, possibly modified (this is used as share for the subsequent hooks in the array).
  • receiveOpen[Array]: function(instance, sender_id, share, Zp)
    • instance: the JIFF instance
    • sender_id: party_id of the sender
    • share: the received share (after decryption)
    • Zp: the modulus
    • Return: the share, possibly modified (this is used as share for the subsequent hooks in the array).
  • reconstructShare[Single]: function(instance, shares)
    • instance: the JIFF instance
    • shares: a map from party_id to its corresponding object: {"value":share, "sender_id":sender_id, "Zp":Zp }
    • Return: the reconstructed secret.
  • afterReconstructShare[Array]: function(instance, value)
    • instance: the JIFF instance
    • value: the reconstructed value as returned by reconstructShare
    • Return: the reconstructed secret, possibly modified (this is used as value for the subsequent hooks in the array).

Miscellaneous Hooks:

  • createSecretShare[Array]: function(instance, secret_share)
    • instance: the JIFF instance
    • secret_share: the secret_share object as created by JIFF
    • Return: the secret_share object to be used by JIFF, possibly modified (this is used for the subsequent hooks in the array).
  • beforeOperation[Array]: function(instance, label, msg) Called before serializing and sending messages for any operation.
    • instance: the JIFF instance
    • label: one of 'initialization', 'share', 'open', 'custom', 'crypto_provider', 'free', or 'disconnect'
    • msg: the message received (parsed into a json object), the actual attributes in the object depend on which label it corresponds to
    • Return: the msg, including any modifications, that will sent out by this event.
  • afterOperation[Array]: function(instance, label, msg) Called after receiving and parsing messages (but before handling them) for any event.
    • instance: the JIFF instance
    • label: one of 'initialization', 'public_keys', 'share', 'open', 'custom', 'crypto_provider', 'free', or 'disconnect'
    • msg: the message received (parsed into a json object), the actual attributes in the object depend on which label it corresponds to
    • Return: the msg, including modifications, that will get passed into operation handlers.

Example

Hooks can be passed to an instance at creation time via the options object.

Single Hooks expect the value to be a function, while Array Hooks expect the value to be an array (even when only a single hooks is used).

var options = {};
options.hooks = {
  /* Example hooks. */
  'beforeShare': [
    function(instance, secret, threshold, receivers_list, senders_list, Zp) {
      /* Some code. */
      return modified_secret;
    } 
  ],
  'computeShares':
    function(secret, party_count, parties_list, threshold, Zp) {
      /* Some code. */
      return shares_map;
    }
};
var instance = make_jiff('hostname', 'computation_id', options);

Flows Supported By Hooks

Hooks allow to customize the following flows in JIFF without having to explicity modify JIFF's source code.

Custom crypto libraries

Allows using a different crypto library (e.g. for browser compatibility purposes), or disabling/changing the crypto primitives all together. Note that the same/compatible implementation of these hooks must be passed to jiff-server, and any participating computation instances created on the server side.

  1. hook: generateKeyPair called on initialization.
  2. hook: dumpKey called to marshal the public key to a string that can be transmitted to other parties.
  3. hook: parseKey called when a marshaled public key is received from some party to parse it.
  4. hook: encryptSign called to sign and encrypt messages sent by this party for various operations, including share, open, and custom messages.
  5. hook: decryptSign called to decrypt and verify messages received by this party.

Share flow

Determines how shares are generated and sent to parties:

  1. jiff_instance.share
  2. hook: beforeShare
  3. hook: computeShare
  4. hook: afterComputeShare
  5. hook: encryptSign
  6. send shares to parties
  7. party receives share
  8. hook: decryptSign
  9. hook: receiveShare
  10. resolve value into corresponding secret_share object

Note that:

  • the party may be receiving a share without sharing anything, in which case only steps 1 and 7-10 are executed;
  • the party may be sharing a value without receiving shares of anything, in which case only steps 1-6 are executed.

Open flow

Determine show parties can open (reveal) a share and get the result:

  1. jiff_instance.open/share.open
  2. hook: beforeOpen
  3. share is refreshed and refreshed value is used going forward
  4. hook: encryptSign
  5. send share to parties
  6. party receives share to open
  7. hook: decryptSign
  8. hook: receiveOpen
  9. hook (once enough shares are received in step 8 above): reconstructShare
  10. hook: afterReconstructShare
  11. resolve reconstructed value into open promise/callback

Alternatively, a party may receive the result for a share that it does not own, in which case the flow becomes:

  • jiff_instance.receive_open
  • party receives share to open (step 6 from above sequence)
  • steps 7-11 from above sequence

A party may also hold a share of the result but not receive the result, in which case only steps 1-5 of the original flow are executed.

Creation of secret_share objects

This flow is particularly useful when developing extensions for JIFF. This allows the user to modify the implementation of a secret_share object, including changing how operations are implemented (e.g. addition, multiplication, etc.), registering callbacks for when the share is computed, or adding additional operations:

  1. a share is created (e.g. by jiff_instance.share or by operating on shares)
  2. new secret_share is invoked
  3. the default secret_share object is created
  4. hook: createSecretShare
  5. returned secret_share object is used by JIFF

Server-Library Hooks

The server library hooks work similarly to the client library. They are passed in the hooks attribute of the options object similarly. Note that these hooks are applied at the granularity of the entire server app, which includes all computations, and all parties in them. If you have special roles or computations that require specific hooks, you will either need to use a dedicated jiff-server instance for them, or provide high level hooks which check the computation and party ids, and execute the appropriate code for them.

Supported Hooks

Crypto Hooks

Exact match of the client library crypto hooks, except it does not include encryptSign or decryptSign, since server does not decrypt/encrypt messages by default.

Initialization Hooks

  • beforeInitialization
  • onInitializeUsedId if party requests id that is already reserved: single hook.
  • afterInitialization

Free Party Ids tracking

For tracking which ids are free and which are used

  • trackFreeIds initialize mailbox object, contains these functions:
    • is_free check if party id is free
    • create_free return (but do not reserve) a free party id
    • reserve reserve a party id as not free

Disconnect/Free Hooks

  • onDisconnect
  • beforeFree
  • afterFree

Mailbox Hooks

For storing messages in mailboxes

  • put_in_mailbox put a message in mailbox
  • get_mailbox get an array containing all messages in mailbox in order
  • remove_from_mailbox remove message from mailbox by id returned by put_in_mailbox or get_mailbox
  • slice_mailbox remove all messages up to and including given id

Miscellaneous Hooks

  • log
  • beforeOperation after receiving but before servicing messages for share, open, custom, and crypto_provider. Server restful extension has an extra operation: 'poll'. Any errors raised in this hook cause the request to reject, and the error to be returned to the client.
  • afterOperation after servicing but before sending output message for share, open, custom, and crypto_provider. Server restful extension has an extra operation: 'poll'. Any errors raised in this hook cause the request to reject, and the error to be returned to the client.
  • computeShares