96 lines
2.2 KiB
HTML
96 lines
2.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>PoW Shield</title>
|
|
</head>
|
|
<script>
|
|
const SHA256_MD_LENGTH = 64;
|
|
const POW_RANDOM_LENGTH = 64;
|
|
|
|
function base64ToBytes(b64) {
|
|
return Uint8Array.from(atob(b64), c => c.charCodeAt(0));
|
|
}
|
|
|
|
function deserializePowChallenge(b64) {
|
|
const bytes = base64ToBytes(b64);
|
|
const view = new DataView(bytes.buffer);
|
|
|
|
let offset = 0;
|
|
|
|
const version = view.getUint32(offset, true); offset += 4;
|
|
const created = view.getUint32(offset, true); offset += 4;
|
|
const ttl = view.getUint32(offset, true); offset += 4;
|
|
const difficulty = view.getUint32(offset, true); offset += 4;
|
|
const random = view.buffer.slice(offset, offset + 64); offset += 64;
|
|
const digest = view.buffer.slice(offset);
|
|
|
|
return {
|
|
version,
|
|
created,
|
|
ttl,
|
|
difficulty,
|
|
random,
|
|
digest
|
|
};
|
|
}
|
|
|
|
function getCookie(name) {
|
|
const cookies = document.cookie.split("; ");
|
|
|
|
for (const c of cookies) {
|
|
if (c.startsWith(name + "=")) {
|
|
return decodeURIComponent(c.substring(name.length + 1));
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function sha256(bytes) {
|
|
const hashBuffer = await crypto.subtle.digest("SHA-256", bytes);
|
|
return new Uint8Array(hashBuffer);
|
|
}
|
|
|
|
function hasLeadingBytes(buf, numBits) {
|
|
const zeroBytes = numBits / 8;
|
|
const remainingBits = numBits % 8;
|
|
const lut = Uint8Array([
|
|
0b11111111, 0b01111111, 0b00111111, 0b00011111,
|
|
0b00001111, 0b00000111, 0b00000011, 0b00000001
|
|
]);
|
|
|
|
for (let i = 0; i < zeroBytes; i++) {
|
|
if (buf[i] > 0) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (buf[zeroBytes + 1] ^ lut[remainingBytes]) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function pow(challenge) {
|
|
const difficulty = deserializePowChallenge(challenge).difficulty
|
|
const pow = Uint32
|
|
|
|
let digest;
|
|
let nonce = 0;
|
|
|
|
do {
|
|
sha256(challenge).then(d => digest = d);
|
|
} while (hasLeadingBytes(digest, difficulty))
|
|
|
|
console.log(digest)
|
|
}
|
|
|
|
const powChallengeCookie = getCookie("pow-challenge");
|
|
const powChallenge = deserializePowChallenge(powChallengeCookie);
|
|
console.log(powChallenge, powChallenge.length)
|
|
</script>
|
|
</html>
|