const crypto = require('crypto'); const RIPEMD160 = require('ripemd160'); const BS58 = require('bs58'); const sha256 = input => crypto.createHash('sha256').update(input).digest(); const ripemd160 = input => new RIPEMD160().update(input).digest(); const bs58 = input => BS58.encode(input); const generateECPoints = privateKey => { const Pcurve = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'); const Gx = BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'); const Gy = BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'); const G = [Gx, Gy]; const modInverse = (a, n) => { a = (a % n + n) % n const dArray = []; let b = n; while(b) { [a, b] = [b, a % b]; dArray.push({a, b}); } if (a !== BigInt(1)) { return null; } let x = BigInt(1); let y = BigInt(0); for(let i = dArray.length - 2; i >= 0; --i) { [x, y] = [y, x - y * BigInt(dArray[i].a / dArray[i].b)]; } return (y % n + n) % n; } const modOf = (a,b) => { const r = ((a % b) + b)% b; return r; } const ECAdd = (a,b) => { const lamAdd = modOf((b[1] - a[1]) * BigInt(modInverse(b[0] - a[0], Pcurve)), Pcurve); const x = modOf((lamAdd*lamAdd - a[0] - b[0]), Pcurve); const y = modOf((lamAdd*(a[0] - x) - a[1]), Pcurve); return [x, y]; } const ECDouble = a => { const lamda = modOf(((BigInt(3)*a[0]*a[0])*(modInverse(BigInt(2)*a[1], Pcurve))), Pcurve); const x = modOf((lamda*lamda - BigInt(2)*a[0]), Pcurve); const y = modOf((lamda*(a[0] - x) - a[1]), Pcurve); return [x, y]; }; const ECMultiply = (genPoint, pvtKey) => { const scalarBinary = BigInt('0x'+pvtKey).toString(2); let GP = genPoint; for (let i=1; i < scalarBinary.length; i++) { GP = ECDouble(GP) if (scalarBinary[i] === '1') { GP = ECAdd(GP, genPoint); } } return GP; } return ECMultiply(G, privateKey); } const privateKey = "6EBD5FAB742ED0734B37C63BD2A3CE8797FE4AC63C9A99781F8BEDDF6307094E"; const publicKey = generateECPoints(privateKey); const checkKey = key => key.length < 64 ? '0'.repeat(64 - key.length) : key; const publicKeyX = checkKey(publicKey[0].toString(16)); const publicKeyY = checkKey(publicKey[1].toString(16)); const uncompressedKey = '04'+publicKeyX+publicKeyY; let compressedKey; if (publicKey[1]%BigInt(2)===BigInt(1)) { compressedKey = '03'+publicKeyX; } else { compressedKey = '02'+publicKeyX; } const keyHex = Buffer.from(uncompressedKey, 'hex'); const ripedHashedKey = ripemd160(sha256(keyHex)); const mainRipeKeyString = '00'+ripedHashedKey.toString('hex'); const mainRipeKey = Buffer.from(mainRipeKeyString, 'hex'); const doubleHashedKey = sha256(sha256(mainRipeKey)).toString('hex'); const checkSum = doubleHashedKey.substr(0, 8); const binaryAddress = Buffer.from(mainRipeKeyString+checkSum, 'hex'); const publicAddress = bs58(binaryAddress); const pvtKeyExtended = "80"+privateKey; const extended = Buffer.from(pvtKeyExtended, 'hex'); const hashedExtended = sha256(sha256(extended)).toString('hex'); const checksum = hashedExtended.substr(0, 8); const finalHex = pvtKeyExtended+checksum; const WIF = bs58(Buffer.from(finalHex, 'hex')); console.log(`This is Bitcoin Address: ${publicAddress} This is WIF Key: ${WIF} This is Uncompressed Public Key: ${uncompressedKey} This is compressed Public Key: ${compressedKey} This is hexadecimal of Private Key: ${privateKey}`);