Wallet Key Derivation via REST
Primus HSM supports key derivation for crypto currency wallets. For a background, see the Wallet Key Derivation article.
Key derivation consists of the following main steps:
- Creating a master key pair.
- Deriving a child key from the master key.
- Using the child key for signing and verification.
Derivation Types
Below is a table listing the combinations of BIP-32 and SLIP-10 derivation types for both EC (Elliptic Curve) and ED (Edwards-Curve Digital Signature Algorithm) keys.
ED (Edwards-Curve Digital Signature Algorithm) Key Derivation Types
| BIP-32 | SLIP-10 | Derivation Type |
|---|---|---|
| 0 | 0 | None |
| 0 | 1 | SLIP-10 |
| 1 | 0 | Cardano (ADA) |
| 1 | 1 | SLIP-10 |
EC (Elliptic Curve Cryptography) Key Derivation Types
| BIP-32 | SLIP-10 | Derivation Type |
|---|---|---|
| 0 | 0 | None |
| 0 | 1 | SLIP-10 |
| 1 | 0 | SLIP-10 |
| 1 | 1 | SLIP-10 |
Creating a Master Key
POST /v1/key
Creating a master key is done using the /v1/key endpoint.
This endpoint is also used to create normal keys.
For a key to be a master key from which child keys can be derived, you need to set the following options:
"derive": trueto allow derivation."slip10": trueand/or"bip32": trueto choose the derivation type for this key (see above).algorithmandcurveOidto choose the type of elliptic curve. See also the list of supported curve OIDs.
Choose carefully, as these settings cannot be changed after the key has been created! If later on you need different settings, you need to create a new key.
Here is an example request body:
{
"label": "<keyname>",
"password": [ "R","E","P","L","A","C","E" ],
"algorithm": "EC",
"curveOid": "1.3.132.0.10",
"attributes": {
"encrypt": true,
"decrypt": true,
"verify": true,
"sign": true,
"wrap": true,
"unwrap": true,
"derive": true,
"bip32": false,
"slip10": true,
"extractable": false,
"modifiable": true,
"destroyable": true,
"sensitive": true,
"copyable": false
}
}
Response:
{
"derivedAttributes": {
"derivationType": "SLIP-10",
"derivationValue": "43CB755D8B3D0D72CCEE2CE608082146CF48B83DF1A513D4FE66087B138F89A6"
},
}
Instead of creating a fresh master key, you can import a master key from a SLIP-10 seed.
Deriving a Child Key
Derived child keys can either be persisted keys (using storage) or temporary keys (requiring re-computation for each key usage).
Child keys are identified by their derivation paths, as defined by SLIP-10.
An example derivation path is ec_slip_10/44'/0'/0'/0/0 where ec_slip_10 is the label of the master key.
Persisted Derived Keys
You can derive from a base key and persist the derived key. This approach offers the advantage of faster signing operations since the derived key is readily available for repeated usage without the need for re-computation. However, persisting the derived key incurs storage cost on disk.
Derived keys can be generated by using the endpoint:
- POST /v1/derivedkey
Temporary Derived Keys
Temporary derived keys are generated dynamically for each key usage requests. These keys are derived on-the-fly from an existing base key and are immediately discarded after their use. Temporary key derivation is often preferred since it reduces storage overhead.
Endpoint where Temporary Key Derivation is available:
- POST /v1/sign
- POST /v1/synchronousSign
- POST /v1/verify
- POST /v1/key/attributes
- POST /v1/key/address
To use temporary derived keys, simply pass a derivation path as the key label to these endpoints. The REST API automatically detects that the label is not a stored key, and will automatically derive the child key as a temporary session object.
Sign a Payload with Temporary Derived Key
POST: /v1/synchronousSign
{
"signRequest": {
"payload": "U2lnblBheWxvYWREZW1v",
"payloadType": "UNSPECIFIED",
"signKeyName": "ec_slip_10/44'/0'/0'/0/0",
"keyPassword": null,
"metaData": "U29tZU1ldGFEYXRh",
"metaDataSignature": "TWV0YURhdGFTaWduYXR1cmU=",
"signatureAlgorithm": "SHA256_WITH_ECDSA",
"signatureType": null
},
"requestSignature": null
}
Response:
{
"signature": "MEQCIE/3O9poWWby9o+DRyC6INWPK2eZX4dFhrgdIFsokhWxAiBPHCdsPtRM4uRVpxAbQQEIWUMUVRIh7OMQfAEzw4TH7g=="
}
Verify
POST: /v1/verify
Replace signature from the previous response and set the initial payload.
{
"verifySignatureRequest": {
"signKeyName": "ec_slip_10/44'/0'/0'/0/0",
"signatureAlgorithm": "SHA256_WITH_ECDSA",
"payload": "U2lnblBheWxvYWREZW1v",
"signature": "MEQCIE/3O9poWWby9o+DRyC6INWPK2eZX4dFhrgdIFsokhWxAiBPHCdsPtRM4uRVpxAbQQEIWUMUVRIh7OMQfAEzw4TH7g=="
}
}
Response:
{
"signatureValid": true
}