softDerive method

Tuple<SchnorrkelSecretKey, List<int>> softDerive(
  1. List<int> chainCode, {
  2. List<int>? message,
  3. GenerateRandom? nonceGenerator,
})

Derives a new Schnorrkel secret key and chain code from the current secret key, chain code, and an optional message.

This method performs a soft derivation following the Schnorrkel RistrettoPoint Hierarchical Deterministic Key Derivation (HDKD) scheme.

Parameters:

  • chainCode: A chain code used in the derivation.
  • message (optional): An optional byte array message used in the derivation. Default is an empty byte array.
  • nonceGenerator (optional): A function that generates a nonce. Default is a function that generates a random 32-byte nonce.

Returns: A tuple containing a new Schnorrkel secret key and a new chain code, derived from the current secret key, chain code, and message.

Example Usage:

List<int> chainCode = ...;
SchnorrkelSecretKey currentSecretKey = ...;
List<int> message = ...;
GenerateRandom? customNonceGenerator = (length) => ...;
var (newSecretKey, newChainCode) = currentSecretKey.softDerive(chainCode, message, customNonceGenerator);

The softDerive method follows the Schnorrkel RistrettoPoint HDKD scheme to derive a new Schnorrkel secret key and chain code. It combines the current secret key, chain code, and an optional message to compute the new secret key and chain code. The nonceGenerator parameter allows specifying a custom function to generate a nonce.

Implementation

Tuple<SchnorrkelSecretKey, List<int>> softDerive(List<int> chainCode,
    {List<int>? message, GenerateRandom? nonceGenerator}) {
  final derivePub = publicKey()._deriveScalarAndChainCode(chainCode, message);
  final nonce = nonceGenerator?.call(32) ?? QuickCrypto.generateRandom(32);
  if (nonce.length != 32) {
    throw const ArgumentException("invalid random bytes length");
  }
  final newKey = Ed25519Utils.add(key(), derivePub.item1);
  final combine = List<int>.from([...newKey, ...nonce]);
  return Tuple(SchnorrkelSecretKey.fromBytes(combine), derivePub.item2);
}