Skip to content

Commit 7355f03

Browse files
authored
Merge pull request #10 from p3root/master
fix ecc sign
2 parents 1e15731 + b93906f commit 7355f03

File tree

3 files changed

+91
-20
lines changed

3 files changed

+91
-20
lines changed

lib/src/utils/ecurve.dart

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const THROW_BAD_TWEAK = 'Expected Tweak';
2121
const THROW_BAD_HASH = 'Expected Hash';
2222
const THROW_BAD_SIGNATURE = 'Expected Signature';
2323

24-
bool isPrivate (Uint8List x) {
24+
bool isPrivate(Uint8List x) {
2525
if (!isScalar(x)) return false;
2626
return _compare(x, ZERO32) > 0 && // > 0
2727
_compare(x, EC_GROUP_ORDER) < 0; // < G
@@ -42,7 +42,7 @@ bool isPoint(Uint8List p) {
4242
}
4343
try {
4444
decodeFrom(p);
45-
} catch(err) {
45+
} catch (err) {
4646
return false;
4747
}
4848
if ((t == 0x02 || t == 0x03) && p.length == 33) {
@@ -61,24 +61,22 @@ bool isPoint(Uint8List p) {
6161
return false;
6262
}
6363

64-
bool isScalar (Uint8List x) {
64+
bool isScalar(Uint8List x) {
6565
return x.length == 32;
6666
}
6767

68-
bool isOrderScalar (x) {
68+
bool isOrderScalar(x) {
6969
if (!isScalar(x)) return false;
7070
return _compare(x, EC_GROUP_ORDER) < 0; // < G
7171
}
7272

73-
bool isSignature (Uint8List value) {
73+
bool isSignature(Uint8List value) {
7474
Uint8List r = value.sublist(0, 32);
7575
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;
7977
}
8078

81-
bool _isPointCompressed (Uint8List p) {
79+
bool _isPointCompressed(Uint8List p) {
8280
return p[0] != 0x04;
8381
}
8482

@@ -96,7 +94,7 @@ Uint8List pointFromScalar(Uint8List d, bool _compressed) {
9694
return getEncoded(pp, _compressed);
9795
}
9896

99-
Uint8List pointAddScalar(Uint8List p,Uint8List tweak, bool _compressed) {
97+
Uint8List pointAddScalar(Uint8List p, Uint8List tweak, bool _compressed) {
10098
if (!isPoint(p)) throw new ArgumentError(THROW_BAD_POINT);
10199
if (!isOrderScalar(tweak)) throw new ArgumentError(THROW_BAD_TWEAK);
102100
bool compressed = assumeCompression(_compressed, p);
@@ -109,7 +107,7 @@ Uint8List pointAddScalar(Uint8List p,Uint8List tweak, bool _compressed) {
109107
return getEncoded(uu, compressed);
110108
}
111109

112-
Uint8List privateAdd (Uint8List d,Uint8List tweak) {
110+
Uint8List privateAdd(Uint8List d, Uint8List tweak) {
113111
if (!isPrivate(d)) throw new ArgumentError(THROW_BAD_PRIVATE);
114112
if (!isOrderScalar(tweak)) throw new ArgumentError(THROW_BAD_TWEAK);
115113
BigInt dd = fromBuffer(d);
@@ -130,14 +128,14 @@ Uint8List sign(Uint8List hash, Uint8List x) {
130128
if (!isPrivate(x)) throw new ArgumentError(THROW_BAD_PRIVATE);
131129
ECSignature sig = deterministicGenerateK(hash, x);
132130
Uint8List buffer = new Uint8List(64);
133-
buffer.setRange(0, 32, encodeBigInt(sig.r));
131+
buffer.setRange(0, 32, _encodeBigInt(sig.r));
134132
var s;
135133
if (sig.s.compareTo(nDiv2) > 0) {
136134
s = n - sig.s;
137135
} else {
138136
s = sig.s;
139137
}
140-
buffer.setRange(32, 64, encodeBigInt(s));
138+
buffer.setRange(32, 64, _encodeBigInt(s));
141139
return buffer;
142140
}
143141

@@ -185,14 +183,25 @@ bool verify(Uint8List hash, Uint8List q, Uint8List signature) {
185183
*/
186184
}
187185

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+
}
192201

193202
ECSignature deterministicGenerateK(Uint8List hash, Uint8List x) {
194203
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));
196205
signer.init(true, pkp);
197206
// signer.init(false, new PublicKeyParameter(new ECPublicKey(secp256k1.curve.decodePoint(x), secp256k1)));
198207
return signer.generateSignature(hash);
@@ -205,3 +214,36 @@ int _compare(Uint8List a, Uint8List b) {
205214
if (aa > bb) return 1;
206215
return -1;
207216
}
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+
}

pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ homepage: https://github.com/dart-bitcoin/bip32-dart
55
author: anicdh <anic.dh@gmail.com>
66

77
environment:
8-
sdk: ">=2.12.0 <3.0.0"
8+
sdk: ">=2.0.0 <3.0.0"
99

1010
dependencies:
11-
pointycastle: ^3.0.0-nullsafety.2
11+
pointycastle: ^3.0.1
1212
hex: ^0.2.0
1313
bs58check: ^1.0.2
1414

test/ecc_test.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import 'package:hex/hex.dart';
2+
import 'package:test/test.dart';
3+
import 'package:bip32/src/utils/ecurve.dart' as ecc;
4+
import 'package:bip32/bip32.dart' as bip32;
5+
6+
final defichain_testnet = bip32.NetworkType(bip32: bip32.Bip32Type(private: 0x04358394, public: 0x043587cf), wif: 0xef);
7+
8+
void main() {
9+
group("curve test", () {
10+
test("test private key generation", () {
11+
// seed
12+
//55b18e96ce3964ef2c81ad69249eca6d42682c11fbe525df6671fcbf0c2be902 private key
13+
14+
final hdSeed = bip32.BIP32.fromSeed(
15+
HEX.decode("6607599b768ce88470b3b20919f9c63bff663e2f1ec3e3072d22fd9da3847784c361d5accc3b411019f5c81dd3e4ccf9fd1fddb232bfc9bfe23864e2e6ee793f"), defichain_testnet);
16+
17+
final xMasterPriv = bip32.BIP32.fromSeed(hdSeed.privateKey, defichain_testnet);
18+
final privateKey = xMasterPriv.derivePath("m/0'/0'/0'");
19+
20+
final privateKeyHex = HEX.encode(privateKey.privateKey);
21+
22+
expect("55b18e96ce3964ef2c81ad69249eca6d42682c11fbe525df6671fcbf0c2be902", privateKeyHex);
23+
});
24+
25+
test("test sign", () {
26+
ecc.sign(HEX.decode("b11d3d5e4ae12b89d5e3872ccc7d1f96d29b0ab888b67dccf1be5164b811cdbe"), HEX.decode("55b18e96ce3964ef2c81ad69249eca6d42682c11fbe525df6671fcbf0c2be902"));
27+
});
28+
});
29+
}

0 commit comments

Comments
 (0)