forked from bcoin-org/bcoin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.js
129 lines (99 loc) · 2.55 KB
/
common.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*!
* common.js - common functions for hd
* Copyright (c) 2015-2016, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
const assert = require('assert');
const LRU = require('../utils/lru');
const common = exports;
/**
* Index at which hardening begins.
* @const {Number}
* @default
*/
common.HARDENED = 0x80000000;
/**
* Min entropy bits.
* @const {Number}
* @default
*/
common.MIN_ENTROPY = 128;
/**
* Max entropy bits.
* @const {Number}
* @default
*/
common.MAX_ENTROPY = 512;
/**
* LRU cache to avoid deriving keys twice.
* @type {LRU}
*/
common.cache = new LRU(500);
/**
* Parse a derivation path and return an array of indexes.
* @see https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
* @param {String} path
* @param {Boolean} hard
* @returns {Number[]}
*/
common.parsePath = function parsePath(path, hard) {
assert(typeof path === 'string');
assert(typeof hard === 'boolean');
assert(path.length >= 1);
assert(path.length <= 3062);
const parts = path.split('/');
const root = parts[0];
if (root !== 'm'
&& root !== 'M'
&& root !== 'm\''
&& root !== 'M\'') {
throw new Error('Invalid path root.');
}
const result = [];
for (let i = 1; i < parts.length; i++) {
let part = parts[i];
const hardened = part[part.length - 1] === '\'';
if (hardened)
part = part.slice(0, -1);
if (part.length > 10)
throw new Error('Path index too large.');
if (!/^\d+$/.test(part))
throw new Error('Path index is non-numeric.');
let index = parseInt(part, 10);
if ((index >>> 0) !== index)
throw new Error('Path index out of range.');
if (hardened) {
index |= common.HARDENED;
index >>>= 0;
}
if (!hard && (index & common.HARDENED))
throw new Error('Path index cannot be hardened.');
result.push(index);
}
return result;
};
/**
* Test whether the key is a master key.
* @param {HDPrivateKey|HDPublicKey} key
* @returns {Boolean}
*/
common.isMaster = function isMaster(key) {
return key.depth === 0
&& key.childIndex === 0
&& key.parentFingerPrint === 0;
};
/**
* Test whether the key is (most likely) a BIP44 account key.
* @param {HDPrivateKey|HDPublicKey} key
* @param {Number?} account
* @returns {Boolean}
*/
common.isAccount = function isAccount(key, account) {
if (account != null) {
const index = (common.HARDENED | account) >>> 0;
if (key.childIndex !== index)
return false;
}
return key.depth === 3 && (key.childIndex & common.HARDENED) !== 0;
};