Line data Source code
1 : import 'dart:typed_data';
2 :
3 20 : final zero = Uint8List.fromList([0]);
4 :
5 5 : Uint8List encodeSignature(Uint8List signature, int hashType) {
6 : // check if hashType is uint8
7 10 : if (hashType < 0 || hashType > 255) {
8 0 : throw ArgumentError('Invalid hashType $hashType');
9 : }
10 10 : if (signature.length != 64) throw ArgumentError("Invalid signature");
11 : // final hashTypeMod = hashType & ~0x80;
12 : // if (hashTypeMod <= 0 || hashTypeMod >= 4) {
13 : // throw ArgumentError('Invalid hashType $hashType');
14 : // }
15 :
16 10 : final r = toDER(signature.sublist(0, 32));
17 10 : final s = toDER(signature.sublist(32, 64));
18 :
19 5 : final encoded = bip66encode(r, s);
20 :
21 15 : return Uint8List.fromList([...encoded, hashType]);
22 : }
23 :
24 5 : Uint8List bip66encode(Uint8List r, Uint8List s) {
25 5 : var lenR = r.length;
26 5 : var lenS = s.length;
27 5 : if (lenR == 0) throw ArgumentError('R length is zero');
28 5 : if (lenS == 0) throw ArgumentError('S length is zero');
29 5 : if (lenR > 33) throw ArgumentError('R length is too long');
30 5 : if (lenS > 33) throw ArgumentError('S length is too long');
31 15 : if (r[0] & 0x80 != 0) throw ArgumentError('R value is negative');
32 15 : if (s[0] & 0x80 != 0) throw ArgumentError('S value is negative');
33 30 : if (lenR > 1 && (r[0] == 0x00) && r[1] & 0x80 == 0) {
34 0 : throw ArgumentError('R value excessively padded');
35 : }
36 18 : if (lenS > 1 && (s[0] == 0x00) && s[1] & 0x80 == 0) {
37 0 : throw ArgumentError('S value excessively padded');
38 : }
39 :
40 15 : var signature = Uint8List(6 + lenR + lenS);
41 :
42 : // 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
43 5 : signature[0] = 0x30;
44 15 : signature[1] = signature.length - 2;
45 5 : signature[2] = 0x02;
46 10 : signature[3] = r.length;
47 10 : signature.setRange(4, 4 + lenR, r);
48 10 : signature[4 + lenR] = 0x02;
49 15 : signature[5 + lenR] = s.length;
50 20 : signature.setRange(6 + lenR, 6 + lenR + lenS, s);
51 : return signature;
52 : }
53 :
54 5 : Uint8List toDER(Uint8List x) {
55 : var i = 0;
56 10 : while (x[i] == 0) {
57 1 : ++i;
58 : }
59 10 : if (i == x.length) return zero;
60 5 : x = x.sublist(i);
61 10 : List<int> combine = List.from(zero);
62 5 : combine.addAll(x);
63 20 : if (x[0] & 0x80 != 0) return Uint8List.fromList(combine);
64 : return x;
65 : }
|