You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
	
	
		
			
				
					
						
							|  |  |  | import SessionSnodeKit | 
					
						
							|  |  |  | import SessionUtilitiesKit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum ProofOfWork { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// A modified version of [Bitmessage's Proof of Work Implementation](https://bitmessage.org/wiki/Proof_of_work). | 
					
						
							|  |  |  |     static func calculate(ttl: UInt64, publicKey: String, data: String) -> (timestamp: UInt64, base64EncodedNonce: String)? { | 
					
						
							|  |  |  |         let nonceSize = MemoryLayout<UInt64>.size | 
					
						
							|  |  |  |         // Get millisecond timestamp | 
					
						
							|  |  |  |         let timestamp = NSDate.millisecondTimestamp() | 
					
						
							|  |  |  |         // Construct payload | 
					
						
							|  |  |  |         let payloadAsString = String(timestamp) + String(ttl) + publicKey + data | 
					
						
							|  |  |  |         let payload = payloadAsString.bytes | 
					
						
							|  |  |  |         // Calculate target | 
					
						
							|  |  |  |         let numerator = UInt64.max | 
					
						
							|  |  |  |         let difficulty = UInt64(SnodeAPI.powDifficulty) | 
					
						
							|  |  |  |         let totalSize = UInt64(payload.count + nonceSize) | 
					
						
							|  |  |  |         let ttlInSeconds = ttl / 1000 | 
					
						
							|  |  |  |         let denominator = difficulty * (totalSize + (ttlInSeconds * totalSize) / UInt64(UInt16.max)) | 
					
						
							|  |  |  |         let target = numerator / denominator | 
					
						
							|  |  |  |         // Calculate proof of work | 
					
						
							|  |  |  |         var value = UInt64.max | 
					
						
							|  |  |  |         let payloadHash = payload.sha512() | 
					
						
							|  |  |  |         var nonce = UInt64(0) | 
					
						
							|  |  |  |         while value > target { | 
					
						
							|  |  |  |             nonce = nonce &+ 1 | 
					
						
							|  |  |  |             let hash = (nonce.bigEndianBytes + payloadHash).sha512() | 
					
						
							|  |  |  |             guard let newValue = UInt64(fromBigEndianBytes: [UInt8](hash[0..<nonceSize])) else { return nil } | 
					
						
							|  |  |  |             value = newValue | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // Encode as base 64 | 
					
						
							|  |  |  |         let base64EncodedNonce = nonce.bigEndianBytes.toBase64()! | 
					
						
							|  |  |  |         // Return | 
					
						
							|  |  |  |         return (timestamp, base64EncodedNonce) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |