@@ -21,7 +21,7 @@ const THROW_BAD_TWEAK = 'Expected Tweak';
21
21
const THROW_BAD_HASH = 'Expected Hash' ;
22
22
const THROW_BAD_SIGNATURE = 'Expected Signature' ;
23
23
24
- bool isPrivate (Uint8List x) {
24
+ bool isPrivate (Uint8List x) {
25
25
if (! isScalar (x)) return false ;
26
26
return _compare (x, ZERO32 ) > 0 && // > 0
27
27
_compare (x, EC_GROUP_ORDER ) < 0 ; // < G
@@ -42,7 +42,7 @@ bool isPoint(Uint8List p) {
42
42
}
43
43
try {
44
44
decodeFrom (p);
45
- } catch (err) {
45
+ } catch (err) {
46
46
return false ;
47
47
}
48
48
if ((t == 0x02 || t == 0x03 ) && p.length == 33 ) {
@@ -61,24 +61,22 @@ bool isPoint(Uint8List p) {
61
61
return false ;
62
62
}
63
63
64
- bool isScalar (Uint8List x) {
64
+ bool isScalar (Uint8List x) {
65
65
return x.length == 32 ;
66
66
}
67
67
68
- bool isOrderScalar (x) {
68
+ bool isOrderScalar (x) {
69
69
if (! isScalar (x)) return false ;
70
70
return _compare (x, EC_GROUP_ORDER ) < 0 ; // < G
71
71
}
72
72
73
- bool isSignature (Uint8List value) {
73
+ bool isSignature (Uint8List value) {
74
74
Uint8List r = value.sublist (0 , 32 );
75
75
Uint8List s = value.sublist (32 , 64 );
76
- return value.length == 64 &&
77
- _compare (r, EC_GROUP_ORDER ) < 0 &&
78
- _compare (s, EC_GROUP_ORDER ) < 0 ;
76
+ return value.length == 64 && _compare (r, EC_GROUP_ORDER ) < 0 && _compare (s, EC_GROUP_ORDER ) < 0 ;
79
77
}
80
78
81
- bool _isPointCompressed (Uint8List p) {
79
+ bool _isPointCompressed (Uint8List p) {
82
80
return p[0 ] != 0x04 ;
83
81
}
84
82
@@ -96,7 +94,7 @@ Uint8List pointFromScalar(Uint8List d, bool _compressed) {
96
94
return getEncoded (pp, _compressed);
97
95
}
98
96
99
- Uint8List pointAddScalar (Uint8List p,Uint8List tweak, bool _compressed) {
97
+ Uint8List pointAddScalar (Uint8List p, Uint8List tweak, bool _compressed) {
100
98
if (! isPoint (p)) throw new ArgumentError (THROW_BAD_POINT );
101
99
if (! isOrderScalar (tweak)) throw new ArgumentError (THROW_BAD_TWEAK );
102
100
bool compressed = assumeCompression (_compressed, p);
@@ -109,7 +107,7 @@ Uint8List pointAddScalar(Uint8List p,Uint8List tweak, bool _compressed) {
109
107
return getEncoded (uu, compressed);
110
108
}
111
109
112
- Uint8List privateAdd (Uint8List d,Uint8List tweak) {
110
+ Uint8List privateAdd (Uint8List d, Uint8List tweak) {
113
111
if (! isPrivate (d)) throw new ArgumentError (THROW_BAD_PRIVATE );
114
112
if (! isOrderScalar (tweak)) throw new ArgumentError (THROW_BAD_TWEAK );
115
113
BigInt dd = fromBuffer (d);
@@ -130,14 +128,14 @@ Uint8List sign(Uint8List hash, Uint8List x) {
130
128
if (! isPrivate (x)) throw new ArgumentError (THROW_BAD_PRIVATE );
131
129
ECSignature sig = deterministicGenerateK (hash, x);
132
130
Uint8List buffer = new Uint8List (64 );
133
- buffer.setRange (0 , 32 , encodeBigInt (sig.r));
131
+ buffer.setRange (0 , 32 , _encodeBigInt (sig.r));
134
132
var s;
135
133
if (sig.s.compareTo (nDiv2) > 0 ) {
136
134
s = n - sig.s;
137
135
} else {
138
136
s = sig.s;
139
137
}
140
- buffer.setRange (32 , 64 , encodeBigInt (s));
138
+ buffer.setRange (32 , 64 , _encodeBigInt (s));
141
139
return buffer;
142
140
}
143
141
@@ -185,14 +183,25 @@ bool verify(Uint8List hash, Uint8List q, Uint8List signature) {
185
183
*/
186
184
}
187
185
188
- BigInt fromBuffer (Uint8List d) { return decodeBigInt (d); }
189
- Uint8List toBuffer (BigInt d) { return encodeBigInt (d); }
190
- ECPoint decodeFrom (Uint8List P ) { return secp256k1.curve.decodePoint (P ); }
191
- Uint8List getEncoded (ECPoint P , compressed) { return P .getEncoded (compressed); }
186
+ BigInt fromBuffer (Uint8List d) {
187
+ return _decodeBigInt (d);
188
+ }
189
+
190
+ Uint8List toBuffer (BigInt d) {
191
+ return _encodeBigInt (d);
192
+ }
193
+
194
+ ECPoint decodeFrom (Uint8List P ) {
195
+ return secp256k1.curve.decodePoint (P );
196
+ }
197
+
198
+ Uint8List getEncoded (ECPoint P , compressed) {
199
+ return P .getEncoded (compressed);
200
+ }
192
201
193
202
ECSignature deterministicGenerateK (Uint8List hash, Uint8List x) {
194
203
final signer = new ECDSASigner (null , new HMac (new SHA256Digest (), 64 ));
195
- var pkp = new PrivateKeyParameter (new ECPrivateKey (decodeBigInt (x), secp256k1));
204
+ var pkp = new PrivateKeyParameter (new ECPrivateKey (_decodeBigInt (x), secp256k1));
196
205
signer.init (true , pkp);
197
206
// signer.init(false, new PublicKeyParameter(new ECPublicKey(secp256k1.curve.decodePoint(x), secp256k1)));
198
207
return signer.generateSignature (hash);
@@ -205,3 +214,36 @@ int _compare(Uint8List a, Uint8List b) {
205
214
if (aa > bb) return 1 ;
206
215
return - 1 ;
207
216
}
217
+
218
+ /// Decode a BigInt from bytes in big-endian encoding.
219
+ BigInt _decodeBigInt (List <int > bytes) {
220
+ BigInt result = new BigInt .from (0 );
221
+ for (int i = 0 ; i < bytes.length; i++ ) {
222
+ result += new BigInt .from (bytes[bytes.length - i - 1 ]) << (8 * i);
223
+ }
224
+ return result;
225
+ }
226
+
227
+ var _byteMask = new BigInt .from (0xff );
228
+
229
+ /// Encode a BigInt into bytes using big-endian encoding.
230
+ Uint8List _encodeBigInt (BigInt number) {
231
+ int needsPaddingByte;
232
+ int rawSize;
233
+
234
+ if (number > BigInt .zero) {
235
+ rawSize = (number.bitLength + 7 ) >> 3 ;
236
+ needsPaddingByte = ((number >> (rawSize - 1 ) * 8 ) & negativeFlag) == negativeFlag ? 1 : 0 ;
237
+ } else {
238
+ needsPaddingByte = 0 ;
239
+ rawSize = (number.bitLength + 8 ) >> 3 ;
240
+ }
241
+
242
+ final size = rawSize < 32 ? rawSize + needsPaddingByte : rawSize;
243
+ var result = new Uint8List (size);
244
+ for (int i = 0 ; i < size; i++ ) {
245
+ result[size - i - 1 ] = (number & _byteMask).toInt ();
246
+ number = number >> 8 ;
247
+ }
248
+ return result;
249
+ }
0 commit comments