Created
October 30, 2023 06:56
-
-
Save mnixry/fa514f408c975071ec375dcc2df1ce44 to your computer and use it in GitHub Desktop.
Pure Python implementation for HashCash proof-of work, friendly for CTF.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Optional | |
import re | |
from pwn import * | |
def mint( | |
resource: str, | |
bits: int = 20, | |
now: Optional[float] = None, | |
ext: str = "", | |
salt_length: int = 8, | |
stamp_seconds: bool = False, | |
): | |
from secrets import token_urlsafe | |
import hashlib | |
from time import strftime, localtime, time | |
from itertools import count | |
def _mint(challenge: str, bits: int) -> str: # type: ignore | |
counter = 0 | |
hex_zeros = "0" * (bits // 4) | |
remain_zeros = {0: 0b0000, 1: 0b0111, 2: 0b0011, 3: 0b0001}.get(bits % 4, 0) | |
counter_hex = "0" | |
for counter in count(): | |
counter_hex = f"{counter:x}" | |
hash = hashlib.sha1(f"{challenge}{counter_hex}".encode()).hexdigest() | |
if not hash.startswith(hex_zeros): | |
continue | |
if not remain_zeros: | |
break | |
if int(hash[bits // 4], 16) <= remain_zeros: | |
break | |
return counter_hex | |
ver = "1" | |
now = now or time() | |
if stamp_seconds: | |
ts = strftime("%y%m%d%H%M%S", localtime(now)) | |
else: | |
ts = strftime("%y%m%d", localtime(now)) | |
challenge = "%s:" * 6 % (ver, bits, ts, resource, ext, token_urlsafe(salt_length)) | |
return challenge + _mint(challenge, bits) | |
HASHCASH_RE = re.compile(r"`hashcash -mb(\d+) (\S+)`") | |
r = remote("120.46.65.156", 32106) | |
matched = None | |
while matched is None: | |
line = r.recvline().decode() | |
print(line) | |
matched = HASHCASH_RE.search(line) | |
pow_bits, pow_resource = matched.groups() | |
mint_result = mint(pow_resource, bits=int(pow_bits)) | |
r.sendline(mint_result.encode()) | |
r.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment