jsrsasign 有異常
const bip39 = require('bip39')
const bip32 = require('bip32');
const bitcoinSecp256r1 = require('bitcoinjs-lib')
const ethUtil = require('ethereumjs-util')
const EC = require('elliptic').ec;
// bitcoinSecp256r1.HDNode.fromSeedBuffer 無法使用,目前正確應該是用 bitcoinSecp256r1.bip32.fromSeed
mnemonic = "簡 熙 夢 幾 聲 可 高 汪 煙 版 統 仇"
path = "m/2018'/5'/1'/0/1"
type = "secp256r1"
// 驗證網頁 https://iancoleman.io/bip39/#chinese_traditional
if (bip39.validateMnemonic(mnemonic)) { console.log("mnemonic is fake!") }
const seed = bip39.mnemonicToSeed(mnemonic).then((vseed)=>{
var root = bip32.fromSeed(vseed)
var PathNode = root.derivePath(path)
console.log("---------------------------------------------")
console.log("# PATH 是 m/2018'/5'/1'/0/1/ \n")
console.log("Bitcoin Address: %o 符合 \n", getAddress(PathNode)) // 1GcgQJN7XgqkZkQcD4dzaZ7bjCFvQ6wxF2 符合 m/2018'/5'/1'/0/1
console.log("root toWIF: %o", root.toWIF())
console.log("PathNode toWIF: %o 符合", PathNode.toWIF()) // Kzq7FAYiWjDAcwU44FvcyCsCpJyLCD19n13FyQgLY6oBNajYcAYz 符合 m/2018'/5'/1'/0/1
console.log("--------------------------------------------- \n")
// 底下為derive(0),所以正確是 m/2018'/5'/1'/0/1/0 為 path + '/0'
console.log("---------------------------------------------")
console.log("# PATH 是 m/2018'/5'/1'/0/1/0 因為底下為derive(0),所以 path + '/0' \n")
console.log("privateKey (WIF): %o 符合", PathNode.derive(0).toWIF()) // L5ccMER4KyRn6pY6amvrFAHacpEsKrH1eTjDNeWwgXMnqjSCUU6N 符合
console.log("privateKey (Buffer): %o", PathNode.derive(0).privateKey)
console.log("privateKey (String): %o", PathNode.derive(0).privateKey.toString())
console.log("privateKey (Hex): %o", PathNode.derive(0).privateKey.toString('hex'))
console.log("privatekeyHex: %o \n", PathNode.derive(0).privkeyHex)
console.log("publicKey (Hex): %o 符合", PathNode.derive(0).publicKey.toString('hex')) //024ac10a81e3a0f86cb4dad68c6a26031d805a057f36048f80a5b91b1c2cb0588c 符合
console.log("Bitcoin Address: %o 符合", getAddress(PathNode.derive(0))) //1Gp8AuHiYyBixrvLkKtC4VDhxpvK8PmYEr 符合
console.log("--------------------------------------------- \n")
console.log('\n-----elliptic Initial Start----- \n');
var ec = new EC('p256');
let keyPair = ec.keyFromPrivate("83CFCC6EF1864C3303A5F8DEF2540167CB2DFA5DD22BB8D197B396972525FD56")
let pubKey = keyPair.getPublic();
console.log("pubKey: %o", pubKey)
// https://github.com/kjur/jsrsasign/issues/394
// sha512('aaa') => d6f644b19812e97b5d871658d6d3400ecd4787faeb9b8990c1e7608288664be77257104a58d033bcf1a0e0945ff06468ebe53e2dff36e248424c7273117dac09
let msgHash = 'd6f644b19812e97b5d871658d6d3400ecd4787faeb9b8990c1e7608288664be7'
let signatureBase64 = 'MEUCIBEcfv2o3UwqwV72CVuYi7HbjcoiuSQOULY5d+DuGt3UAiEAtoNrdNWvjfdz/vR6nPiD+RveKN5znBtYaIrRDp2K7Ks='
let signatureHex = Buffer.from(signatureBase64, 'base64').toString('hex');
let validSig = ec.verify(msgHash, signatureHex, pubKey);
console.log("Signature valid? %o \n", validSig);
// use json
var ec = new EC('secp256k1');
keyPair = ec.keyFromPrivate(dkey.publicKey)
pubKey = keyPair.getPublic();
console.log("pubKey: %o", pubKey)
var signature = keyPair.sign(json);
var derSign = signature.toDER();
//console.log("signature: %o", signature)
console.log("json verify: %o", keyPair.verify(json, derSign));
console.log('\n-----elliptic ed25519 Start----- \n');
var EdDSA = require('elliptic').eddsa
var ec2 = new EdDSA('ed25519');
var ec2keypair = ec2.keyFromSecret(dkey.privateKey)
//console.log("key: %o", key)
var signature = ec2keypair.sign(json).toHex();
console.log("signature: %o", signature)
var privateKeyHex = new Buffer(ec2keypair.getSecret()).toString('hex')
var publickeyHex = new Buffer(ec2keypair.getPublic()).toString('hex')
console.log("private key hex: %o", privateKeyHex)
console.log("public key hex: %o", publickeyHex)
var ec2keypair2 = ec2.keyFromPublic(publickeyHex, 'hex');
console.log("EdDSA json verify: %o", ec2keypair2.verify(json, signature));
bip39.mnemonicToSeed(mnemonic).then((vseed)=>{
var root = bitcoinSecp256r1.bip32.fromSeed(vseed)
var PathNode = root.derivePath(path)
console.log("bitcoinSecp256r1 privateKey (Hex): %o", PathNode.derive(0).privateKey.toString('hex'))
console.log("bitcoinSecp256r1 publicKey (Hex): %o", PathNode.derive(0).publicKey.toString('hex'))
const buf = Buffer.allocUnsafe(32);
new Buffer.from(msgHash).copy(buf, 0, 0, 32)
//msgbuf32 = new Buffer("01234567890123456789012345678901")
console.log("msgHash buf 32: %o", buf.toString("hex"))
var ecPair = bitcoinSecp256r1.ECPair.fromPrivateKey(PathNode.derive(0).privateKey)
var signstring = ecPair.sign(buf)
console.log("signstring: %o", signstring.toString("hex"))
var verifyresult = ecPair.verify(buf, signstring)
console.log("verify: %o", verifyresult)
})
})
DeriveKey(mnemonic, path, type).then((v)=>{
console.log("dkey: %o", v)
});
function getAddress (node, network) {
return bitcoinSecp256r1.payments.p2pkh({ pubkey: node.publicKey, network }).address
}
function getEthereumAddress(privkeyHex) {
const hexAddress = ethUtil.privateToAddress(Buffer.from(privkeyHex, 'hex')).toString('hex')
const checksumAddress = ethUtil.toChecksumAddress(hexAddress)
return checksumAddress
}
function DeriveKey(mnemonic, derivePath, type) {
switch (type) {
case "secp256r1":
if (bip39.validateMnemonic(mnemonic)) { console.log("mnemonic is fake!") }
return bip39.mnemonicToSeed(mnemonic).then((vseed)=>{
var root = bip32.fromSeed(vseed)
var PathNode = root.derivePath(derivePath)
console.log("# PATH 是 m/2018'/5'/1'/0/1/0 因為底下為derive(0),所以 path + '/0' \n")
console.log("privateKey (Hex): %o", PathNode.derive(0).privateKey.toString('hex'))
console.log("publicKey (Hex): %o 符合", PathNode.derive(0).publicKey.toString('hex')) // 024ac10a81e3a0f86cb4dad68c6a26031d805a057f36048f80a5b91b1c2cb0588c 符合
const buf = Buffer.allocUnsafe(32);
PathNode.derive(0).privateKey.copy(buf, 0, 0, 32)
console.log("Ethereum Address: %o 符合", getEthereumAddress(buf.toString('hex')) ) // 0xe020343a09086F53a203c9A0Ea76010049399575 符合
return {
pub_buf: PathNode.derive(0).publicKey,
wif: PathNode.derive(0).toWIF(),
publicKey: PathNode.derive(0).publicKey.toString('hex'),
privateKey: PathNode.derive(0).privateKey.toString('hex'),
ethAddress: getEthereumAddress(buf.toString('hex')),
path: derivePath
}
}).catch((e) => {
console.log('handle error here: ', e.message)
})
break;
default:
throw "type should be secp256k1 or secp256r1";
}
}