This commit is contained in:
陆柯 2022-08-16 11:59:32 +08:00
commit 71eb5d5dce
2 changed files with 68 additions and 74 deletions

14
test.js
View File

@ -94,8 +94,8 @@ console.log('address = ', add)
/////////////////////// keyutil
let seckeyObject = new keyutil.Key('oct', Buffer.from(acc.seckey, 'hex'), { namedCurve: 'P-256K' }) // {P-256 : secp256r1, P-384 : secp384r1, P-521 : secp521r1, P-256K : secp256k1}
let seckeyObject2 = new keyutil.Key('oct', tic.hex_to_buf(acc.seckey, 'hex'), { namedCurve: 'P-256K' })
let seckeyObject = new keyutil.Key('oct', Buffer.from(acc.prikey, 'hex'), { namedCurve: 'P-256K' }) // {P-256 : secp256r1, P-384 : secp384r1, P-521 : secp521r1, P-256K : secp256k1}
let seckeyObject2 = new keyutil.Key('oct', tic.hex_to_buf(acc.prikey, 'hex'), { namedCurve: 'P-256K' })
let seckeyPEM
seckeyObject.export('pem').then((data) => (seckeyPEM = data))
let seckeyDER
@ -124,17 +124,17 @@ verifyKU.end()
var verified = verifyKU.verify(pubkeyPEM, signatureKU) // specify format in [pem,der] and type in [pkcs1,spki]
console.log('verified = ', verified) // 可以验证通过但是用的privatekey没有成功使用publickey。
crypto.createCipheriv('aes-256-cfb', Buffer.from(acc.seckey, 'hex'), Buffer.alloc(16))
crypto.createCipheriv('aes-256-cfb', Buffer.from(acc.prikey, 'hex'), Buffer.alloc(16))
////////////////////// crypto + PEM
toPEM = function (kp) {
let pubkey = crypto
.createECDH('secp256k1')
.setPrivateKey(kp.seckey, 'hex')
.setPrivateKey(kp.prikey, 'hex')
.getPublicKey('hex', 'compressed')
console.log('ECDH created publickey = ', pubkey)
let mykey = '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420' + kp.seckey + 'a144034200' + pubkey
let mykey = '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420' + kp.prikey + 'a144034200' + pubkey
console.log(mykey)
let privKey = '-----BEGIN PRIVATE KEY-----\n' + Buffer.from(mykey, 'hex').toString('base64') + '\n-----END PRIVATE KEY-----'
// pubKey2 = crypto.createPublicKey(privKey); //也可恢复出公钥。测试不成功。
@ -156,7 +156,7 @@ console.log('pemKP = ', pemKP)
// https://www.shangyang.me/2017/05/24/encrypt-rsa-keyformat/
var buf1 = Buffer.from('308141020100301306072a8648ce3d020106082a8648ce3d030107042730250201010420', 'hex') // specific byte-sequence for curve prime256v1
var buf2 = Buffer.from(acc.seckey, 'hex') // raw private key (32 bytes)
var buf2 = Buffer.from(acc.prikey, 'hex') // raw private key (32 bytes)
var privateKeyPkcs8Der = Buffer.concat([buf1, buf2], buf1.length + buf2.length)
var sign = crypto.createSign('sha256')
sign.write('毛主席万岁')
@ -186,7 +186,7 @@ var EC = require('elliptic').ec
var ec = new EC('secp256k1')
// Generate keys
//var key = ec.genKeyPair();
var key = ec.keyFromPrivate(acc.seckey) // 注意,不需要 'hex' 参数
var key = ec.keyFromPrivate(acc.prikey) // 注意,不需要 'hex' 参数
// Sign the message's hash (input must be an array, or a hex-string)
var msgHash = tic.hash('毛主席万岁')
var msgHashBad = tic.hash('毛主席万岁 ')

128
ticc.js
View File

@ -138,14 +138,14 @@ class TicCrypto {
* 测试是否合法的私钥
*
* @static
* @param {String} seckey
* @param {String} prikey
* @return {Boolean}
* @memberof TicCrypto
*/
static is_seckey ({ seckey } = {}) {
static is_seckey ({ prikey } = {}) {
// 比特币、以太坊的私钥64 hex
// nacl.sign 的私钥 128 hex, nacl.box 的私钥 64 hex
return /^([a-fA-F0-9]{128}|[a-fA-F0-9]{64})$/.test(seckey)
return /^([a-fA-F0-9]{128}|[a-fA-F0-9]{64})$/.test(prikey)
}
/**
@ -208,7 +208,7 @@ class TicCrypto {
* @return {String}
* @memberof TicCrypto
*/
static async encrypt_easy ({ data, tool = 'crypto', keytype = 'pwd', key, input, output, cipher } = {}) {
static async encrypt_easy ({ data, tool = 'crypto', keytype = 'pwd', key, input = my.INPUT, output = my.OUTPUT, cipher = my.CIPHER } = {}) {
if (tool === 'eccrypto') {
// data 应当是 utf8 的字符串。key 必须是 pubkey
// eccrypto 能用 Uint8Array 和 Buffer
@ -219,17 +219,17 @@ class TicCrypto {
} else if (keytype === 'pwd') {
// 对称加密
if (typeof key === 'string') {
let inputEncoding = my.INPUT_LIST.includes(input) ? input : my.INPUT // 'utf8' by default, 'ascii', 'latin1' for string or ignored for Buffer/TypedArray/DataView
let outputEncoding = output === 'buf' ? undefined : my.OUTPUT_LIST.includes(output) ? output : my.OUTPUT // 'latin1', 'base64', 'hex' by default or 'buf' to Buffer explicitly
let inputEncoding = input // 'utf8' by default, 'ascii', 'latin1' for string or ignored for Buffer/TypedArray/DataView
let outputEncoding = output === 'buf' ? undefined : output // 'latin1', 'base64', 'hex' by default or 'buf' to Buffer explicitly
const iv = crypto.randomBytes(16)
let encryptor = crypto.createCipheriv(my.CIPHER_LIST.includes(cipher) ? cipher : my.CIPHER, this.hex_to_buf(this.hash_easy(key)), iv) // cipher 和 key 的长度必须相同,例如 cipher 是 ***-192那么 key 就必须是 192/8=24 字节 = 48 hex 的。
let encryptor = crypto.createCipheriv(cipher, this.hex_to_buf(this.hash_easy(key)), iv) // cipher 和 key 的长度必须相同,例如 cipher 是 ***-192那么 key 就必须是 192/8=24 字节 = 48 hex 的。
if (typeof data !== 'string' && !(data instanceof Buffer) && !(data instanceof DataView)) data = JSON.stringify(data)
let ciphertext = encryptor.update(data, inputEncoding, outputEncoding)
ciphertext += encryptor.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string
return { iv: iv.toString('hex'), ciphertext } // 有 iv显然每次结果不一样
}
} else if (keytype === 'seckey') {
// 尚未走通,不能使用 ticc 生成的 Elliptic curve 椭圆曲线算法公私钥,只能用 crypto.generateKeyPair('rsa') 生成的 rsa 公私钥
} else if (keytype === 'prikey') {
// 尚未走通,不能使用 ticc 生成的 Elliptic curve 椭圆曲线算法公私钥,只能用 crypto.generateKeyPairSync('rsa') 生成的 rsa 公私钥
let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(key), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。
return crypto.privateEncrypt(seckeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果都一样。
} else if (keytype === 'pubkey') {
@ -248,7 +248,7 @@ class TicCrypto {
* @return {String}
* @memberof TicCrypto
*/
static async decrypt_easy ({ data = {}, tool = 'crypto', keytype = 'pwd', key, input, output, cipher } = {}) {
static async decrypt_easy ({ data = {}, tool = 'crypto', keytype = 'pwd', key, input = my.OUTPUT, output = my.OUTPUT, cipher = my.CIPHER } = {}) {
// data 应当是 encrypt 输出的数据类型
if (tool === 'eccrypto') {
try {
@ -264,19 +264,15 @@ class TicCrypto {
} else if (keytype === 'pwd') {
// 对称解密
if ((typeof data.ciphertext === 'string' || data.ciphertext instanceof Buffer) && typeof key === 'string') {
let inputEncoding = my.OUTPUT_LIST.includes(input) ? input : my.OUTPUT // input (=output of encrypt) could be 'latin1', 'base64', 'hex' by default for string or ignored for Buffer
let outputEncoding = output === 'buf' ? undefined : my.INPUT_LIST.includes(output) ? output : my.INPUT // output (=input of encrypt) could be 'latin1', 'ascii', 'utf8' by default or 'buf' to Buffer explicitly
let decryptor = crypto.createDecipheriv(
my.CIPHER_LIST.includes(cipher) ? cipher : my.CIPHER,
this.hex_to_buf(this.hash_easy(key)),
Buffer.from(data.iv, 'hex')
)
let inputEncoding = input // input (=output of encrypt) could be 'latin1', 'base64', 'hex' by default for string or ignored for Buffer
let outputEncoding = output === 'buf' ? undefined : output // output (=input of encrypt) could be 'latin1', 'ascii', 'utf8' by default or 'buf' to Buffer explicitly
let decryptor = crypto.createDecipheriv(cipher, this.hex_to_buf(this.hash_easy(key)), Buffer.from(data.iv, 'hex'))
let decrypted = decryptor.update(data.ciphertext, inputEncoding, outputEncoding)
decrypted += decryptor.final(outputEncoding) // 但是 Buffer + Buffer 还是会变成string
// 如果用户输入错误密码deciper也能解密无法自动判断是否正确结果。可在返回后人工判断。
return decrypted
}
} else if (keytype === 'seckey') {
} else if (keytype === 'prikey') {
// 尚未走通,不能使用 ticc 生成的 Elliptic curve 椭圆曲线算法公私钥
let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(key), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。
return crypto.privateDecrypt(seckeyPEM, Buffer.from(data)) // 返回 Buffer。每次结果都一样。
@ -292,31 +288,31 @@ class TicCrypto {
*
* @static
* @param {*} data
* @param {String} seckey
* @param {String} prikey
* @param {Object} option [option={}]
* @return {String}
* @memberof TicCrypto
*/
static async sign_easy ({ data, seckey, tool = 'crypto', hasher }) {
static async sign_easy ({ data, prikey, tool = 'crypto', hasher = my.HASHER }) {
// data can be string or buffer or object, results are the same
if (this.is_hashable({ data }) && this.is_seckey({ seckey })) {
if (tool === 'nacl' && seckey.length === 128) {
if (this.is_hashable({ data }) && this.is_seckey({ prikey })) {
if (tool === 'nacl' && prikey.length === 128) {
// 使用nacl的签名算法。注意nacl.sign需要的seckey是64字节=128字符。
let hashBuf = this.hash_easy(data, { output: 'buf' }) // 哈希必须输出为 buffer
let signature = nacl.sign.detached(hashBuf, Buffer.from(seckey, 'hex'))
let signature = nacl.sign.detached(hashBuf, Buffer.from(prikey, 'hex'))
return Buffer.from(signature).toString('hex') // 签名是64节128个hex字符
} else if (tool === 'eccrypto' && seckey.length === 64) {
} else if (tool === 'eccrypto' && prikey.length === 64) {
// eccrypto 对同一组data,seckey生成的签名是固定的观察到hex长度为140或142是der格式。
let signature = await eccrypto.sign(Buffer.from(seckey, 'hex'), this.hash_easy(data, { output: 'buf' }))
let signature = await eccrypto.sign(Buffer.from(prikey, 'hex'), this.hash_easy(data, { output: 'buf' }))
return signature.toString('hex')
} else if (seckey.length === 64) {
} else if (prikey.length === 64) {
// 纯 crypto
let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(seckey), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。
let signer = crypto.createSign(my.HASHER_LIST.includes(hasher) ? hasher : my.HASHER) // 注意不知为何hasher必须含有'sha'才能完成签名,例如 sha1, sha256, sha512, sha3, RSA-SHA1, id-rsassa-pkcs1-v1_5-with-sha3-224, 其他都会报错。
let seckeyPEM = await new keyman.Key('oct', this.hex_to_buf(prikey), { namedCurve: 'P-256K' }).export('pem') // 私钥导出的der格式为144字节。
let signer = crypto.createSign(hasher) // 注意不知为何hasher必须含有'sha'才能完成签名,例如 sha1, sha256, sha512, sha3, RSA-SHA1, id-rsassa-pkcs1-v1_5-with-sha3-224, 其他都会报错。
signer.update(this.hash_easy(data)).end()
let signature = signer.sign(seckeyPEM, 'hex')
// since nodejs 12, 有了 crypto.sign 方法,但在浏览器中无效:
// let signature = crypto.sign(my.HASHER_LIST.includes(hasher) ? hasher : my.HASHER, Buffer.from(this.hash_easy(data)), seckeyPEM).toString('hex')
// let signature = crypto.sign(hasher, Buffer.from(this.hash_easy(data)), seckeyPEM).toString('hex')
return signature // 发现同样的输入nodejs里每次调用会生成不同的 signature, 且长度不定(140,142,144 hex) 但都可以通过 verify。但在浏览器里调用signature却是固定的。
}
}
@ -334,7 +330,7 @@ class TicCrypto {
* @return {Boolean}
* @memberof TicCrypto
*/
static async verify_easy ({ data, signature, pubkey, tool = 'crypto', hasher }) {
static async verify_easy ({ data, signature, pubkey, tool = 'crypto', hasher = my.HASHER }) {
// data could be anything, but converts to string or remains be Buffer/TypedArray/DataView
if (this.is_hashable({ data }) && this.is_signature({ sig: signature }) && this.is_pubkey({ pubkey })) {
if ('nacl' === tool && signature.length === 128) {
@ -355,11 +351,11 @@ class TicCrypto {
} else if (signature.length >= 140) {
// 纯 crypto // 发现大小写不影响 crypto 验签!都能通过
let pubkeyPEM = await new keyman.Key('oct', this.hex_to_buf(pubkey), { namedCurve: 'P-256K' }).export('pem') // 公钥导出的der格式为88字节。经测试同一对压缩和非压缩公钥得出的结果一模一样。
let verifier = crypto.createVerify(my.HASHER_LIST.includes(hasher) ? hasher : my.HASHER)
let verifier = crypto.createVerify(hasher)
verifier.update(this.hash_easy(data)).end() // end() 在 nodejs 12 里返回verifier自身但在浏览器里返回 undefined因此不能串联运行。
let verified = verifier.verify(pubkeyPEM, signature, 'hex') // 如果给signature添加1位hexcrypto 的 verify结果也是true! 估计因为一位hex不被转成字节。但减少1位会导致false
// since nodejs 12, 有了 crypto.verify 方法,但在浏览器中无效:
// let verified = crypto.verify(my.HASHER_LIST.includes(hasher) ? hasher : my.HASHER, Buffer.from(this.hash_easy(data)), pubkeyPEM, Buffer.from(signature, 'hex'))
// let verified = crypto.verify(hasher, Buffer.from(this.hash_easy(data)), pubkeyPEM, Buffer.from(signature, 'hex'))
return verified
}
}
@ -372,13 +368,12 @@ class TicCrypto {
* @static
* @param {String} pass
* @param {Object} option
* @return {Object} {pubkey, seckey, address,}
* @return {Object} {pubkey, prikey, address,}
* @memberof TicCrypto
*/
static pass_to_keypair ({ pass, hasher } = {}) {
static pass_to_keypair ({ pass, hasher = my.HASHER } = {}) {
// 如果使用其他机制例如密码、随机数不使用secword也可生成keypair
if (this.is_hashable({ data: pass })) {
hasher = my.HASHER_LIST.includes(hasher) ? hasher : my.HASHER
var hashBuf = crypto
.createHash(hasher)
.update(pass)
@ -387,7 +382,7 @@ class TicCrypto {
return {
hash: hashBuf.toString('hex'),
pubkey: Buffer.from(keypair.publicKey).toString('hex'), // 测试过 不能直接keypair.publicKey.toString('hex')不是buffer类型
seckey: Buffer.from(keypair.secretKey).toString('hex'),
prikey: Buffer.from(keypair.secretKey).toString('hex'),
}
}
return null
@ -430,10 +425,10 @@ class TicCrypto {
* @static
* @param {String} secword
* @param {Object} option
* @return {Object} {pubkey, seckey,}
* @return {Object} {pubkey, prikey,}
* @memberof TicCrypto
*/
static secword_to_keypair ({ secword, coin, pass, pathRoot, pathIndex, path, tool, hasher } = {}) {
static secword_to_keypair ({ secword, coin, pass, pathRoot, pathIndex, path, tool, hasher = my.HASHER } = {}) {
// coin 币种;
// passphase 密码,默认为空;
// path 规范为 m/Purpose'/CoinType'/Account'/Change/Index (https://learnblockchain.cn/2018/09/28/hdwallet/), 其中
@ -452,7 +447,6 @@ class TicCrypto {
}
if (tool === 'nacl') {
// 采用自己的算法bip39算法从secword到种子hash后用 nacl.sign.keyPair.fromSeed()方法。
hasher = my.HASHER_LIST.includes(hasher) ? hasher : my.HASHER
let hashBuf = crypto
.createHash(hasher)
.update(this.secword_to_seed({ secword, pass }))
@ -460,7 +454,7 @@ class TicCrypto {
let keypair = nacl.sign.keyPair.fromSeed(hashBuf) // nacl.sign.keyPair.fromSeed 要求32字节的种子而 this.secword2seed生成的是64字节种子所以要先做一次sha256
return {
pubkey: Buffer.from(keypair.publicKey).toString('hex'), // 测试过 不能直接keypair.publicKey.toString('hex')不是buffer类型
seckey: Buffer.from(keypair.secretKey).toString('hex'), // nacl.sign.keyPair.fromSeed 得到的 seckey 是64字节的不同于比特币/以太坊的32字节密钥。
prikey: Buffer.from(keypair.secretKey).toString('hex'), // nacl.sign.keyPair.fromSeed 得到的 prikey 是64字节的不同于比特币/以太坊的32字节密钥。
tool,
}
} else {
@ -482,7 +476,7 @@ class TicCrypto {
}
return {
path,
seckey: key.privateKey.toString('hex'), // 或者 key.toJSON().privateKey。或者 key.privateKey.slice(2) 删除开头的'0x'如果是ethers.HDNode.fromMnemonic(secword)的结果
prikey: key.privateKey.toString('hex'), // 或者 key.toJSON().privateKey。或者 key.privateKey.slice(2) 删除开头的'0x'如果是ethers.HDNode.fromMnemonic(secword)的结果
pubkey: key.publicKey.toString('hex'),
}
}
@ -600,29 +594,29 @@ class TicCrypto {
* 从私钥到公钥
*
* @static
* @param {*} seckey
* @param {*} prikey
* @param {*} [option={}]
* @return {*}
* @memberof TicCrypto
*/
static seckey_to_pubkey ({ seckey, curve, compress } = {}) {
if (this.is_seckey({ seckey }) && seckey.length === 64) {
static seckey_to_pubkey ({ prikey, curve, compress } = {}) {
if (this.is_seckey({ prikey }) && prikey.length === 64) {
// 只能用于32字节的私钥BTC, ETH)。也就是不能用于 TIC 的私钥。
curve = my.CURVE_LIST.includes(curve) ? curve : my.CURVE // 默认为 secp256k1
// return new crypto.createECDH(curve).setPrivateKey(seckey,'hex').getPublicKey('hex', compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错TypeError: null is not an object (evaluating 'this.rand.getBytes')
// return new crypto.createECDH(curve).setPrivateKey(prikey,'hex').getPublicKey('hex', compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错TypeError: null is not an object (evaluating 'this.rand.getBytes')
// 从 nodejs 10.0 开始,还有 crypto.ECDH.convertKey 方法,更直接。但可惜,浏览器里不存在 crypto.ECDH。
return this.buf_to_hex(secp256k1.publicKeyCreate(Buffer.from(seckey, 'hex'), compress !== false)) // 可用于浏览器。缺省输出压缩公钥compress=false时输出非压缩公钥。
// 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(seckey)).toString('hex') // 可用于浏览器
return this.buf_to_hex(secp256k1.publicKeyCreate(Buffer.from(prikey, 'hex'), compress !== false)) // 可用于浏览器。缺省输出压缩公钥compress=false时输出非压缩公钥。
// 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(prikey)).toString('hex') // 可用于浏览器
// 或者 const ecc = require('eccrypto')
// if (compress===false){
// return ecc.getPublic(this.hex_to_buf(seckey)).toString('hex')
// return ecc.getPublic(this.hex_to_buf(prikey)).toString('hex')
// }else{
// return ecc.getPublicCompressed(this.hex_to_buf(seckey)).toString('hex')
// return ecc.getPublicCompressed(this.hex_to_buf(prikey)).toString('hex')
// }
// 注意Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(seckey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同
} else if (this.is_seckey({ seckey }) && seckey.length === 128) {
// 注意Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(prikey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同
} else if (this.is_seckey({ prikey }) && prikey.length === 128) {
// 用于64字节=128 hex的 TIC 私钥
let keypair = nacl.sign.keyPair.fromSecretKey(Buffer.from(seckey, 'hex'))
let keypair = nacl.sign.keyPair.fromSecretKey(Buffer.from(prikey, 'hex'))
return Buffer.from(keypair.publicKey).toString('hex') // 测试过 不能直接keypair.publicKey.toString('hex')不是buffer类型
}
return null
@ -632,21 +626,21 @@ class TicCrypto {
* 从私钥到地址
*
* @static
* @param {*} seckey
* @param {*} prikey
* @param {*} option
* @return {*}
* @memberof TicCrypto
*/
static seckey_to_address ({ seckey, coin, world } = {}) {
static seckey_to_address ({ prikey, coin, world } = {}) {
coin = coin?.toUpperCase() || my.COIN
if (this.is_seckey({ seckey })) {
if (this.is_seckey({ prikey })) {
/** @type {*} */
let pubkey
if (coin === 'ETH') {
pubkey = this.seckey_to_pubkey({ seckey, compress: false })
pubkey = this.seckey_to_pubkey({ prikey, compress: false })
return this.pubkey_to_address({ pubkey: pubkey, coin, world })
} else {
pubkey = this.seckey_to_pubkey({ seckey, compress: true })
pubkey = this.seckey_to_pubkey({ prikey, compress: true })
return this.pubkey_to_address({ pubkey: pubkey, coin, world })
}
}
@ -677,13 +671,13 @@ class TicCrypto {
.digest('hex')
.slice(-40)
} else {
let h256 = crypto
let h256buf = crypto
.createHash('sha256')
.update(Buffer.from(pubkey, 'hex'))
.digest()
let h160 = crypto
.createHash('ripemd160')
.update(h256)
.update(h256buf)
.digest('hex')
return h160
}
@ -921,14 +915,14 @@ class TicCrypto {
kp = nacl.sign.keyPair()
}
return {
seckey: Buffer.from(kp.secretKey).toString('hex'),
prikey: Buffer.from(kp.secretKey).toString('hex'),
pubkey: Buffer.from(kp.publicKey).toString('hex'),
}
} else {
let seckey = this.randomize_seckey()
let pubkey = this.seckey_to_pubkey({ seckey })
let prikey = this.randomize_seckey()
let pubkey = this.seckey_to_pubkey({ prikey })
return {
seckey,
prikey,
pubkey,
}
}
@ -1027,14 +1021,14 @@ class TicCrypto {
* @return {*}
* @memberof TicCrypto
*/
static get_merkle_hash ({ hashList, output, hasher } = {}) {
static get_merkle_hash ({ hashList, output = my.OUTPUT, hasher = my.HASHER } = {}) {
// merkle算法略有难度暂时用最简单的hash代替
if (Array.isArray(hashList)) {
myhasher = crypto.createHash(my.HASHER_LIST.includes(hasher) ? hasher : my.HASHER)
for (var hash of hashList) {
const myhasher = crypto.createHash(hasher)
for (let hash of hashList) {
myhasher.update(hash)
}
return myhasher.digest(output === 'buf' ? undefined : output || my.OUTPUT)
return myhasher.digest(output === 'buf' ? undefined : output)
}
return null
}