HMAC

In addition to ECDSA signatures, Schnorr signatures, and RSA operations, the Builder Vault also supports HMAC-SHA256 and HMAC-SHA512 operations.

📘

A Note on Performance and Parameters

Computing HMAC in a threshold wallet requires the use of so-called general purpose MPC. Builder Vault uses one of the most efficient general purpose MPC protocols, but even so, the computation of HMAC still requires a significant amount of bandwidth between the MPC nodes. For this reason, it is not suited for use cases demanding high-throughput or for computing HMAC of long messages.

Builder Vault currently only supports HMAC keys shared with a security threshold of one among two or three MPC nodes. Contact the Builder Vault support team for more information.

Key Generation

You can generate a new HMAC key among a set of MPC nodes as follows:

keyID, err := client.HMAC().GenerateKey(ctx, sessionConfig, threshold, keyLength, desiredKeyID)

As usual, the sessionConfig defines the set of MPC nodes among which the resulting HMAC key should be secret shared and a unique session ID. The threshold is the security threshold for the key. The keyLength specifies the byte length of the key to generate. The key length must be between 1 and 256. Finally, desiredKeyID can be used to give the key a specific ID. If desiredKeyID is set to the empty string, the MPC nodes will agree on a random key ID for the new key.

To start the MPC key generation, the above method must be called on the SDKs of all the MPC nodes specified in the session configuration. The MPC session will only succeed if they agree on the session configuration, as well as the threshold, keyLength, and desired key ID.

If the MPC operation succeeds, the key ID will be returned to each SDK.

📘

When to Use the Key

If an honest MPC node succeeds with the key generation MPC session, the protocol ensures that the MPC node will hold a correct key share. But the protocol does not guarantee that all honest players will succeed. In the worst case, only a few honest players will succeed, too few to actually perform a decryption or signature. Therefore you should make sure that all MPC nodes successfully completed the key generation MPC session before using the new key.

Message Authentication

Given an HMAC key in the Builder Vault with some key ID, you can compute the HMAC-SHA256 or HMAC-SHA512 digests of a byte array data as follows:

partialResult, err = client.HMAC().HMACSHA512(ctx, sessionConfig, keyID, data)

This will start an MPC session among the MPC nodes defined in the session configuration. If they all agree on the key ID, and the data to be authenticated, the MPC session will succeed and each SDK will receive a partial result. To obtain the final HMAC digest, the partial results must be collected and combined as follows:

digest, err := tsm.HMACFinalize([][]byte{ partialResult1, partialResult2, partialResult3})

A complete example, showing how to generate a 128-bit HMAC, can be found in our demo repository (Go). The key is then used to compute a HMAC-SHA256 digest of a message.

Key Import and Export

HMAC keys can be imported and exported in the same way as AES keys. The only difference is the checksum used to ensure the integrity of the HMAC key sharing to import or export is the first three bytes of the value SHA256("BuilderVault HMAC Key" || key), where key is the HMAC key.

A full example of import and export of HMAC keys using Builder Vault can be found here: Go.