101 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| //
 | |
| // Reference
 | |
| // https://github.com/TecharoHQ/anubis/blob/ecc716940e34ebe7249974f2789a99a2c7115e4e/web/js/proof-of-work.mjs
 | |
| //
 | |
| 
 | |
| class anubis{
 | |
| 	
 | |
| 	public function __construct(){
 | |
| 		
 | |
| 		include_once "fuckhtml.php";
 | |
| 		$this->fuckhtml = new fuckhtml();
 | |
| 	}
 | |
| 	
 | |
| 	public function scrape($html){
 | |
| 		
 | |
| 		$this->fuckhtml->load($html);
 | |
| 		
 | |
| 		$script =
 | |
| 			$this->fuckhtml
 | |
| 			->getElementById(
 | |
| 				"anubis_challenge",
 | |
| 				"script"
 | |
| 			);
 | |
| 		
 | |
| 		if(count($script) === 0){
 | |
| 			
 | |
| 			throw new Exception("Failed to scrape anubis challenge data");
 | |
| 		}
 | |
| 		
 | |
| 		$script =
 | |
| 			json_decode(
 | |
| 				$this->fuckhtml
 | |
| 				->getTextContent(
 | |
| 					$script
 | |
| 				),
 | |
| 				true
 | |
| 			);
 | |
| 		
 | |
| 		if($script === null){
 | |
| 			
 | |
| 			throw new Exception("Failed to decode anubis challenge data");
 | |
| 		}
 | |
| 		
 | |
| 		if(
 | |
| 			!isset($script["challenge"]) ||
 | |
| 			!isset($script["rules"]["difficulty"]) ||
 | |
| 			!is_int($script["rules"]["difficulty"]) ||
 | |
| 			!is_string($script["challenge"])
 | |
| 		){
 | |
| 			
 | |
| 			throw new Exception("Found invalid challenge data");
 | |
| 		}
 | |
| 		
 | |
| 		return $this->rape($script["challenge"], $script["rules"]["difficulty"]);
 | |
| 	}
 | |
| 	
 | |
| 	private function is_valid_hash($hash, $difficulty){
 | |
| 		
 | |
| 		for ($i=0; $i<$difficulty; $i++) {
 | |
| 			
 | |
| 			$index = (int)floor($i / 2);
 | |
| 			$nibble = $i % 2;
 | |
| 			
 | |
| 			$byte = ord($hash[$index]);
 | |
| 			$nibble = ($byte >> ($nibble === 0 ? 4 : 0)) & 0x0f;
 | |
| 			
 | |
| 			if($nibble !== 0){
 | |
| 				return false;
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		return true;
 | |
| 	}
 | |
| 	
 | |
| 	public function rape($data, $difficulty = 5){
 | |
| 		
 | |
| 		$nonce = 0;
 | |
| 		
 | |
| 		while(true){
 | |
| 			
 | |
| 			$hash_binary = hash("sha256", $data . $nonce, true);
 | |
| 			
 | |
| 			if($this->is_valid_hash($hash_binary, $difficulty)){
 | |
| 				
 | |
| 				$hash_hex = bin2hex($hash_binary);
 | |
| 				
 | |
| 				return [
 | |
| 					"response" => $hash_hex,
 | |
| 					//"data" => $data,
 | |
| 					//"difficulty" => $difficulty,
 | |
| 					"nonce" => $nonce
 | |
| 				];
 | |
| 			}
 | |
| 			
 | |
| 			$nonce++;
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
