signECDSADer method

List<int> signECDSADer(
  1. List<int> digest, {
  2. List<int> extraEntropy = const [],
})

Signs the given transaction digest using ECDSA (DER-encoded).

  • digest: The transaction digest (message) to sign.

Implementation

List<int> signECDSADer(List<int> digest,
    {List<int> extraEntropy = const []}) {
  ECDSASignature ecdsaSign = _signingKey.signDigestDeterminstic(
      digest: digest, hashFunc: () => SHA256(), extraEntropy: extraEntropy);
  List<int> signature =
      CryptoSignatureUtils.toDer([ecdsaSign.r, ecdsaSign.s]);
  BigInt attempt = BigInt.one;
  int lengthR = signature[3];
  while (lengthR == 33) {
    ecdsaSign = _signingKey.signDigestDeterminstic(
        digest: digest,
        hashFunc: () => SHA256(),
        extraEntropy: [
          ...extraEntropy,
          ...BigintUtils.toBytes(attempt, length: 32)
        ]);
    signature = CryptoSignatureUtils.toDer([ecdsaSign.r, ecdsaSign.s]);
    attempt += BigInt.one;
    lengthR = signature[3];
  }
  final int derPrefix = signature[0];
  int lengthTotal = signature[1];
  final int derTypeInt = signature[2];
  final List<int> R = signature.sublist(4, 4 + lengthR);
  int lengthS = signature[5 + lengthR];
  final List<int> S = signature.sublist(5 + lengthR + 1);
  BigInt sAsBigint = BigintUtils.fromBytes(S);
  List<int> newS;
  if (lengthS == 33) {
    sAsBigint = BitcoinSignerUtils.order - sAsBigint;
    newS = BigintUtils.toBytes(sAsBigint, length: BitcoinSignerUtils.baselen);
    lengthS -= 1;
    lengthTotal -= 1;
  } else {
    newS = S;
  }
  return [
    derPrefix,
    lengthTotal,
    derTypeInt,
    lengthR,
    ...R,
    derTypeInt,
    lengthS,
    ...newS
  ];
}