bip32-ed25519 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +12 -0
- package/package.json +6 -4
- package/test/derive.test.js +45 -17
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var elliptic = require('elliptic');
|
|
|
4
4
|
var utils = elliptic.utils;
|
|
5
5
|
var EDDSA = require('./elliptic_eddsa_variant');
|
|
6
6
|
var eddsa = new EDDSA('ed25519');
|
|
7
|
+
var pbkdf2 = require('pbkdf2');
|
|
7
8
|
|
|
8
9
|
function sha512(data) {
|
|
9
10
|
var digest = hash.sha512().update(data).digest();
|
|
@@ -48,6 +49,16 @@ function fromSeed2(seed) {
|
|
|
48
49
|
return Buffer.concat([extended, block.slice(32, 64)])
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
function fromEntropy(entropy) {
|
|
53
|
+
const xprv = pbkdf2.pbkdf2Sync('', entropy, 4096, 96, 'sha512')
|
|
54
|
+
|
|
55
|
+
xprv[0] &= 248
|
|
56
|
+
xprv[31] &= 31
|
|
57
|
+
xprv[31] |= 64
|
|
58
|
+
|
|
59
|
+
return Buffer.from(xprv)
|
|
60
|
+
}
|
|
61
|
+
|
|
51
62
|
function derivePrivate(xprv, index) {
|
|
52
63
|
var kl = xprv.slice(0, 32);
|
|
53
64
|
var kr = xprv.slice(32, 64);
|
|
@@ -160,6 +171,7 @@ function verify(message, sig, xpub) {
|
|
|
160
171
|
module.exports = {
|
|
161
172
|
fromSeed2: fromSeed2,
|
|
162
173
|
fromSeed: generateFromSeed,
|
|
174
|
+
fromEntropy,
|
|
163
175
|
generateFromSeed: generateFromSeed,
|
|
164
176
|
derivePrivate: derivePrivate,
|
|
165
177
|
derivePublic: derivePublic,
|
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bip32-ed25519",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"bn.js": "^5.
|
|
8
|
-
"elliptic": "^6.
|
|
9
|
-
"hash.js": "^1.1.7"
|
|
7
|
+
"bn.js": "^5.2.3",
|
|
8
|
+
"elliptic": "^6.6.1",
|
|
9
|
+
"hash.js": "^1.1.7",
|
|
10
|
+
"pbkdf2": "^3.1.5"
|
|
10
11
|
},
|
|
11
12
|
"devDependencies": {
|
|
13
|
+
"bip39": "^3.1.0",
|
|
12
14
|
"mocha": "^10.3.0",
|
|
13
15
|
"should": "^11.2.1"
|
|
14
16
|
},
|
package/test/derive.test.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
var should = require('should');
|
|
2
|
+
var bip39 = require('bip39');
|
|
2
3
|
|
|
3
|
-
var
|
|
4
|
-
var eddsa =
|
|
4
|
+
var bip32Ed25519 = require('../index');
|
|
5
|
+
var eddsa = bip32Ed25519.eddsa;
|
|
5
6
|
|
|
6
7
|
describe('derive', function() {
|
|
7
8
|
|
|
@@ -9,19 +10,19 @@ describe('derive', function() {
|
|
|
9
10
|
|
|
10
11
|
it('general', function(done) {
|
|
11
12
|
var seed = Buffer.from('e2282f95e0c16a0f2837553c9000c22c82d87e667b5ded17b26d15bdb60245f0e89067d412aa8c41caa4dfbbdcf8fd3095cb974c0104bc0a9309491f929681e1', 'hex');
|
|
12
|
-
var xprv =
|
|
13
|
+
var xprv = bip32Ed25519.generateFromSeed(seed);
|
|
13
14
|
console.log('xprv:', xprv.toString('hex'));
|
|
14
15
|
|
|
15
|
-
var xpub =
|
|
16
|
+
var xpub = bip32Ed25519.toPublic(xprv);
|
|
16
17
|
console.log('xpub:', xpub.toString('hex'));
|
|
17
18
|
|
|
18
19
|
var total = 10000000;
|
|
19
20
|
for (var i = 0; i < 100000; i++) {
|
|
20
21
|
var index = parseInt(Math.random() * 100000);
|
|
21
22
|
console.log('[' + i + '/' + total + '] ' + index);
|
|
22
|
-
var derivedPrivateKey =
|
|
23
|
-
var derivedPublicKey =
|
|
24
|
-
var toPublicKey =
|
|
23
|
+
var derivedPrivateKey = bip32Ed25519.derivePrivate(xprv, index);
|
|
24
|
+
var derivedPublicKey = bip32Ed25519.derivePublic(xpub, index);
|
|
25
|
+
var toPublicKey = bip32Ed25519.toPublic(derivedPrivateKey);
|
|
25
26
|
|
|
26
27
|
should.equal(derivedPublicKey.toString('hex'), toPublicKey.toString('hex'));
|
|
27
28
|
|
|
@@ -30,8 +31,8 @@ describe('derive', function() {
|
|
|
30
31
|
should.equal(derivedPublicKey.slice(0, 32).toString('hex'), publicKey.toString('hex'));
|
|
31
32
|
|
|
32
33
|
var message = Buffer.from('hello world');
|
|
33
|
-
var sig =
|
|
34
|
-
var verify =
|
|
34
|
+
var sig = bip32Ed25519.sign(message, derivedPrivateKey);
|
|
35
|
+
var verify = bip32Ed25519.verify(message, sig, derivedPublicKey);
|
|
35
36
|
should.equal(verify, true, 'verify failed: index=' + index)
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -42,33 +43,60 @@ describe('derive', function() {
|
|
|
42
43
|
var seed = Buffer.from('3660a6289d878f317fa7b180ce0b375178bd5ffe0ada03fca6905255fe25028166c802750d85f90bb0123b07608bbcfbc6b1be84519d68f37935e2a2a4b43cfe', 'hex');
|
|
43
44
|
var path = 'm/53686/60791/4984';
|
|
44
45
|
|
|
45
|
-
var xprv =
|
|
46
|
+
var xprv = bip32Ed25519.generateFromSeed(seed);
|
|
46
47
|
console.log('xprv:', xprv.toString('hex'));
|
|
47
48
|
|
|
48
|
-
var xpub =
|
|
49
|
+
var xpub = bip32Ed25519.toPublic(xprv);
|
|
49
50
|
console.log('xpub:', xpub.toString('hex'));
|
|
50
51
|
|
|
51
52
|
var indexes = path.split('/').slice(1);
|
|
52
|
-
var xprv =
|
|
53
|
-
var xpub =
|
|
53
|
+
var xprv = bip32Ed25519.generateFromSeed(seed);
|
|
54
|
+
var xpub = bip32Ed25519.toPublic(xprv);
|
|
54
55
|
|
|
55
56
|
var derivedPrivateKey = xprv;
|
|
56
57
|
var derivedPublicKey = xpub;
|
|
57
58
|
|
|
58
59
|
for (var j = 0; j < indexes.length; j++) {
|
|
59
|
-
derivedPrivateKey =
|
|
60
|
-
derivedPublicKey =
|
|
60
|
+
derivedPrivateKey = bip32Ed25519.derivePrivate(derivedPrivateKey, parseInt(indexes[j]));
|
|
61
|
+
derivedPublicKey = bip32Ed25519.derivePublic(derivedPublicKey, parseInt(indexes[j]));
|
|
61
62
|
|
|
62
63
|
const keyPair = eddsa.keyFromSecret(derivedPrivateKey.slice(0, 32));
|
|
63
64
|
var publicKey = Buffer.from(keyPair.getPublic(true, true));
|
|
64
65
|
should.equal(derivedPublicKey.slice(0, 32).toString('hex'), publicKey.toString('hex'));
|
|
65
66
|
|
|
66
67
|
var message = Buffer.from('hello world');
|
|
67
|
-
var sig =
|
|
68
|
-
var verify =
|
|
68
|
+
var sig = bip32Ed25519.sign(message, derivedPrivateKey);
|
|
69
|
+
var verify = bip32Ed25519.verify(message, sig, derivedPublicKey);
|
|
69
70
|
should.equal(verify, true, 'verify failed')
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
done();
|
|
73
74
|
});
|
|
75
|
+
|
|
76
|
+
it('fromEntropy', function(done) {
|
|
77
|
+
const mnemonic = 'expire found smooth ride piece swamp blast model slot fiction under gate escape animal reform'
|
|
78
|
+
|
|
79
|
+
const path1 = "m/44'/1815'/0'"
|
|
80
|
+
const expectedPublicKey1 = "ac9f7fabfa177eb5f5c44ae2a6bf84ede53bdbc256db64f22e9bcfdd8a82fb14015b1f5744f995b434f26e597e7aeae8c053a59fcb69aedf5c8c218846063eff"
|
|
81
|
+
const path2 = "m/1852'/1815'/0'"
|
|
82
|
+
const expectedPublicKey2 = "6b8d464521e3c433c33837a7aca2b70baaef19d48b8984f7a0eba66e32f3b62aedbdac20b6aa6bef253c15f9779487d6a5601ec35b915070c5370dceee11bd56"
|
|
83
|
+
|
|
84
|
+
let key1 = bip32Ed25519.fromEntropy(Buffer.from(bip39.mnemonicToEntropy(mnemonic), 'hex'))
|
|
85
|
+
let arr1 = path1.split("/")
|
|
86
|
+
for (let i = 1; i < arr1.length; i++) {
|
|
87
|
+
key1 = bip32Ed25519.derivePrivate(key1, arr1[i].indexOf("'") > 0 ? (parseInt(arr1[i].slice(0, arr1[i].length - 1)) + 0x80000000) : parseInt(arr1[i]))
|
|
88
|
+
}
|
|
89
|
+
console.log(bip32Ed25519.toPublic(key1).toString('hex'))
|
|
90
|
+
should.equal(bip32Ed25519.toPublic(key1).toString('hex'), expectedPublicKey1);
|
|
91
|
+
|
|
92
|
+
let key2 = bip32Ed25519.fromEntropy(Buffer.from(bip39.mnemonicToEntropy(mnemonic), 'hex'))
|
|
93
|
+
let arr2 = path2.split("/")
|
|
94
|
+
for (let i = 1; i < arr2.length; i++) {
|
|
95
|
+
key2 = bip32Ed25519.derivePrivate(key2, arr2[i].indexOf("'") > 0 ? (parseInt(arr2[i].slice(0, arr2[i].length - 1)) + 0x80000000) : parseInt(arr2[i]))
|
|
96
|
+
}
|
|
97
|
+
console.log(bip32Ed25519.toPublic(key2).toString('hex'))
|
|
98
|
+
should.equal(bip32Ed25519.toPublic(key2).toString('hex'), expectedPublicKey2);
|
|
99
|
+
|
|
100
|
+
done();
|
|
101
|
+
});
|
|
74
102
|
});
|