UNPKG

nel-neo-thinsdk

Version:
369 lines (335 loc) 16.7 kB
module ThinNeo { declare var scrypt: any; var scrypt_loaded: boolean = false; var CryptoJS = require('crypto-js'); var Buffer = require("buffer"); export class Helper { public static GetPrivateKeyFromWIF(wif: string): Uint8Array { if (wif == null) throw new Error("null wif"); var data = Neo.Cryptography.Base58.decode(wif); //检查标志位 if (data.length != 38 || data[0] != 0x80 || data[33] != 0x01) throw new Error("wif length or tag is error"); //取出检验字节 var sum = data.subarray(data.length - 4, data.length); var realdata = data.subarray(0, data.length - 4); //验证,对前34字节进行进行两次hash取前4个字节 var _checksum = Neo.Cryptography.Sha256.computeHash(realdata); var checksum = new Uint8Array(Neo.Cryptography.Sha256.computeHash(_checksum)); var sumcalc = checksum.subarray(0, 4); for (var i = 0; i < 4; i++) { if (sum[i] != sumcalc[i]) throw new Error("the sum is not match."); } var privateKey = data.subarray(1, 1 + 32); return privateKey; } public static GetWifFromPrivateKey(prikey: Uint8Array): string { var data = new Uint8Array(38); data[0] = 0x80; data[33] = 0x01; for (var i = 0; i < 32; i++) { data[i + 1] = prikey[i]; } var realdata = data.subarray(0, data.length - 4); var _checksum = Neo.Cryptography.Sha256.computeHash(realdata); var checksum = new Uint8Array(Neo.Cryptography.Sha256.computeHash(_checksum)); for (var i = 0; i < 4; i++) { data[34 + i] = checksum[i]; } var wif = Neo.Cryptography.Base58.encode(data); return wif; } public static GetPublicKeyFromPrivateKey(privateKey: Uint8Array): Uint8Array { var pkey = Neo.Cryptography.ECPoint.multiply(Neo.Cryptography.ECCurve.secp256r1.G, privateKey); return pkey.encodePoint(true); } public static Hash160(data: Uint8Array): Uint8Array { var hash1 = Neo.Cryptography.Sha256.computeHash(data); var hash2 = Neo.Cryptography.RIPEMD160.computeHash(hash1); return new Uint8Array(hash2); } public static GetAddressCheckScriptFromPublicKey(publicKey: Uint8Array): Uint8Array { var script = new Uint8Array(publicKey.length + 2); script[0] = publicKey.length; for (var i = 0; i < publicKey.length; i++) { script[i + 1] = publicKey[i]; }; script[script.length - 1] = 172;//CHECKSIG return script; } public static GetPublicKeyScriptHashFromPublicKey(publicKey: Uint8Array): Uint8Array { var script = Helper.GetAddressCheckScriptFromPublicKey(publicKey); var scripthash = Neo.Cryptography.Sha256.computeHash(script); scripthash = Neo.Cryptography.RIPEMD160.computeHash(scripthash); return new Uint8Array(scripthash); } public static GetScriptHashFromScript(script: Uint8Array): Uint8Array { var scripthash = Neo.Cryptography.Sha256.computeHash(script); scripthash = Neo.Cryptography.RIPEMD160.computeHash(scripthash); return new Uint8Array(scripthash); } public static GetAddressFromScriptHash(scripthash: Uint8Array): string { var data = new Uint8Array(scripthash.length + 1); data[0] = 0x17; for (var i = 0; i < scripthash.length; i++) { data[i + 1] = scripthash[i]; } var hash = Neo.Cryptography.Sha256.computeHash(data); hash = Neo.Cryptography.Sha256.computeHash(hash); var hashu8 = new Uint8Array(hash, 0, 4); var alldata = new Uint8Array(data.length + 4); for (var i = 0; i < data.length; i++) { alldata[i] = data[i]; } for (var i = 0; i < 4; i++) { alldata[data.length + i] = hashu8[i]; } return Neo.Cryptography.Base58.encode(alldata); } public static GetAddressFromPublicKey(publicKey: Uint8Array): string { var scripthash = Helper.GetPublicKeyScriptHashFromPublicKey(publicKey); return Helper.GetAddressFromScriptHash(scripthash); } public static GetPublicKeyScriptHash_FromAddress(address: string): Uint8Array { var array: Uint8Array = Neo.Cryptography.Base58.decode(address); var salt = array.subarray(0, 1); var hash = array.subarray(1, 1 + 20); var check = array.subarray(21, 21 + 4); var checkdata = array.subarray(0, 21); var hashd = Neo.Cryptography.Sha256.computeHash(checkdata); hashd = Neo.Cryptography.Sha256.computeHash(hashd); var hashd = hashd.slice(0, 4); var checked = new Uint8Array(hashd); for (var i = 0; i < 4; i++) { if (checked[i] != check[i]) { throw new Error("the sum is not match."); } } return hash.clone(); } public static Sign(message: Uint8Array, privateKey: Uint8Array): Uint8Array { var PublicKey = Neo.Cryptography.ECPoint.multiply(Neo.Cryptography.ECCurve.secp256r1.G, privateKey); var pubkey = PublicKey.encodePoint(false).subarray(1, 64); //var PublicKey = ThinNeo.Cryptography.ECC.ECCurve.Secp256r1.G * prikey; //var pubkey = PublicKey.EncodePoint(false).Skip(1).ToArray(); var key = new Neo.Cryptography.ECDsaCryptoKey(PublicKey, privateKey); var ecdsa = new Neo.Cryptography.ECDsa(key); ////using(var ecdsa = System.Security.Cryptography.ECDsa.Create(new System.Security.Cryptography.ECParameters //{ // Curve = System.Security.Cryptography.ECCurve.NamedCurves.nistP256, // D = prikey, // Q = new System.Security.Cryptography.ECPoint // { // X = pubkey.Take(32).ToArray(), // Y = pubkey.Skip(32).ToArray() // } //})) { //var hash = Neo.Cryptography.Sha256.computeHash(message); return new Uint8Array(ecdsa.sign(message)); } } public static VerifySignature(message: Uint8Array, signature: Uint8Array, pubkey: Uint8Array) { var PublicKey = Neo.Cryptography.ECPoint.decodePoint(pubkey, Neo.Cryptography.ECCurve.secp256r1); var usepk = PublicKey.encodePoint(false).subarray(1, 64); var key = new Neo.Cryptography.ECDsaCryptoKey(PublicKey); var ecdsa = new Neo.Cryptography.ECDsa(key); { return ecdsa.verify(message, signature); } } public static String2Bytes(str): Uint8Array { var back = []; var byteSize = 0; for (var i = 0; i < str.length; i++) { var code = str.charCodeAt(i); if (0x00 <= code && code <= 0x7f) { byteSize += 1; back.push(code); } else if (0x80 <= code && code <= 0x7ff) { byteSize += 2; back.push((192 | (31 & (code >> 6)))); back.push((128 | (63 & code))) } else if ((0x800 <= code && code <= 0xd7ff) || (0xe000 <= code && code <= 0xffff)) { byteSize += 3; back.push((224 | (15 & (code >> 12)))); back.push((128 | (63 & (code >> 6)))); back.push((128 | (63 & code))) } } var uarr = new Uint8Array(back.length); for (i = 0; i < back.length; i++) { uarr[i] = back[i] & 0xff; } return uarr; } public static Bytes2String(_arr: Uint8Array) { var UTF = ''; for (var i = 0; i < _arr.length; i++) { var one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/); if (v && one.length == 8) { var bytesLength = v[0].length; var store = _arr[i].toString(2).slice(7 - bytesLength); for (var st = 1; st < bytesLength; st++) { store += _arr[st + i].toString(2).slice(2) } UTF += String.fromCharCode(parseInt(store, 2)); i += bytesLength - 1 } else { UTF += String.fromCharCode(_arr[i]) } } return UTF; } public static Aes256Encrypt(src: string, key: string): string { var srcs = CryptoJS.enc.Utf8.parse(src); var keys = CryptoJS.enc.Utf8.parse(key); var encryptedkey = CryptoJS.AES.encrypt(srcs, keys, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); return encryptedkey.ciphertext.toString(); } public static Aes256Encrypt_u8(src: Uint8Array, key: Uint8Array): Uint8Array { var srcs = CryptoJS.enc.Utf8.parse("1234123412341234"); srcs.sigBytes = src.length; srcs.words = new Array<number>(src.length / 4); for (var i = 0; i < src.length / 4; i++) { srcs.words[i] = src[i * 4 + 3] + src[i * 4 + 2] * 256 + src[i * 4 + 1] * 256 * 256 + src[i * 4 + 0] * 256 * 256 * 256; } var keys = CryptoJS.enc.Utf8.parse("1234123412341234"); keys.sigBytes = key.length; keys.words = new Array<number>(key.length / 4); for (var i = 0; i < key.length / 4; i++) { keys.words[i] = key[i * 4 + 3] + key[i * 4 + 2] * 256 + key[i * 4 + 1] * 256 * 256 + key[i * 4 + 0] * 256 * 256 * 256; } var encryptedkey = CryptoJS.AES.encrypt(srcs, keys, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); var str: string = encryptedkey.ciphertext.toString(); return str.hexToBytes(); } public static Aes256Decrypt_u8(encryptedkey: Uint8Array, key: Uint8Array): Uint8Array { var keys = CryptoJS.enc.Utf8.parse("1234123412341234"); keys.sigBytes = key.length; keys.words = new Array<number>(key.length / 4); for (var i = 0; i < key.length / 4; i++) { keys.words[i] = key[i * 4 + 3] + key[i * 4 + 2] * 256 + key[i * 4 + 1] * 256 * 256 + key[i * 4 + 0] * 256 * 256 * 256; } var base64key = Base64.fromByteArray(encryptedkey); var srcs = CryptoJS.AES.decrypt(base64key, keys, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); var str: string = srcs.toString(); return str.hexToBytes(); } public static GetNep2FromPrivateKey(prikey: Uint8Array, passphrase: string, n = 14, r = 8, p = 8, callback: (info: string, result: string) => void): void { var pubkey = Helper.GetPublicKeyFromPrivateKey(prikey); let addr = Helper.GetAddressFromPublicKey(pubkey); var addresshash = Helper.GetAddrHash(addr); scrypt(passphrase, addresshash, { logN: 14, r: r, p: p, dkLen: 64, encoding: 'hex' }, function (res:string) { var u8dk = res.hexToBytes(); var derivedhalf1 = u8dk.subarray(0, 32); var derivedhalf2 = u8dk.subarray(32, 64); var u8xor = new Uint8Array(32); for (var i = 0; i < 32; i++) { u8xor[i] = prikey[i] ^ derivedhalf1[i]; } var encryptedkey = Helper.Aes256Encrypt_u8(u8xor, derivedhalf2); let buffer = new Uint8Array(39); buffer[0] = 0x01; buffer[1] = 0x42; buffer[2] = 0xe0; for (var i = 3; i < 3 + 4; i++) { buffer[i] = addresshash[i - 3]; } for (var i = 7; i < 32 + 7; i++) { buffer[i] = encryptedkey[i - 7]; } var b1 = Neo.Cryptography.Sha256.computeHash(buffer); b1 = Neo.Cryptography.Sha256.computeHash(b1); var u8hash = new Uint8Array(b1); var outbuf = new Uint8Array(39 + 4); for (var i = 0; i < 39; i++) { outbuf[i] = buffer[i]; } for (var i = 39; i < 39 + 4; i++) { outbuf[i] = u8hash[i - 39]; } var base58str = Neo.Cryptography.Base58.encode(outbuf); callback("finish", base58str); }); return; } public static GetPrivateKeyFromNep2(nep2: string, passphrase: string, n = 14, r = 8, p = 8, callback: (info: string, result: string | Uint8Array) => void) { let data = Neo.Cryptography.Base58.decode(nep2); if (data.length != 39 + 4) { callback("error", "data.length error"); return; } if (data[0] != 0x01 || data[1] != 0x42 || data[2] != 0xe0) { callback("error", "dataheader error"); return; } var hash = data.subarray(39, 39 + 4); var buffer = data.subarray(0, 39); var b1 = Neo.Cryptography.Sha256.computeHash(buffer); b1 = Neo.Cryptography.Sha256.computeHash(b1); var u8hash = new Uint8Array(b1); for (var i = 0; i < 4; i++) { if (u8hash[i] != hash[i]) { callback("error", "data hash error"); return; } } var addresshash = buffer.subarray(3, 3 + 4); var encryptedkey = buffer.subarray(7, 7 + 32); scrypt(passphrase, addresshash, { logN: 14, r: r, p: p, dkLen: 64, encoding: 'hex' }, function (res: string) { var u8dk = res.hexToBytes() //new Uint8Array(res); var derivedhalf1 = u8dk.subarray(0, 32); var derivedhalf2 = u8dk.subarray(32, 64); var u8xor = Helper.Aes256Decrypt_u8(encryptedkey, derivedhalf2); var prikey = new Uint8Array(u8xor.length); for (var i = 0; i < 32; i++) { prikey[i] = u8xor[i] ^ derivedhalf1[i]; } var pubkey = Helper.GetPublicKeyFromPrivateKey(prikey); var address = Helper.GetAddressFromPublicKey(pubkey); var addresshashgot = Helper.GetAddrHash(address); for (var i = 0; i < 4; i++) { if (addresshash[i] != addresshashgot[i]) { callback("error", "nep2 hash not match."); return; } } callback("finish", prikey); }); } public static GetAddrHash(addr: string): any { var buffer = new Buffer.Buffer(addr); let strkey = Neo.Cryptography.Sha256.computeHash(buffer); strkey = Neo.Cryptography.Sha256.computeHash(strkey); var addresshash = new Uint8Array(strkey); return addresshash.subarray(0, 4); } } }