OSDN Git Service

Merge branch 'dapp-v1.4.0' into dev
[bytom/Bytom-JS-SDK.git] / src / utils / account.js
1 var scrypt = require('scrypt-js');
2 var cryp = require('crypto-browserify');
3 var sha3_256 = require('js-sha3').sha3_256;
4 var _ = require('lodash')
5 var ED25519 =require('./ed25519');
6 var Curve25519 = new ED25519.Curve;
7
8 function decrypt(v3Keystore, password) {
9     /* jshint maxcomplexity: 10 */
10
11     if (!_.isString(password)) {
12         throw new Error('No password given.');
13     }
14
15     var json = (_.isObject(v3Keystore)) ? v3Keystore : JSON.parse(v3Keystore);
16     var derivedKey;
17     var kdfparams;
18     if (json.crypto.kdf === 'scrypt') {
19         kdfparams = json.crypto.kdfparams;
20
21         // FIXME: support progress reporting callback
22         derivedKey = scrypt.syncScrypt(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.n, kdfparams.r, kdfparams.p, kdfparams.dklen);
23     } else if (json.crypto.kdf === 'pbkdf2') {
24         kdfparams = json.crypto.kdfparams;
25
26         if (kdfparams.prf !== 'hmac-sha256') {
27             throw new Error('Unsupported parameters to PBKDF2');
28         }
29
30         derivedKey = cryp.pbkdf2Sync(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.c, kdfparams.dklen, 'sha3256');
31     } else {
32         throw new Error('Unsupported key derivation scheme');
33     }
34
35     var ciphertext = Buffer.from(json.crypto.ciphertext, 'hex');
36
37     var mac = sha3_256(Buffer.concat([Buffer(derivedKey.slice(16, 32)), ciphertext]));
38     if (mac !== json.crypto.mac) {
39         throw new Error('Key derivation failed - possibly wrong password');
40     }
41
42     var decipher = cryp.createDecipheriv(json.crypto.cipher, derivedKey.slice(0, 16), Buffer.from(json.crypto.cipherparams.iv, 'hex'));
43     var privateKey = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
44
45     return privateKey;
46 };
47
48 function scalarmult_base (q){
49     var base = Curve25519.point().base();
50     var scalar = Curve25519.scalar().setBytes(new Uint8Array(q));
51     var target = Curve25519.point().mul(scalar, base);
52
53     return target.toString();
54 }
55
56 export function restoreFromKeyStore(v3Keystore, password){
57     const privatekey = decrypt(v3Keystore, password);
58     const publickey = scalarmult_base(privatekey.slice(0, privatekey.length/2)) + privatekey.slice(privatekey.length/2, privatekey.length).toString('hex')
59
60     return publickey;
61 }