Guest User

shitscript 2.0

a guest
Nov 21st, 2024
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.00 KB | Cybersecurity | 0 0
  1. import hashlib
  2. from Crypto.Cipher import AES
  3. from Crypto.Util.Padding import pad, unpad
  4. from Crypto.Random import get_random_bytes
  5. from numba import cuda, uint32, uint64, uint8
  6. import numpy as np
  7. import argparse
  8. import os
  9. import time
  10. import multiprocessing
  11.  
  12. # Parameters
  13. BLOCK_SIZE = 16 # AES block size
  14.  
  15. # Encrypt the hidden link using AES CBC mode with a random IV
  16. def encrypt_link(link, key):
  17. """
  18. Encrypts the given link using AES encryption in CBC mode with a random IV.
  19.  
  20. :param link: The link to encrypt.
  21. :param key: The AES encryption key.
  22. :return: The encrypted link (bytes), with the IV prepended.
  23. """
  24. iv = get_random_bytes(BLOCK_SIZE)
  25. cipher = AES.new(key, AES.MODE_CBC, iv)
  26. encrypted_link = iv + cipher.encrypt(pad(link.encode(), BLOCK_SIZE))
  27. return encrypted_link
  28.  
  29. # Decrypt the hidden link
  30. def decrypt_link(encrypted_link, key):
  31. """
  32. Decrypts the given encrypted link using AES encryption in CBC mode.
  33.  
  34. :param encrypted_link: The encrypted link (bytes), with the IV prepended.
  35. :param key: The AES decryption key.
  36. :return: The decrypted link as a string.
  37. """
  38. iv = encrypted_link[:BLOCK_SIZE]
  39. cipher = AES.new(key, AES.MODE_CBC, iv)
  40. decrypted_data = cipher.decrypt(encrypted_link[BLOCK_SIZE:])
  41. decrypted_link = unpad(decrypted_data, BLOCK_SIZE).decode()
  42. return decrypted_link
  43.  
  44. # GPU kernel for hash computation using DJB2 hash function
  45. @cuda.jit
  46. def find_nonce_kernel(d_challenge_bytes, challenge_length, nonce_start, target, result):
  47. """
  48. CUDA kernel function to find a nonce that produces a DJB2 hash value below the target.
  49.  
  50. :param d_challenge_bytes: Device array of challenge bytes.
  51. :param challenge_length: Length of the challenge bytes.
  52. :param nonce_start: Starting nonce value for this batch (uint64).
  53. :param target: Target hash value (difficulty).
  54. :param result: Device array to store the result [nonce, flag].
  55. """
  56. idx = cuda.grid(1)
  57. nonce = uint64(nonce_start) + uint64(idx)
  58.  
  59. local_buffer = cuda.local.array(64, dtype=uint8) # Local array for data
  60.  
  61. # Copy challenge_bytes into local_buffer
  62. for i in range(challenge_length):
  63. local_buffer[i] = d_challenge_bytes[i]
  64.  
  65. # Append nonce as bytes to local_buffer
  66. nonce_start_pos = challenge_length
  67. for i in range(8): # 8 bytes for uint64 nonce
  68. shift_amount = uint64(8 * i)
  69. local_buffer[nonce_start_pos + i] = uint8((nonce >> shift_amount) & uint64(0xFF))
  70.  
  71. total_length = nonce_start_pos + 8
  72.  
  73. # Compute DJB2 hash
  74. hash_value = uint32(5381)
  75. for i in range(total_length):
  76. c = uint32(local_buffer[i])
  77. hash_value = uint32(hash_value * uint32(33) + c)
  78.  
  79. # Check if hash matches difficulty
  80. if hash_value < target:
  81. # Atomically set the result if not already found
  82. old = cuda.atomic.cas(result, 1, 0, 1)
  83. if old == 0:
  84. result[0] = nonce # Store nonce
  85.  
  86. # Solve the challenge using GPU
  87. def find_nonce_gpu(challenge, difficulty):
  88. """
  89. Solves the proof-of-work challenge using GPU acceleration.
  90.  
  91. :param challenge: The challenge string (hexadecimal).
  92. :param difficulty: The difficulty level (number of bits).
  93. :return: The nonce value that solves the challenge.
  94. """
  95. try:
  96. # Check for maximum difficulty
  97. if difficulty >= 32:
  98. print("Error: Maximum difficulty level for this implementation is 31.")
  99. return None
  100.  
  101. challenge_bytes = np.frombuffer(bytes.fromhex(challenge), dtype=np.uint8).copy()
  102. challenge_length = challenge_bytes.size
  103. result = np.zeros(2, dtype=np.uint64) # result[0] = nonce, result[1] = flag
  104.  
  105. # Transfer data to device once
  106. d_challenge_bytes = cuda.to_device(challenge_bytes)
  107. d_result = cuda.to_device(result)
  108.  
  109. threads_per_block = 256
  110. blocks_per_grid = 1024
  111. batch_size = np.uint64(threads_per_block * blocks_per_grid)
  112. nonce_start = np.uint64(0)
  113.  
  114. max_hash_value = 0xFFFFFFFF # Use standard Python integer
  115. target = max_hash_value >> difficulty
  116.  
  117. # Convert target to uint32 for CUDA kernel
  118. target_uint32 = np.uint32(target)
  119.  
  120. # Check if target is zero
  121. if target == 0:
  122. print("Error: Target hash value is zero. Cannot proceed with difficulty level >= 32.")
  123. return None
  124.  
  125. # Calculate the expected number of hashes needed
  126. probability = target / float(max_hash_value + 1)
  127. expected_hashes = 1 / probability
  128.  
  129. # Perform a benchmark to estimate hash rate
  130. print("Performing benchmark to estimate hash rate...")
  131. benchmark_batches = 10 # Number of batches to process during the benchmark
  132. start_time = time.time()
  133.  
  134. for _ in range(benchmark_batches):
  135. find_nonce_kernel[blocks_per_grid, threads_per_block](
  136. d_challenge_bytes, challenge_length, nonce_start, target_uint32, d_result
  137. )
  138. cuda.synchronize() # Ensure kernel execution is complete
  139. nonce_start += batch_size
  140.  
  141. end_time = time.time()
  142. elapsed_time = end_time - start_time
  143.  
  144. # Calculate hash rate
  145. total_hashes = batch_size * benchmark_batches
  146. hash_rate = total_hashes / elapsed_time # Hashes per second
  147.  
  148. # Estimate total expected time
  149. estimated_total_time = expected_hashes / hash_rate
  150.  
  151. print(f"Estimated hash rate: {hash_rate:.2f} hashes/second")
  152. print(f"Expected number of hashes to find solution: {expected_hashes:.0f}")
  153. print(f"Estimated time to complete: {estimated_total_time:.2f} seconds ({estimated_total_time/60:.2f} minutes)")
  154.  
  155. # Reset nonce_start and result for the actual computation
  156. nonce_start = np.uint64(0)
  157. result[1] = 0 # Reset the flag
  158. d_result.copy_to_device(result)
  159.  
  160. print("Starting GPU processing...")
  161. start_time = time.time()
  162.  
  163. # Variables for controlling print intervals
  164. print_interval = 5 # Print progress every 5 seconds
  165. last_print_time = start_time
  166. range_start_nonce = nonce_start # Keep track of the starting nonce for the current range
  167.  
  168. total_hashes_processed = np.uint64(0) # To track total hashes processed
  169.  
  170. try:
  171. while True:
  172. # Launch GPU kernel for the current batch
  173. find_nonce_kernel[blocks_per_grid, threads_per_block](
  174. d_challenge_bytes, challenge_length, nonce_start, target_uint32, d_result
  175. )
  176. cuda.synchronize() # Ensure kernel execution is complete
  177.  
  178. # Copy results back to the host
  179. result = d_result.copy_to_host()
  180.  
  181. # Update total hashes processed
  182. total_hashes_processed += batch_size
  183.  
  184. # Check if solution found
  185. if result[1] == 1: # Solution found
  186. elapsed_time = time.time() - start_time
  187. print(f"\nSolution found at nonce {result[0]} (Elapsed time: {elapsed_time:.2f}s)")
  188. return int(result[0])
  189.  
  190. nonce_start += batch_size # Increment nonce_start for the next batch
  191.  
  192. # Only print the progress message if a certain amount of time has passed
  193. current_time = time.time()
  194. if current_time - last_print_time >= print_interval:
  195. elapsed_time = current_time - start_time
  196. # Update estimated time remaining
  197. hashes_performed = total_hashes_processed
  198. hashes_remaining = expected_hashes - hashes_performed
  199. est_time_remaining = hashes_remaining / hash_rate
  200. est_total_time = elapsed_time + est_time_remaining
  201.  
  202. # Progress percentage
  203. progress = min((hashes_performed / expected_hashes) * 100, 100)
  204.  
  205. print(f"Processed nonce range {range_start_nonce} - {nonce_start} "
  206. f"(Elapsed: {elapsed_time:.2f}s, Remaining: {est_time_remaining:.2f}s, "
  207. f"Progress: {progress:.2f}%)")
  208. last_print_time = current_time
  209. range_start_nonce = nonce_start # Update the starting nonce for the next range
  210.  
  211. except KeyboardInterrupt:
  212. print("\nProcess interrupted by user.")
  213. return None
  214.  
  215. except Exception as e:
  216. print(f"An error occurred during GPU computation: {e}")
  217. print("Falling back to CPU solver...")
  218. return find_nonce_cpu(challenge, difficulty)
  219.  
  220. # Worker function for multiprocessing CPU solver
  221. def cpu_worker(args):
  222. challenge_bytes, nonce_start, nonce_end, target, return_dict, worker_id = args
  223. for nonce in range(nonce_start, nonce_end):
  224. data = challenge_bytes + nonce.to_bytes(8, byteorder='little')
  225. # Compute DJB2 hash
  226. hash_value = 5381
  227. for c in data:
  228. hash_value = ((hash_value * 33) + c) & 0xFFFFFFFF # Ensure 32-bit unsigned integer
  229. if hash_value < target:
  230. return_dict['nonce'] = nonce
  231. return True # Found solution
  232. return False # Did not find solution
  233.  
  234. # Solve the challenge using CPU
  235. def find_nonce_cpu(challenge, difficulty):
  236. """
  237. Solves the proof-of-work challenge using CPU.
  238.  
  239. :param challenge: The challenge string (hexadecimal).
  240. :param difficulty: The difficulty level (number of bits).
  241. :return: The nonce value that solves the challenge.
  242. """
  243. # Check for maximum difficulty
  244. if difficulty >= 32:
  245. print("Error: Maximum difficulty level for this implementation is 31.")
  246. return None
  247.  
  248. max_hash_value = 0xFFFFFFFF # Standard Python integer
  249. target = max_hash_value >> difficulty
  250.  
  251. # Check if target is zero
  252. if target == 0:
  253. print("Error: Target hash value is zero. Cannot proceed with difficulty level >= 32.")
  254. return None
  255.  
  256. challenge_bytes = bytes.fromhex(challenge)
  257.  
  258. # Calculate the expected number of hashes needed
  259. probability = target / float(max_hash_value + 1)
  260. expected_hashes = 1 / probability
  261.  
  262. # Perform a benchmark to estimate hash rate
  263. print("Performing benchmark to estimate hash rate...")
  264. benchmark_nonces = 100000 # Number of nonces to process during the benchmark
  265. start_time = time.time()
  266.  
  267. nonce = 0
  268. for _ in range(benchmark_nonces):
  269. data = challenge_bytes + nonce.to_bytes(8, byteorder='little')
  270. # Compute DJB2 hash
  271. hash_value = 5381
  272. for c in data:
  273. hash_value = ((hash_value * 33) + c) & 0xFFFFFFFF
  274. nonce += 1
  275.  
  276. end_time = time.time()
  277. elapsed_time = end_time - start_time
  278.  
  279. # Calculate hash rate
  280. hash_rate_per_core = benchmark_nonces / elapsed_time # Hashes per second
  281.  
  282. # Estimate total expected time
  283. num_cores = multiprocessing.cpu_count()
  284. hash_rate = hash_rate_per_core * num_cores
  285. estimated_total_time = expected_hashes / hash_rate
  286.  
  287. print(f"Estimated hash rate per core: {hash_rate_per_core:.2f} hashes/second")
  288. print(f"Total estimated hash rate: {hash_rate:.2f} hashes/second")
  289. print(f"Expected number of hashes to find solution: {expected_hashes:.0f}")
  290. print(f"Estimated time to complete: {estimated_total_time:.2f} seconds ({estimated_total_time/60:.2f} minutes)")
  291.  
  292. # Start multiprocessing pool
  293. print(f"Starting CPU processing on {num_cores} cores...")
  294. manager = multiprocessing.Manager()
  295. return_dict = manager.dict()
  296. pool = multiprocessing.Pool(processes=num_cores)
  297. nonce_start = 0
  298. chunk_size = 1000000 # Adjust as needed
  299. total_hashes_processed = 0
  300. start_time = time.time()
  301.  
  302. try:
  303. while True:
  304. jobs = []
  305. for i in range(num_cores):
  306. nonce_range_start = nonce_start + i * chunk_size
  307. nonce_range_end = nonce_range_start + chunk_size
  308. args = (challenge_bytes, nonce_range_start, nonce_range_end, target, return_dict, i)
  309. job = pool.apply_async(cpu_worker, args=(args,))
  310. jobs.append(job)
  311.  
  312. # Wait for jobs to finish or for a solution to be found
  313. for job in jobs:
  314. result = job.get()
  315. if result:
  316. pool.terminate()
  317. elapsed_time = time.time() - start_time
  318. nonce_found = return_dict['nonce']
  319. print(f"\nSolution found at nonce {nonce_found} (Elapsed time: {elapsed_time:.2f}s)")
  320. return nonce_found
  321.  
  322. nonce_start += num_cores * chunk_size
  323. total_hashes_processed += num_cores * chunk_size
  324.  
  325. # Progress update
  326. elapsed_time = time.time() - start_time
  327. hashes_remaining = expected_hashes - total_hashes_processed
  328. est_time_remaining = hashes_remaining / hash_rate
  329. progress = min((total_hashes_processed / expected_hashes) * 100, 100)
  330. print(f"Processed up to nonce {nonce_start} "
  331. f"(Elapsed: {elapsed_time:.2f}s, Remaining: {est_time_remaining:.2f}s, "
  332. f"Progress: {progress:.2f}%)")
  333.  
  334. except KeyboardInterrupt:
  335. print("\nProcess interrupted by user.")
  336. pool.terminate()
  337. return None
  338. except Exception as e:
  339. print(f"An error occurred during CPU computation: {e}")
  340. pool.terminate()
  341. return None
  342. finally:
  343. pool.close()
  344. pool.join()
  345.  
  346. print("Failed to find a valid nonce.")
  347. return None
  348.  
  349. # Generate a challenge
  350. def generate_challenge(link, difficulty):
  351. """
  352. Generates a new challenge string and encrypts the link.
  353.  
  354. :param link: The hidden link to encrypt.
  355. :param difficulty: The difficulty level for the challenge.
  356. :return: The combined string containing the challenge, difficulty, and encrypted link.
  357. """
  358. # Check for maximum difficulty
  359. if difficulty >= 32:
  360. print("Error: Maximum difficulty level for this implementation is 31.")
  361. return None
  362.  
  363. challenge = os.urandom(16).hex() # Random 16-byte challenge
  364. challenge_with_difficulty = f"{challenge}:{difficulty}" # Embed difficulty
  365. key = hashlib.sha256(challenge_with_difficulty.encode()).digest()[:BLOCK_SIZE] # Derive key
  366. encrypted_link = encrypt_link(link, key)
  367. combined_string = f"{challenge}:{difficulty}:{encrypted_link.hex()}"
  368. return combined_string
  369.  
  370. # Parse combined input string
  371. def parse_combined_string(combined_string):
  372. """
  373. Parses the combined string into challenge, difficulty, and encrypted link.
  374.  
  375. :param combined_string: The combined string from challenge generation.
  376. :return: Tuple of (challenge, difficulty, encrypted_link).
  377. """
  378. try:
  379. # Limit the number of splits to 2 to handle colons in the encrypted link
  380. parts = combined_string.split(":", 2)
  381. if len(parts) != 3:
  382. raise ValueError
  383. challenge, difficulty_str, encrypted_link_hex = parts
  384. if not all(c in '0123456789abcdefABCDEF' for c in challenge):
  385. raise ValueError
  386. difficulty = int(difficulty_str)
  387. if not isinstance(difficulty, int) or difficulty < 0:
  388. raise ValueError
  389. encrypted_link = bytes.fromhex(encrypted_link_hex)
  390. return challenge, difficulty, encrypted_link
  391. except ValueError:
  392. raise ValueError("Invalid input format. Expected format: <challenge>:<difficulty>:<encrypted_link>")
  393.  
  394. # Main program
  395. def main():
  396. usage_text = """
  397. Examples:
  398.  
  399. Generate a new challenge with a hidden link:
  400. python gpu_hard_challenge_ex.py --generate --link "https://example.com/hidden" --difficulty 25
  401.  
  402. Solve a given challenge and reveal the hidden link:
  403. python gpu_hard_challenge_ex.py --solve --input "<challenge>:<difficulty>:<encrypted_link>"
  404.  
  405. View this help message:
  406. python gpu_hard_challenge_ex.py --help
  407. """
  408.  
  409. parser = argparse.ArgumentParser(
  410. description="GPU Hard Challenge: A Proof-of-Work System Using GPU Acceleration.",
  411. formatter_class=argparse.RawDescriptionHelpFormatter,
  412. epilog=usage_text
  413. )
  414.  
  415. group = parser.add_mutually_exclusive_group(required=True)
  416. group.add_argument("--generate", action="store_true", help="Generate a new challenge string with an encrypted link.")
  417. group.add_argument("--solve", action="store_true", help="Solve a given challenge to reveal the hidden link.")
  418.  
  419. parser.add_argument("--link", type=str, help="The hidden link to encrypt (required when using --generate).")
  420. parser.add_argument("--difficulty", type=int, default=5, help="Difficulty level for the proof-of-work (default: 5). Acceptable range: 0-31.")
  421. parser.add_argument("--input", type=str, help="The combined input string to solve, in the format <challenge>:<difficulty>:<encrypted_link> (required when using --solve).")
  422.  
  423. args = parser.parse_args()
  424.  
  425. if args.generate:
  426. if not args.link:
  427. print("Error: Please provide a link using --link when generating a challenge.")
  428. parser.print_help()
  429. return
  430. try:
  431. combined_string = generate_challenge(args.link, args.difficulty)
  432. if combined_string:
  433. print("\nGenerated Combined String:\n")
  434. print(combined_string)
  435. print("\nShare this combined string with the solver.\n")
  436. except Exception as e:
  437. print(f"An error occurred during challenge generation: {e}")
  438. return
  439.  
  440. elif args.solve:
  441. if not args.input:
  442. print("Error: Please provide the combined input string using --input when solving a challenge.")
  443. parser.print_help()
  444. return
  445.  
  446. # Parse the input
  447. try:
  448. challenge, difficulty, encrypted_link = parse_combined_string(args.input)
  449. except ValueError as e:
  450. print(e)
  451. return
  452.  
  453. # Check for maximum difficulty
  454. if difficulty >= 32:
  455. print("Error: Maximum difficulty level for this implementation is 31.")
  456. return
  457.  
  458. print("Solving challenge...")
  459. if cuda.is_available():
  460. print("CUDA detected, using GPU...")
  461. nonce = find_nonce_gpu(challenge, difficulty)
  462. else:
  463. print("CUDA not detected, falling back to CPU...")
  464. nonce = find_nonce_cpu(challenge, difficulty)
  465.  
  466. if nonce is not None:
  467. print(f"Found Nonce: {nonce}")
  468. key = hashlib.sha256(f"{challenge}:{difficulty}".encode()).digest()[:BLOCK_SIZE]
  469. try:
  470. hidden_link = decrypt_link(encrypted_link, key)
  471. print(f"Hidden Link: {hidden_link}")
  472. except Exception as e:
  473. print(f"An error occurred during decryption: {e}")
  474. else:
  475. print("Failed to find a valid nonce.")
  476.  
  477. if __name__ == "__main__":
  478. main()
  479.  
Advertisement
Add Comment
Please, Sign In to add comment