bytesUnwrapDerSignature function

Uint8List bytesUnwrapDerSignature(
  1. Uint8List derEncoded
)

ECDSA DER Signature 0x30|b1|0x02|b2|r|0x02|b3|s b1 = Length of remaining data b2 = Length of r b3 = Length of s

If the first byte is higher than 0x80, an additional 0x00 byte is prepended to the value.

Implementation

Uint8List bytesUnwrapDerSignature(Uint8List derEncoded) {
  if (derEncoded.length == 64) return derEncoded;

  final buf = Uint8List.fromList(derEncoded);

  const splitter = 0x02;
  final b1 = buf[1];

  if (b1 != buf.length - 2) {
    throw 'Bytes long is not correct';
  }
  if (buf[2] != splitter) {
    throw 'Splitter not found';
  }

  Tuple2<int, Uint8List> getBytes(Uint8List remaining) {
    int length = 0;
    Uint8List bytes;

    if (remaining[0] != splitter) {
      throw 'Splitter not found';
    }
    if (remaining[1] > 32) {
      if (remaining[2] != 0x0 || remaining[3] <= 0x80) {
        throw 'r value is not correct';
      } else {
        length = remaining[1];
        bytes = remaining.sublist(3, 2 + length);
      }
    } else {
      length = remaining[1];
      bytes = remaining.sublist(2, 2 + length);
    }
    return Tuple2(length, bytes);
  }

  final rRemaining = buf.sublist(2);
  final rBytes = getBytes(rRemaining);
  final b2 = rBytes.item1;
  final r = Uint8List.fromList(rBytes.item2);
  final sRemaining = rRemaining.sublist(b2 + 2);

  final sBytes = getBytes(sRemaining);
  // final b3 = sBytes.item1;
  final s = Uint8List.fromList(sBytes.item2);
  return Uint8List.fromList([...r, ...s]);
}