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 instancepublic_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 instancepublic_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 instancemessage
: the message to encrypt always a stringencryption_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 instancecipher_text
: the cipher_text to decrypt, the format and type matches that returned by encryptSign must be a JavaScript objectdecryption_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.
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 instancesecret
: the secret to sharethreshold
: the threshold for sharingreceivers_list
: array of ids of receiving partiessenders_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).
- Initially, parameters are as passed to
computeShares[Single]: function(instance, secret, parties_list, threshold, Zp)
instance
: the JIFF instancesecret
: the secret to shareparties_list
: array of ids of parties for which to create shares of the secretthreshold
: the threshold for sharingZp
: the modulus- Return: must return a map from
party_id
to its corresponding share value (for everyparty_id
inparties_list
).
afterComputeShare[Array]: function(instance, shares, threshold, receivers_list, senders_list, Zp)
instance
: the JIFF instanceshares
: a map from party_id to the corresponding share valuethreshold
: the threshold for sharingreceivers_list
: array of ids of receiving partiessenders_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 everyparty_id
inreceivers_list
).
receiveShare[Array]: function(instance, sender_id, share)
instance
: the JIFF instancesender_id
: party_id of the sendershare
: the received share (after decryption)- Return: the share, possibly modified (this is used as share for the subsequent hooks in the array).
beforeOpen[Array]: function(instance, share, parties)
instance
: the JIFF instanceshare
: 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 instancesender_id
: party_id of the sendershare
: 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 instanceshares
: 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 instancevalue
: 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).
createSecretShare[Array]: function(instance, secret_share)
instance
: the JIFF instancesecret_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 instancelabel
: 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 instancelabel
: 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.
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);
Hooks allow to customize the following flows in JIFF without having to explicity modify JIFF's source code.
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.
- hook:
generateKeyPair
called on initialization. - hook:
dumpKey
called to marshal the public key to a string that can be transmitted to other parties. - hook:
parseKey
called when a marshaled public key is received from some party to parse it. - hook:
encryptSign
called to sign and encrypt messages sent by this party for various operations, including share, open, and custom messages. - hook:
decryptSign
called to decrypt and verify messages received by this party.
Determines how shares are generated and sent to parties:
jiff_instance.share
- hook:
beforeShare
- hook:
computeShare
- hook:
afterComputeShare
- hook:
encryptSign
- send shares to parties
- party receives share
- hook:
decryptSign
- hook:
receiveShare
- 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.
Determine show parties can open (reveal) a share and get the result:
jiff_instance.open/share.open
- hook:
beforeOpen
- share is refreshed and refreshed value is used going forward
- hook:
encryptSign
- send share to parties
- party receives share to open
- hook:
decryptSign
- hook:
receiveOpen
- hook (once enough shares are received in step 8 above):
reconstructShare
- hook:
afterReconstructShare
- 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.
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:
- a share is created (e.g. by
jiff_instance.share
or by operating on shares) new secret_share
is invoked- the default
secret_share
object is created - hook:
createSecretShare
- returned
secret_share
object is used by JIFF
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.
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.
beforeInitialization
onInitializeUsedId
if party requests id that is already reserved: single hook.afterInitialization
For tracking which ids are free and which are used
trackFreeIds
initialize mailbox object, contains these functions:is_free
check if party id is freecreate_free
return (but do not reserve) a free party idreserve
reserve a party id as not free
onDisconnect
beforeFree
afterFree
For storing messages in mailboxes
put_in_mailbox
put a message in mailboxget_mailbox
get an array containing all messages in mailbox in orderremove_from_mailbox
remove message from mailbox by id returned by put_in_mailbox or get_mailboxslice_mailbox
remove all messages up to and including given id
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