Skip to content

Commit e9806c0

Browse files
committed
Simple sanity check on wrap
1 parent c8dfd2c commit e9806c0

File tree

7 files changed

+189
-5
lines changed

7 files changed

+189
-5
lines changed

src/bip32.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
33
const crypto = require("./crypto");
4+
const testecc_1 = require("./testecc");
45
const bs58check = require('bs58check');
56
const typeforce = require('typeforce');
67
const wif = require('wif');
78
function default_1(ecc) {
9+
testecc_1.testEcc(ecc);
810
const UINT256_TYPE = typeforce.BufferN(32);
911
const NETWORK_TYPE = typeforce.compile({
1012
wif: typeforce.UInt8,
@@ -212,12 +214,16 @@ function default_1(ecc) {
212214
signSchnorr(hash) {
213215
if (!this.privateKey)
214216
throw new Error('Missing private key');
217+
if (!ecc.signSchnorr)
218+
throw new Error('signSchnorr not supported by ecc library');
215219
return Buffer.from(ecc.signSchnorr(hash, this.privateKey));
216220
}
217221
verify(hash, signature) {
218222
return ecc.verify(hash, this.publicKey, signature);
219223
}
220224
verifySchnorr(hash, signature) {
225+
if (!ecc.verifySchnorr)
226+
throw new Error('verifySchnorr not supported by ecc library');
221227
return ecc.verifySchnorr(hash, this.publicKey.subarray(1, 33), signature);
222228
}
223229
}

src/testecc.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
const h = (hex) => Buffer.from(hex, 'hex');
4+
function testEcc(ecc) {
5+
assert(ecc.isPoint(h('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')));
6+
assert(!ecc.isPoint(h('030000000000000000000000000000000000000000000000000000000000000005')));
7+
assert(ecc.isPrivate(h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')));
8+
// order - 1
9+
assert(ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')));
10+
// 0
11+
assert(!ecc.isPrivate(h('0000000000000000000000000000000000000000000000000000000000000000')));
12+
// order
13+
assert(!ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141')));
14+
// order + 1
15+
assert(!ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142')));
16+
assert(Buffer.from(ecc.pointFromScalar(h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af'))).equals(h('02b07ba9dca9523b7ef4bd97703d43d20399eb698e194704791a25ce77a400df99')));
17+
assert(Buffer.from(ecc.pointAddScalar(h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('0000000000000000000000000000000000000000000000000000000000000003'))).equals(h('02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5')));
18+
assert(Buffer.from(ecc.privateAdd(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e'), h('0000000000000000000000000000000000000000000000000000000000000002'))).equals(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')));
19+
assert(Buffer.from(ecc.sign(h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'))).equals(h('54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5')));
20+
assert(ecc.verify(h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5')));
21+
if (ecc.signSchnorr) {
22+
assert(Buffer.from(ecc.signSchnorr(h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), h('c90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b14e5c9'), h('c87aa53824b4d7ae2eb035a2b5bbbccc080e76cdc6d1692c4b0b62d798e6d906'))).equals(h('5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7')));
23+
}
24+
if (ecc.verifySchnorr) {
25+
assert(ecc.verifySchnorr(h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), h('dd308afec5777e13121fa72b9cc1b7cc0139715309b086c960e18fd969774eb8'), h('5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7')));
26+
}
27+
}
28+
exports.testEcc = testEcc;
29+
function assert(bool) {
30+
if (!bool)
31+
throw new Error('ecc library invalid');
32+
}

test/index.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
let BIP32Creator = require('..').default
22
let tape = require('tape')
33
let fixtures = require('./fixtures/index.json')
4-
import('tiny-secp256k1').then(ecc => BIP32Creator(ecc)).then(BIP32 => {
4+
let ecc
5+
import('tiny-secp256k1').then(lib => {
6+
ecc = lib
7+
return BIP32Creator(lib)
8+
}).then(BIP32 => {
59
let LITECOIN = {
610
wif: 0xb0,
711
bip32: {
@@ -95,6 +99,15 @@ validAll.forEach((ff) => {
9599
})
96100
})
97101

102+
tape('invalid ecc library throws', (t) => {
103+
t.throws(() => {
104+
BIP32Creator({ isPoint: () => false })
105+
}, /ecc library invalid/)
106+
// Run with no schnorr and check it doesn't throw
107+
BIP32Creator({ ...ecc, signSchnorr: null, verifySchnorr: null })
108+
t.end()
109+
})
110+
98111
tape('fromBase58 throws', (t) => {
99112
fixtures.invalid.fromBase58.forEach((f) => {
100113
t.throws(() => {

ts-src/bip32.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as crypto from './crypto';
2+
import { testEcc } from './testecc';
23
const bs58check = require('bs58check');
34
const typeforce = require('typeforce');
45
const wif = require('wif');
@@ -65,17 +66,18 @@ export interface TinySecp256k1Interface {
6566
): Uint8Array | null;
6667
privateAdd(d: Uint8Array, tweak: Uint8Array): Uint8Array | null;
6768
sign(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
68-
signSchnorr(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
69+
signSchnorr?(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
6970
verify(
7071
h: Uint8Array,
7172
Q: Uint8Array,
7273
signature: Uint8Array,
7374
strict?: boolean,
7475
): boolean;
75-
verifySchnorr(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean;
76+
verifySchnorr?(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean;
7677
}
7778

7879
export default function(ecc: TinySecp256k1Interface): BIP32API {
80+
testEcc(ecc);
7981
const UINT256_TYPE = typeforce.BufferN(32);
8082
const NETWORK_TYPE = typeforce.compile({
8183
wif: typeforce.UInt8,
@@ -346,6 +348,8 @@ export default function(ecc: TinySecp256k1Interface): BIP32API {
346348

347349
signSchnorr(hash: Buffer): Buffer {
348350
if (!this.privateKey) throw new Error('Missing private key');
351+
if (!ecc.signSchnorr)
352+
throw new Error('signSchnorr not supported by ecc library');
349353
return Buffer.from(ecc.signSchnorr(hash, this.privateKey));
350354
}
351355

@@ -354,6 +358,8 @@ export default function(ecc: TinySecp256k1Interface): BIP32API {
354358
}
355359

356360
verifySchnorr(hash: Buffer, signature: Buffer): boolean {
361+
if (!ecc.verifySchnorr)
362+
throw new Error('verifySchnorr not supported by ecc library');
357363
return ecc.verifySchnorr(hash, this.publicKey.subarray(1, 33), signature);
358364
}
359365
}

ts-src/testecc.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { TinySecp256k1Interface } from './bip32';
2+
3+
const h = (hex: string): Buffer => Buffer.from(hex, 'hex');
4+
5+
export function testEcc(ecc: TinySecp256k1Interface): void {
6+
assert(
7+
ecc.isPoint(
8+
h('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
9+
),
10+
);
11+
assert(
12+
!ecc.isPoint(
13+
h('030000000000000000000000000000000000000000000000000000000000000005'),
14+
),
15+
);
16+
assert(
17+
ecc.isPrivate(
18+
h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
19+
),
20+
);
21+
// order - 1
22+
assert(
23+
ecc.isPrivate(
24+
h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'),
25+
),
26+
);
27+
// 0
28+
assert(
29+
!ecc.isPrivate(
30+
h('0000000000000000000000000000000000000000000000000000000000000000'),
31+
),
32+
);
33+
// order
34+
assert(
35+
!ecc.isPrivate(
36+
h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'),
37+
),
38+
);
39+
// order + 1
40+
assert(
41+
!ecc.isPrivate(
42+
h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142'),
43+
),
44+
);
45+
assert(
46+
Buffer.from(
47+
ecc.pointFromScalar(
48+
h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af'),
49+
)!,
50+
).equals(
51+
h('02b07ba9dca9523b7ef4bd97703d43d20399eb698e194704791a25ce77a400df99'),
52+
),
53+
);
54+
assert(
55+
Buffer.from(
56+
ecc.pointAddScalar(
57+
h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
58+
h('0000000000000000000000000000000000000000000000000000000000000003'),
59+
)!,
60+
).equals(
61+
h('02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5'),
62+
),
63+
);
64+
assert(
65+
Buffer.from(
66+
ecc.privateAdd(
67+
h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e'),
68+
h('0000000000000000000000000000000000000000000000000000000000000002'),
69+
)!,
70+
).equals(
71+
h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'),
72+
),
73+
);
74+
assert(
75+
Buffer.from(
76+
ecc.sign(
77+
h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'),
78+
h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'),
79+
)!,
80+
).equals(
81+
h(
82+
'54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5',
83+
),
84+
),
85+
);
86+
assert(
87+
ecc.verify(
88+
h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'),
89+
h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
90+
h(
91+
'54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5',
92+
),
93+
),
94+
);
95+
if (ecc.signSchnorr) {
96+
assert(
97+
Buffer.from(
98+
ecc.signSchnorr(
99+
h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'),
100+
h('c90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b14e5c9'),
101+
h('c87aa53824b4d7ae2eb035a2b5bbbccc080e76cdc6d1692c4b0b62d798e6d906'),
102+
)!,
103+
).equals(
104+
h(
105+
'5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7',
106+
),
107+
),
108+
);
109+
}
110+
if (ecc.verifySchnorr) {
111+
assert(
112+
ecc.verifySchnorr(
113+
h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'),
114+
h('dd308afec5777e13121fa72b9cc1b7cc0139715309b086c960e18fd969774eb8'),
115+
h(
116+
'5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7',
117+
),
118+
),
119+
);
120+
}
121+
}
122+
123+
function assert(bool: boolean): void {
124+
if (!bool) throw new Error('ecc library invalid');
125+
}

types/bip32.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ export interface TinySecp256k1Interface {
4646
pointAddScalar(p: Uint8Array, tweak: Uint8Array, compressed?: boolean): Uint8Array | null;
4747
privateAdd(d: Uint8Array, tweak: Uint8Array): Uint8Array | null;
4848
sign(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
49-
signSchnorr(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
49+
signSchnorr?(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array;
5050
verify(h: Uint8Array, Q: Uint8Array, signature: Uint8Array, strict?: boolean): boolean;
51-
verifySchnorr(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean;
51+
verifySchnorr?(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean;
5252
}
5353
export default function (ecc: TinySecp256k1Interface): BIP32API;
5454
export {};

types/testecc.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { TinySecp256k1Interface } from './bip32';
2+
export declare function testEcc(ecc: TinySecp256k1Interface): void;

0 commit comments

Comments
 (0)