<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bitcoin Address Verifier</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
input, button { padding: 8px; margin: 5px 0; width: 100%; }
pre { background: #f4f4f4; padding: 10px; }
</style>
</head>
<body>
<h2>🔑 Bitcoin Address Verifier</h2>
<label>Private Key (hex):</label>
<input id="privKey" value="00000000000000000000000000000000000000000000000000000000000000e0">
<label>Expected hash160:</label>
<input id="expHash160" value="dce76b2613052ea012204404a97b3c25eac31715">
<label>Expected Address:</label>
<input id="expAddr" value="1M92tSqNmQLYw33fuBvjmeadirh1ysMBxK">
<button onclick="runVerification()">Verify</button>
<h3>Result:</h3>
<pre id="output"></pre>
<script>
// --- Base58, ECC, and Hash functions from before ---
function hexToBytes(hex) {
return new Uint8Array(hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
}
function bytesToHex(bytes) {
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
}
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
function base58Encode(buffer) {
let x = BigInt('0x' + bytesToHex(buffer));
let result = '';
while (x > 0) {
const mod = x % 58n;
result = BASE58_ALPHABET[Number(mod)] + result;
x = x / 58n;
}
for (let byte of buffer) {
if (byte === 0x00) result = '1' + result;
else break;
}
return result;
}
function getPublicKeyCompressed(privKeyHex) {
const secp256k1 = {
p: BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'),
a: 0n,
b: 7n,
Gx: BigInt('0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'),
Gy: BigInt('0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8'),
};
function mod(n, p) { return ((n % p) + p) % p; }
function inv(n, p) {
let [a, b] = [n, p], [x, y] = [1n, 0n];
while (b) [a, b, x, y] = [b, a % b, y, x - y * (a / b)];
return mod(x, p);
}
function add(P, Q) {
if (!P) return Q;
if (!Q) return P;
let [x1, y1] = P, [x2, y2] = Q;
if (x1 === x2 && y1 !== y2) return null;
let m = x1 === x2 ? mod(3n * x1 * x1, secp256k1.p) * inv(2n * y1, secp256k1.p) : mod(y2 - y1, secp256k1.p) * inv(x2 - x1, secp256k1.p);
let x3 = mod(m * m - x1 - x2, secp256k1.p);
let y3 = mod(m * (x1 - x3) - y1, secp256k1.p);
return [x3, y3];
}
function multiply(k, P) {
let R = null;
for (let i = 0; i < 256; i++) {
if (k & (1n << BigInt(i))) R = add(R, P);
P = add(P, P);
}
return R;
}
let privKey = BigInt('0x' + privKeyHex);
let pubKey = multiply(privKey, [secp256k1.Gx, secp256k1.Gy]);
let prefix = pubKey[1] % 2n === 0n ? '02' : '03';
return prefix + pubKey[0].toString(16).padStart(64, '0');
}
async function hash160(hex) {
let sha = await crypto.subtle.digest('SHA-256', hexToBytes(hex));
let shaBytes = new Uint8Array(sha);
let ripemd = await crypto.subtle.digest('RIPEMD-160', shaBytes);
return bytesToHex(new Uint8Array(ripemd));
}
async function runVerification() {
let privKeyHex = document.getElementById('privKey').value.trim();
let expectedHash160 = document.getElementById('expHash160').value.trim();
let expectedAddr = document.getElementById('expAddr').value.trim();
let output = '';
output += '🔑 Private Key: ' + privKeyHex + '\\n';
let pubKeyHex = getPublicKeyCompressed(privKeyHex);
output += '🔓 Public Key (Compressed): ' + pubKeyHex + '\\n';
let shaHash = await crypto.subtle.digest('SHA-256', hexToBytes(pubKeyHex));
let shaHex = bytesToHex(new Uint8Array(shaHash));
output += '🌀 SHA256(pubkey): ' + shaHex + '\\n';
let hash160Hex = await hash160(pubKeyHex);
output += '🌪️ RIPEMD160(SHA256(pubkey)): ' + hash160Hex + '\\n';
output += '✅ Expected hash160: ' + expectedHash160 + ' | Match: ' + (expectedHash160 === hash160Hex) + '\\n';
let versioned = '00' + hash160Hex;
let verBuf = hexToBytes(versioned);
let chk1 = await crypto.subtle.digest('SHA-256', verBuf);
let chk2 = await crypto.subtle.digest('SHA-256', chk1);
let checksum = bytesToHex(new Uint8Array(chk2)).slice(0, 8);
output += '🔗 Version + hash160: ' + versioned + '\\n';
output += '🔐 Checksum: ' + checksum + '\\n';
let fullHex = versioned + checksum;
let address = base58Encode(hexToBytes(fullHex));
output += '🏁 Bitcoin Address: ' + address + '\\n';
output += '✅ Expected Address: ' + expectedAddr + ' | Match: ' + (expectedAddr === address) + '\\n';
document.getElementById('output').innerText = output;
}
</script>
</body>
</html>