├── .gitattributes ├── Main.py ├── README.md ├── Replay.py ├── TCP ├── Client │ ├── endpoint.py │ ├── factory.py │ └── protocol.py ├── Crypto.py ├── Nonce.py ├── Packet │ ├── packetEnum.py │ ├── reader.py │ └── writer.py ├── PacketReceiver.py └── Server │ ├── endpoint.py │ ├── factory.py │ └── protocol.py ├── TweetnaclMod ├── randombytes.c ├── randombytes.h ├── setup.py ├── tweetnacl.c ├── tweetnacl.h └── tweetnaclmodule.c ├── UDP ├── CryptoRC4.py ├── packetEnum.py ├── packetProcessor.py └── protocol.py ├── config.json ├── hexdump.py ├── requirements.txt └── urandom_hook.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import json 5 | import time 6 | import frida 7 | import argparse 8 | 9 | from Replay import Replay 10 | from TCP.Crypto import Crypto 11 | from twisted.internet import reactor 12 | from TCP.Server.factory import ServerFactory 13 | from TCP.Server.endpoint import ServerEndpoint 14 | from TCP.Client.endpoint import ClientEndpoint 15 | 16 | from UDP.protocol import UDPProtocol 17 | 18 | 19 | MAX_FRIDA_RETRY = 10 20 | 21 | 22 | def onClose(udp_protocol): 23 | print("[*] Closing proxy !") 24 | 25 | if udp_protocol is not None: 26 | udp_protocol.packetProcessor.stop() 27 | 28 | 29 | def start_frida_script(network, adbpath): 30 | # Would be better to use frida.get_usb_device().spawn to spawn the app 31 | # But it seems that it is broken on some version so we use adb to spawn the game 32 | os.system(adbpath + " shell monkey -p com.supercell.clashroyale -c android.intent.category.LAUNCHER 1") 33 | time.sleep(0.5) 34 | 35 | try: 36 | if network: 37 | device = frida.get_remote_device() 38 | else: 39 | device = frida.get_usb_device() 40 | 41 | except Exception as exception: 42 | print('[*] Can\'t connect to your device ({}) !'.format(exception.__class__.__name__)) 43 | exit() 44 | 45 | retry_count = 0 46 | process = None 47 | 48 | while not process: 49 | try: 50 | process = device.attach('com.supercell.clashroyale') 51 | 52 | except Exception as exception: 53 | if retry_count == MAX_FRIDA_RETRY: 54 | print('[*] Can\'t attach frida to the game ({}) ! Start the frida server on your device'.format(exception.__class__.__name__)) 55 | exit() 56 | 57 | retry_count += 1 58 | time.sleep(0.5) 59 | 60 | print('[*] Frida attached !') 61 | 62 | if os.path.isfile("urandom_hook.js"): 63 | script = process.create_script(open("urandom_hook.js").read()) 64 | 65 | else: 66 | print('[*] urandom_hook.js script is missing, cannot inject the script !') 67 | exit() 68 | 69 | script.load() 70 | 71 | print('[*] Script injected !') 72 | 73 | 74 | if __name__ == '__main__': 75 | parser = argparse.ArgumentParser(description='Python proxy used to decrypt all clash royale game traffic') 76 | parser.add_argument('-f', '--frida', help='inject the frida script at the proxy runtime', action='store_true') 77 | parser.add_argument('-n', '--network', help='connect to frida via network rather than USB', action='store_true') 78 | parser.add_argument('-v', '--verbose', help='print packet hexdump in console', action='store_true') 79 | parser.add_argument('-r', '--replay', help='save packets in replay folder', action='store_true') 80 | parser.add_argument('-u', '--udp', help='start the udp proxy', action='store_true') 81 | parser.add_argument('-a', '--adbpath', help='path to adb', default='adb') 82 | 83 | args = parser.parse_args() 84 | 85 | if os.path.isfile('config.json'): 86 | config = json.load(open('config.json')) 87 | 88 | else: 89 | print('[*] config.json is missing !') 90 | exit() 91 | 92 | if args.frida: 93 | start_frida_script(args.network, args.adbpath) 94 | 95 | crypto = Crypto(config['ServerKey']) 96 | replay = Replay(config['ReplayDirectory']) 97 | 98 | client_endpoint = ClientEndpoint(reactor, config['Hostname'], config['Port']) 99 | server_endpoint = ServerEndpoint(reactor, config['Port']) 100 | 101 | udp_protocol = UDPProtocol(config['UDPHost'], config['UDPPort'], replay) if args.udp else None 102 | server_endpoint.listen(ServerFactory(client_endpoint, udp_protocol, crypto, replay, args)) 103 | 104 | print("[*] TCP Proxy is listening on {}:{}".format(server_endpoint.interface, server_endpoint.port)) 105 | 106 | if udp_protocol is not None: 107 | udp_listener = reactor.listenUDP(config['UDPPort'], udp_protocol) 108 | udp_listener_host = udp_listener.getHost() 109 | 110 | print("[*] UDP Proxy is listening on {}:{}".format(udp_listener_host.host, udp_listener_host.port)) 111 | 112 | reactor.addSystemEventTrigger('before', 'shutdown', onClose, udp_protocol) 113 | reactor.run() 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## TwistedProxy 2 | **TwistedProxy** is a python proxy that aims to capture, decrypt & save Clash Royale game traffic. This is an adapted version for v2.4 that use a workaround based on frida since Supercell enforced their game protection which make the serverKey patching impossible. 3 | 4 | ### Setup the proxy 5 | The proxy need some external dependencies to run: 6 | 7 | **If you want the frida script to be injected at proxy runtime:** 8 | 9 | >- Install **ADB** and add it to your path 10 | >- Setup **frida-server** on your device if you want to run the frida script at the proxy launch, here is a guide: [https://www.frida.re/docs/android/](https://www.frida.re/docs/android/) 11 | 12 | 1. Install the modded version of **tweetnacl**. Just run `python setup.py build_ext -b ../TCP` in TweetnaclMod directory to install it 13 | 1. Run `python -m pip install -r requirements.txt` to install the others dependencies 14 | 15 | ### How to use it ? 16 | 17 | To start the proxy you will just have to run the following command: 18 | > python Main.py 19 | 20 | 21 | However the proxy accept some optionals arguments that are: 22 | 23 | * `-f`: the game will be automatically spawned and the frida script will be injected at proxy runtime 24 | * `-n`: connect to frida via network rather than USB 25 | * `-v`: the proxy will be run in verbose mode that basically output packets hexdump in terminal 26 | * `-r`: all packets will be saved in the repository you've set in config.json (ReplayDirectory key) 27 | * `-u`: UDP proxy will be launched too 28 | * `-a`: optional path to adb, useful if using specific adb/Android emulator 29 | 30 | ### UDP Proxy 31 | 32 | Before running the UDP Proxy you should set the local ip where the proxy is running in config.json (UDPHost key). 33 | 34 | ### Credits 35 | 36 | [Misha](https://github.com/MISHA-CRDEV) - For the crypto workaround 37 | [iGio](https://github.com/iGio90) - For all his amazing contribution to the RE community of the game 38 | **Nameless** - For the huge help and explanations about the UDP protocol 39 | 40 | ### PS 41 | 42 | Any question or bug to report ? Feel free to contact me at @GaLaXy1036#1601 on discord -------------------------------------------------------------------------------- /Replay.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | 5 | 6 | class Replay: 7 | 8 | def __init__(self, dirname): 9 | self.session = None 10 | self.dirname = dirname 11 | 12 | self.tcp_path = '{}/TCP'.format(self.dirname) 13 | self.udp_path = '{}/UDP'.format(self.dirname) 14 | 15 | self.tcp_message_index_path = '{}/message.index'.format(self.tcp_path) 16 | self.udp_session_index_path = '{}/session.index'.format(self.udp_path) 17 | 18 | self.udp_session_path = None 19 | self.udp_message_index_path = None 20 | 21 | if not os.path.isdir(self.dirname): 22 | self.init_directory() 23 | 24 | else: 25 | self.check_directory() 26 | 27 | def init_directory(self): 28 | os.makedirs(self.dirname) 29 | os.makedirs(self.tcp_path) 30 | os.makedirs(self.udp_path) 31 | 32 | self.write_index(self.tcp_message_index_path) 33 | self.write_index(self.udp_session_index_path) 34 | 35 | def check_directory(self): 36 | if not os.path.isdir(self.tcp_path): 37 | os.makedirs(self.tcp_path) 38 | self.write_index(self.tcp_message_index_path) 39 | 40 | elif not os.path.isfile(self.tcp_message_index_path): 41 | self.write_index(self.tcp_message_index_path) 42 | 43 | if not os.path.isdir(self.udp_path): 44 | os.makedirs(self.udp_path) 45 | self.write_index(self.udp_session_index_path) 46 | 47 | elif not os.path.isfile(self.udp_session_index_path): 48 | self.write_index(self.udp_session_index_path) 49 | 50 | def write_index(self, path, index='0'): 51 | with open(path, 'w') as f: 52 | f.write(index) 53 | 54 | def increment_index(self, path, index): 55 | self.write_index(path, str(index + 1)) 56 | 57 | def get_index(self, path): 58 | with open(path, 'r') as f: 59 | return int(f.read()) 60 | 61 | def save_tcp_packet(self, packet_name, data): 62 | index = self.get_index(self.tcp_message_index_path) 63 | 64 | with open('{}/{}-{}.bin'.format(self.tcp_path, index, packet_name), 'wb') as f: 65 | f.write(data) 66 | 67 | self.increment_index(self.tcp_message_index_path, index) 68 | 69 | def save_udp_packet(self, session, packet_name, data): 70 | session_index = self.get_index(self.udp_session_index_path) 71 | 72 | if self.session is None: 73 | self.session = session 74 | 75 | self.udp_session_path = '{}/Session-{}'.format(self.udp_path, session_index) 76 | self.udp_message_index_path = '{}/packet.index'.format(self.udp_session_path) 77 | 78 | if not os.path.isdir(self.udp_session_path): 79 | os.makedirs(self.udp_session_path) 80 | self.write_index(self.udp_message_index_path) 81 | 82 | elif session != self.session: 83 | self.session = session 84 | self.increment_index(self.udp_session_index_path, session_index) 85 | 86 | session_index += 1 87 | 88 | self.udp_session_path = '{}/Session-{}'.format(self.udp_path, session_index) 89 | self.udp_message_index_path = '{}/packet.index'.format(self.udp_session_path) 90 | 91 | os.makedirs(self.udp_session_path) 92 | self.write_index(self.udp_message_index_path) 93 | 94 | packet_index = self.get_index(self.udp_message_index_path) 95 | 96 | with open('{}/{}-{}.bin'.format(self.udp_session_path, packet_index, packet_name), 'wb') as f: 97 | f.write(data) 98 | 99 | self.increment_index(self.udp_message_index_path, packet_index) 100 | -------------------------------------------------------------------------------- /TCP/Client/endpoint.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from twisted.internet.endpoints import TCP4ClientEndpoint 4 | 5 | 6 | class ClientEndpoint(TCP4ClientEndpoint): 7 | 8 | @property 9 | def host(self): 10 | return self._host 11 | 12 | @property 13 | def port(self): 14 | return self._port 15 | -------------------------------------------------------------------------------- /TCP/Client/factory.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from TCP.Client.protocol import ClientProtocol 4 | from twisted.internet.protocol import ClientFactory 5 | 6 | 7 | class ClientFactory(ClientFactory): 8 | 9 | def __init__(self, server): 10 | self.server = server 11 | 12 | def buildProtocol(self, addr): 13 | return ClientProtocol(self) 14 | -------------------------------------------------------------------------------- /TCP/Client/protocol.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import hexdump 4 | import socket 5 | 6 | from TCP.PacketReceiver import packetReceiver 7 | from TCP.Packet.packetEnum import packet_enum 8 | from UDP.packetEnum import udp_packet_enum 9 | from twisted.internet.protocol import Protocol 10 | 11 | UDP_IP = "127.0.0.1" 12 | UDP_PORT = 9340 13 | 14 | class ClientProtocol(packetReceiver, Protocol): 15 | 16 | def __init__(self, factory): 17 | self.factory = factory 18 | self.factory.server.client = self 19 | self.server = self.factory.server 20 | self.crypto = self.server.crypto 21 | self.udpsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 22 | 23 | def connectionMade(self): 24 | self.peer = self.transport.getPeer() 25 | print('[*] Connected to {}:{}'.format(self.peer.host, self.peer.port)) 26 | 27 | def connectionLost(self, reason): 28 | print('[*] Server closed the connection !') 29 | self.server.transport.loseConnection() 30 | 31 | def processPacket(self, packet_id, data): 32 | decrypted = self.crypto.decrypt_server_packet(packet_id, data[7:]) 33 | 34 | if packet_id == 27579 and self.server.factory.args.udp: 35 | client_host = self.server.transport.getPeer().host 36 | 37 | decrypted = self.server.factory.udp_protocol.build_udp_info_packet(client_host, decrypted) 38 | 39 | encrypted = self.crypto.encrypt_server_packet(packet_id, decrypted) 40 | payload = packet_id.to_bytes(2, 'big') + len(encrypted).to_bytes(3, 'big') + data[5:7] + encrypted 41 | 42 | self.server.transport.write(payload) 43 | bstr = (packet_id).to_bytes(2, byteorder='big') 44 | if len(decrypted) < 40: 45 | self.udpsock.sendto(bstr+decrypted, (UDP_IP, UDP_PORT)) 46 | 47 | packet_name = packet_enum.get(packet_id, udp_packet_enum.get(packet_id, packet_id)) 48 | 49 | print('[*] {} received from server'.format(packet_name)) 50 | 51 | if self.server.factory.args.verbose and decrypted: 52 | print(hexdump.hexdump(decrypted)) 53 | 54 | if self.server.factory.args.replay: 55 | self.server.factory.replay.save_tcp_packet(packet_name, data[:7] + decrypted) 56 | 57 | -------------------------------------------------------------------------------- /TCP/Crypto.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | 5 | from TCP._tweetnacl import ( 6 | crypto_box_afternm, 7 | crypto_box_beforenm, 8 | crypto_scalarmult_base, 9 | crypto_box_open_afternm 10 | ) 11 | from TCP.Nonce import Nonce 12 | 13 | 14 | class Crypto: 15 | 16 | def __init__(self, server_key): 17 | self.session_key = None 18 | self.server_key = bytes.fromhex(server_key) 19 | self.client_sk = bytes.fromhex('85980ab6075cc197ab8de0faba3c699682b459979365435144482f5ebae82145') 20 | self.client_pk = crypto_scalarmult_base(self.client_sk) 21 | self.nonce = None 22 | self.rnonce = None 23 | self.snonce = None 24 | self.s = None 25 | self.k = None 26 | 27 | def encrypt_client_packet(self, packet_id, payload): 28 | if packet_id == 10100: 29 | return payload 30 | 31 | elif packet_id == 10101: 32 | payload = self.session_key + bytes(self.snonce) + payload 33 | encrypted = crypto_box_afternm(payload, bytes(self.nonce), self.s) 34 | return self.client_pk + encrypted 35 | 36 | elif self.snonce is None: 37 | return payload 38 | 39 | else: 40 | return crypto_box_afternm(payload, bytes(self.snonce), self.k) 41 | 42 | def decrypt_client_packet(self, packet_id, payload): 43 | if packet_id == 10100: 44 | return payload 45 | 46 | elif packet_id == 10101: 47 | if payload[:32] != self.client_pk: 48 | print('[*] It look like frida didn\'t attached properly to your device since client pk don\'t match with the static one !') 49 | os._exit(0) 50 | 51 | payload = payload[32:] # skip the pk since we already know it 52 | self.nonce = Nonce(clientKey=self.client_pk, serverKey=self.server_key) 53 | self.s = crypto_box_beforenm(self.server_key, self.client_sk) 54 | 55 | decrypted = crypto_box_open_afternm(payload, bytes(self.nonce), self.s) 56 | self.snonce = Nonce(decrypted[24:48]) 57 | 58 | return decrypted[48:] 59 | 60 | elif self.snonce is None: 61 | return payload 62 | 63 | else: 64 | self.snonce.increment() 65 | return crypto_box_open_afternm(payload, bytes(self.snonce), self.k) 66 | 67 | def encrypt_server_packet(self, packet_id, payload): 68 | if packet_id == 20100 or (packet_id == 20103 and not self.session_key): 69 | return payload 70 | 71 | elif packet_id in (20103, 24662): 72 | nonce = Nonce(self.snonce, self.client_pk, self.server_key) 73 | payload = bytes(self.rnonce) + self.k + payload 74 | encrypted = crypto_box_afternm(payload, bytes(nonce), self.s) 75 | 76 | return encrypted 77 | 78 | else: 79 | return crypto_box_afternm(payload, bytes(self.rnonce), self.k) 80 | 81 | def decrypt_server_packet(self, packet_id, payload): 82 | if packet_id == 20100: 83 | self.session_key = payload[-24:] 84 | return payload 85 | 86 | elif packet_id == 20103 and not self.session_key: 87 | return payload 88 | 89 | elif packet_id in (20103, 24662): 90 | nonce = Nonce(self.snonce, self.client_pk, self.server_key) 91 | 92 | decrypted = crypto_box_open_afternm(payload, bytes(nonce), self.s) 93 | 94 | self.rnonce = Nonce(decrypted[:24]) 95 | self.k = decrypted[24:56] 96 | 97 | return decrypted[56:] 98 | 99 | else: 100 | self.rnonce.increment() 101 | return crypto_box_open_afternm(payload, bytes(self.rnonce), self.k) 102 | -------------------------------------------------------------------------------- /TCP/Nonce.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from os import urandom 4 | 5 | from hashlib import blake2b 6 | from TCP._tweetnacl import crypto_box_NONCEBYTES 7 | 8 | 9 | class Nonce: 10 | 11 | def __init__(self, nonce=None, clientKey=None, serverKey=None): 12 | if not clientKey: 13 | if nonce: 14 | self._nonce = nonce 15 | 16 | else: 17 | self._nonce = urandom(crypto_box_NONCEBYTES) 18 | 19 | else: 20 | b2 = blake2b(digest_size=24) 21 | if nonce: 22 | b2.update(bytes(nonce)) 23 | b2.update(bytes(clientKey)) 24 | b2.update(serverKey) 25 | self._nonce = b2.digest() 26 | 27 | def __bytes__(self): 28 | return self._nonce 29 | 30 | def __len__(self): 31 | return len(self._nonce) 32 | 33 | def increment(self): 34 | self._nonce = (int.from_bytes(self._nonce, 'little') + 2).to_bytes( 35 | crypto_box_NONCEBYTES, 'little') 36 | -------------------------------------------------------------------------------- /TCP/Packet/packetEnum.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | packet_enum = { 5 | # Client Packet 6 | 10100: "ClientHello", 7 | 10101: "Login", 8 | 14888: "ClientCapabilities", 9 | 15665: "KeepAlive", 10 | 11 | # Server Packet 12 | 20100: "ServerHello", 13 | 20103: "LoginFailed", 14 | 24662: "LoginOK", 15 | 22006: "OwnHomeData", 16 | 20247: "KeepAliveOk", 17 | 25612: "SectorState", 18 | 27691: "GoogleAccountAlreadyBound" 19 | } 20 | -------------------------------------------------------------------------------- /TCP/Packet/reader.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from io import BytesIO 4 | 5 | 6 | class Reader(BytesIO): 7 | 8 | def __init__(self, data): 9 | super().__init__(data) 10 | 11 | @property 12 | def has_remaining_bytes(self): 13 | return len(self.getvalue()) > self.tell() 14 | 15 | def reinit(self, data): 16 | self.flush() 17 | self.seek(0) 18 | self.truncate(0) 19 | self.write(data) 20 | self.seek(0) 21 | 22 | def read_byte(self): 23 | return int.from_bytes(self.read(1), 'big') 24 | 25 | def read_uint32(self): 26 | return int.from_bytes(self.read(4), 'big') 27 | 28 | def read_string(self): 29 | return self.read(self.read_uint32()).decode('utf-8') 30 | 31 | def read_vint(self): 32 | shift = 0 33 | result = 0 34 | 35 | while True: 36 | byte = self.read(1) 37 | if shift == 0: 38 | byte = self._sevenBitRotateLeft(byte) 39 | 40 | i = int.from_bytes(byte, "big") 41 | result |= (i & 0x7f) << shift 42 | shift += 7 43 | if not (i & 0x80): 44 | break 45 | 46 | return (((result) >> 1) ^ (-((result) & 1))) 47 | 48 | def _sevenBitRotateLeft(self, byte): 49 | n = int.from_bytes(byte, 'big') 50 | seventh = (n & 0x40) >> 6 # save 7th bit 51 | msb = (n & 0x80) >> 7 # save msb 52 | n <<= 1 # rotate to the left 53 | n &= ~(0x181) # clear 8th and 1st bit and 9th if any 54 | n |= (msb << 7) | (seventh) # insert msb and 6th back in 55 | return bytes([n]) 56 | 57 | def read_bytearray(self): 58 | return self.read(self.read_uint32()) 59 | -------------------------------------------------------------------------------- /TCP/Packet/writer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from io import BytesIO 4 | 5 | 6 | class Writer(BytesIO): 7 | 8 | def __init__(self): 9 | super().__init__() 10 | 11 | def write_byte(self, value): 12 | self.write(value.to_bytes(1, 'big')) 13 | 14 | def write_uint32(self, value): 15 | self.write(value.to_bytes(4, 'big')) 16 | 17 | def write_string(self, value): 18 | if value: 19 | self.write_uint32(len(value)) 20 | self.write(value.encode('utf-8')) 21 | 22 | else: 23 | self.write_uint32(0xffffffff) 24 | 25 | def write_vint(self, value): 26 | rotate = True 27 | 28 | if value == 0: 29 | self.write_byte(0) 30 | 31 | else: 32 | value = (value << 1) ^ (value >> 31) 33 | while value: 34 | b = value & 0x7f 35 | 36 | if value >= 0x80: 37 | b |= 0x80 38 | 39 | if rotate: 40 | rotate = False 41 | lsb = b & 0x1 42 | msb = (b & 0x80) >> 7 43 | b >>= 1 44 | b &= ~(0xC0) 45 | b |= (msb << 7) | (lsb << 6) 46 | 47 | self.write_byte(b) 48 | value >>= 7 49 | 50 | def write_bytearray(self, value): 51 | self.write_uint32(len(value)) 52 | self.write(value) 53 | -------------------------------------------------------------------------------- /TCP/PacketReceiver.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | class packetReceiver: 5 | 6 | buffer = b'' 7 | packet = b'' 8 | 9 | def dataReceived(self, data): 10 | 11 | self.buffer += data 12 | while self.buffer: 13 | if self.packet: 14 | packet_id = int.from_bytes(self.packet[:2], "big") 15 | packet_length = int.from_bytes(self.packet[2:5], "big") 16 | 17 | if len(self.buffer) >= packet_length: 18 | self.packet += self.buffer[:packet_length] 19 | self.processPacket(packet_id, self.packet) 20 | self.packet = b"" 21 | self.buffer = self.buffer[packet_length:] 22 | 23 | else: 24 | break 25 | 26 | elif len(self.buffer) >= 7: 27 | self.packet = self.buffer[:7] 28 | 29 | if len(self.buffer) == 7 and int.from_bytes(self.packet[2:5], 'big') == 0: 30 | packet_id = int.from_bytes(self.packet[:2], "big") 31 | self.processPacket(packet_id, self.packet) 32 | 33 | self.buffer = self.buffer[7:] 34 | -------------------------------------------------------------------------------- /TCP/Server/endpoint.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from twisted.internet.endpoints import TCP4ServerEndpoint 4 | 5 | 6 | class ServerEndpoint(TCP4ServerEndpoint): 7 | 8 | @property 9 | def interface(self): 10 | if not self._interface: 11 | return "0.0.0.0" 12 | 13 | else: 14 | return self._interface 15 | 16 | @property 17 | def port(self): 18 | return self._port 19 | -------------------------------------------------------------------------------- /TCP/Server/factory.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from twisted.internet.protocol import Factory 4 | from TCP.Server.protocol import ServerProtocol 5 | 6 | 7 | class ServerFactory(Factory): 8 | 9 | def __init__(self, client_endpoint, udp_protocol, crypto, replay, arguments): 10 | self.client_endpoint = client_endpoint 11 | self.udp_protocol = udp_protocol 12 | self.replay = replay 13 | self.crypto = crypto 14 | self.args = arguments 15 | 16 | def buildProtocol(self, endpoint): 17 | return ServerProtocol(self) 18 | -------------------------------------------------------------------------------- /TCP/Server/protocol.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import hexdump 4 | import socket 5 | 6 | from twisted.internet import reactor 7 | from TCP.Client.factory import ClientFactory 8 | from TCP.PacketReceiver import packetReceiver 9 | from TCP.Packet.packetEnum import packet_enum 10 | from UDP.packetEnum import udp_packet_enum 11 | from twisted.internet.protocol import Protocol 12 | 13 | UDP_IP = "127.0.0.1" 14 | UDP_PORT = 9340 15 | class ServerProtocol(packetReceiver, Protocol): 16 | 17 | def __init__(self, factory): 18 | self.factory = factory 19 | self.factory.server = self 20 | self.crypto = self.factory.crypto 21 | self.client = None 22 | self.udpsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 23 | 24 | def connectionMade(self): 25 | self.peer = self.transport.getPeer() 26 | print('[*] New connection from {}'.format(self.peer.host)) 27 | self.factory.client_endpoint.connect(ClientFactory(self)) 28 | 29 | def connectionLost(self, reason): 30 | print('[*] Client disconnected !') 31 | if self.client: 32 | self.client.transport.loseConnection() 33 | 34 | def processPacket(self, packet_id, data): 35 | 36 | if not self.client: 37 | reactor.callLater(0.25, self.processPacket, packet_id, data) 38 | return 39 | 40 | decrypted = self.crypto.decrypt_client_packet(packet_id, data[7:]) 41 | encrypted = self.crypto.encrypt_client_packet(packet_id, decrypted) 42 | payload = packet_id.to_bytes(2, 'big') + len(encrypted).to_bytes(3, 'big') + data[5:7] + encrypted 43 | 44 | packet_name = packet_enum.get(packet_id, udp_packet_enum.get(packet_id, packet_id)) 45 | 46 | print('[*] {} received from client'.format(packet_name)) 47 | 48 | self.client.transport.write(payload) 49 | bstr = (packet_id).to_bytes(2, byteorder='big') 50 | if len(decrypted) < 40: 51 | self.udpsock.sendto(bstr+decrypted, (UDP_IP, UDP_PORT)) 52 | 53 | if self.factory.args.verbose and decrypted: 54 | print(hexdump.hexdump(decrypted)) 55 | 56 | if self.factory.args.replay: 57 | self.factory.replay.save_tcp_packet(packet_name, data[:7] + decrypted) 58 | 59 | -------------------------------------------------------------------------------- /TweetnaclMod/randombytes.c: -------------------------------------------------------------------------------- 1 | // In the case that are compiling on linux, we need to define _GNU_SOURCE 2 | // *before* randombytes.h is included. Otherwise SYS_getrandom will not be 3 | // declared. 4 | #if defined(__linux__) 5 | # define _GNU_SOURCE 6 | #endif /* defined(__linux__) */ 7 | 8 | #include "randombytes.h" 9 | 10 | #if defined(_WIN32) 11 | /* Windows */ 12 | # include 13 | # include /* CryptAcquireContext, CryptGenRandom */ 14 | #endif /* defined(_WIN32) */ 15 | 16 | 17 | #if defined(__linux__) 18 | /* Linux */ 19 | // We would need to include , but not every target has access 20 | // to the linux headers. We only need RNDGETENTCNT, so we instead inline it. 21 | // RNDGETENTCNT is originally defined in `include/uapi/linux/random.h` in the 22 | // linux repo. 23 | # define RNDGETENTCNT 0x80045200 24 | 25 | # include 26 | # include 27 | # include 28 | # include 29 | # include 30 | # include 31 | # include 32 | # include 33 | # include 34 | # include 35 | 36 | // We need SSIZE_MAX as the maximum read len from /dev/urandom 37 | # if !defined(SSIZE_MAX) 38 | # define SSIZE_MAX (SIZE_MAX / 2 - 1) 39 | # endif /* defined(SSIZE_MAX) */ 40 | 41 | #endif /* defined(__linux__) */ 42 | 43 | 44 | #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 45 | /* Dragonfly, FreeBSD, NetBSD, OpenBSD (has arc4random) */ 46 | # include 47 | # if defined(BSD) 48 | # include 49 | # endif 50 | #endif 51 | 52 | #if defined(__EMSCRIPTEN__) 53 | # include 54 | #endif /* defined(__EMSCRIPTEN__) */ 55 | 56 | 57 | #if defined(_WIN32) 58 | static int randombytes_win32_randombytes(unsigned char* buf, long long n) 59 | { 60 | HCRYPTPROV ctx; 61 | BOOL tmp; 62 | 63 | tmp = CryptAcquireContext(&ctx, NULL, NULL, PROV_RSA_FULL, 64 | CRYPT_VERIFYCONTEXT); 65 | if (tmp == FALSE) return -1; 66 | 67 | tmp = CryptGenRandom(ctx, n, (BYTE*) buf); 68 | if (tmp == FALSE) return -1; 69 | 70 | tmp = CryptReleaseContext(ctx, 0); 71 | if (tmp == FALSE) return -1; 72 | 73 | return 0; 74 | } 75 | #endif /* defined(_WIN32) */ 76 | 77 | 78 | #if defined(__linux__) && defined(SYS_getrandom) 79 | static int randombytes_linux_randombytes_getrandom(unsigned char *buf, long long n) 80 | { 81 | /* I have thought about using a separate PRF, seeded by getrandom, but 82 | * it turns out that the performance of getrandom is good enough 83 | * (250 MB/s on my laptop). 84 | */ 85 | size_t offset = 0, chunk; 86 | int ret; 87 | while (n > 0) { 88 | /* getrandom does not allow chunks larger than 33554431 */ 89 | chunk = n <= 33554431 ? n : 33554431; 90 | do { 91 | ret = syscall(SYS_getrandom, (char *)buf + offset, chunk, 0); 92 | } while (ret == -1 && errno == EINTR); 93 | if (ret < 0) return ret; 94 | offset += ret; 95 | n -= ret; 96 | } 97 | assert(n == 0); 98 | return 0; 99 | } 100 | #endif /* defined(__linux__) && defined(SYS_getrandom) */ 101 | 102 | 103 | #if defined(__linux__) && !defined(SYS_getrandom) 104 | static int randombytes_linux_get_entropy_avail(int fd) 105 | { 106 | int ret; 107 | ioctl(fd, RNDGETENTCNT, &ret); 108 | return ret; 109 | } 110 | 111 | 112 | static int randombytes_linux_wait_for_entropy(int device) 113 | { 114 | /* We will block on /dev/random, because any increase in the OS' entropy 115 | * level will unblock the request. I use poll here (as does libsodium), 116 | * because we don't *actually* want to read from the device. */ 117 | const int bits = 128; 118 | struct pollfd pfd; 119 | int fd, retcode; /* Used as file descriptor *and* poll() return code */ 120 | 121 | /* If the device has enough entropy already, we will want to return early */ 122 | if (randombytes_linux_get_entropy_avail(device) >= bits) { 123 | return 0; 124 | } 125 | 126 | do { 127 | fd = open("/dev/random", O_RDONLY); 128 | } while (fd == -1 && errno == EINTR); /* EAGAIN will not occur */ 129 | if (fd == -1) { 130 | /* Unrecoverable IO error */ 131 | return -1; 132 | } 133 | 134 | pfd.fd = fd; 135 | pfd.events = POLLIN; 136 | do { 137 | retcode = poll(&pfd, 1, -1); 138 | } while ((retcode == -1 && (errno == EINTR || errno == EAGAIN)) || 139 | randombytes_linux_get_entropy_avail(device) < bits); 140 | if (retcode != 1) { 141 | do { 142 | retcode = close(fd); 143 | } while (retcode == -1 && errno == EINTR); 144 | return -1; 145 | } 146 | retcode = close(fd); 147 | return retcode; 148 | } 149 | 150 | 151 | static int randombytes_linux_randombytes_urandom(unsigned char *buf, long long n) 152 | { 153 | int fd; 154 | size_t offset = 0, count; 155 | ssize_t tmp; 156 | do { 157 | fd = open("/dev/urandom", O_RDONLY); 158 | } while (fd == -1 && errno == EINTR); 159 | if (randombytes_linux_wait_for_entropy(fd) == -1) return -1; 160 | 161 | while (n > 0) { 162 | count = n <= SSIZE_MAX ? n : SSIZE_MAX; 163 | tmp = read(fd, (char *)buf + offset, count); 164 | if (tmp == -1 && (errno == EAGAIN || errno == EINTR)) { 165 | continue; 166 | } 167 | if (tmp == -1) return -1; /* Unrecoverable IO error */ 168 | offset += tmp; 169 | n -= tmp; 170 | } 171 | assert(n == 0); 172 | return 0; 173 | } 174 | #endif /* defined(__linux__) && !defined(SYS_getrandom) */ 175 | 176 | 177 | #if defined(BSD) 178 | static int randombytes_bsd_randombytes(unsigned char *buf, long long n) 179 | { 180 | arc4random_buf(buf, n); 181 | return 0; 182 | } 183 | #endif /* defined(BSD) */ 184 | 185 | 186 | #if defined(__EMSCRIPTEN__) 187 | static int randombytes_js_randombytes_nodejs(unsigned char *buf, long long n) { 188 | int ret = EM_ASM_INT({ 189 | const crypto = require('crypto'); 190 | try { 191 | writeArrayToMemory(crypto.randomBytes($1), $0); 192 | return 0; 193 | } catch (error) { 194 | return -1; 195 | } 196 | }, buf, n); 197 | return ret; 198 | } 199 | #endif /* defined(__EMSCRIPTEN__) */ 200 | 201 | 202 | void randombytes(unsigned char *buf, long long n) 203 | { 204 | #if defined(__EMSCRIPTEN__) 205 | # pragma message("Using crypto api from NodeJS") 206 | randombytes_js_randombytes_nodejs(buf, n); 207 | #elif defined(__linux__) 208 | # if defined(SYS_getrandom) 209 | # pragma message("Using getrandom system call") 210 | /* Use getrandom system call */ 211 | randombytes_linux_randombytes_getrandom(buf, n); 212 | # else 213 | # pragma message("Using /dev/urandom device") 214 | /* When we have enough entropy, we can read from /dev/urandom */ 215 | randombytes_linux_randombytes_urandom(buf, n); 216 | # endif 217 | #elif defined(BSD) 218 | # pragma message("Using arc4random system call") 219 | /* Use arc4random system call */ 220 | randombytes_bsd_randombytes(buf, n); 221 | #elif defined(_WIN32) 222 | # pragma message("Using Windows cryptographic API") 223 | /* Use windows API */ 224 | randombytes_win32_randombytes(buf, n); 225 | #else 226 | # error "randombytes(...) is not supported on this platform" 227 | #endif 228 | } -------------------------------------------------------------------------------- /TweetnaclMod/randombytes.h: -------------------------------------------------------------------------------- 1 | #ifndef sss_RANDOMBYTES_H 2 | #define sss_RANDOMBYTES_H 3 | 4 | /* 5 | * Write `n` bytes of high quality random bytes to `buf` 6 | */ 7 | extern void randombytes(unsigned char *buf, long long n); 8 | 9 | #endif /* sss_RANDOMBYTES_H */ -------------------------------------------------------------------------------- /TweetnaclMod/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Hsalsa17 mod 5 | 6 | """ 7 | Build and install the TweetNaCl wrapper. 8 | """ 9 | 10 | from __future__ import print_function 11 | 12 | import platform 13 | 14 | from distutils.core import setup, Extension 15 | 16 | 17 | libraries = [] 18 | 19 | if platform.system() == "Windows": 20 | libraries.append("advapi32") 21 | 22 | nacl_module = Extension('_tweetnacl', 23 | ["tweetnaclmodule.c", "tweetnacl.c", "randombytes.c"], 24 | libraries=libraries, 25 | extra_compile_args=["-O2", 26 | "-funroll-loops", 27 | "-fomit-frame-pointer"]) 28 | 29 | setup(name = 'tweetnaclMod', 30 | version = '0.1', 31 | author = "Brian Warner, Jan Mojžíš", 32 | description = """Python wrapper for TweetNaCl""", 33 | ext_modules = [nacl_module], 34 | packages = ["nacl"], 35 | package_dir = {"nacl": ""}, 36 | ) 37 | -------------------------------------------------------------------------------- /TweetnaclMod/tweetnacl.c: -------------------------------------------------------------------------------- 1 | #include "tweetnacl.h" 2 | #define FOR(i,n) for (i = 0;i < n;++i) 3 | #define sv static void 4 | 5 | typedef unsigned char u8; 6 | typedef unsigned long u32; 7 | typedef unsigned long long u64; 8 | typedef long long i64; 9 | typedef i64 gf[16]; 10 | extern void randombytes(u8 *,u64); 11 | 12 | static const u8 13 | _0[16], 14 | _9[32] = {9}; 15 | static const gf 16 | gf0, 17 | gf1 = {1}, 18 | _121665 = {0xDB41,1}, 19 | D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203}, 20 | D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406}, 21 | X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169}, 22 | Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666}, 23 | I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83}; 24 | 25 | static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); } 26 | 27 | static u32 ld32(const u8 *x) 28 | { 29 | u32 u = x[3]; 30 | u = (u<<8)|x[2]; 31 | u = (u<<8)|x[1]; 32 | return (u<<8)|x[0]; 33 | } 34 | 35 | static u64 dl64(const u8 *x) 36 | { 37 | u64 i,u=0; 38 | FOR(i,8) u=(u<<8)|x[i]; 39 | return u; 40 | } 41 | 42 | sv st32(u8 *x,u32 u) 43 | { 44 | int i; 45 | FOR(i,4) { x[i] = u; u >>= 8; } 46 | } 47 | 48 | sv ts64(u8 *x,u64 u) 49 | { 50 | int i; 51 | for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; } 52 | } 53 | 54 | static int vn(const u8 *x,const u8 *y,int n) 55 | { 56 | u32 i,d = 0; 57 | FOR(i,n) d |= x[i]^y[i]; 58 | return (1 & ((d - 1) >> 8)) - 1; 59 | } 60 | 61 | int crypto_verify_16(const u8 *x,const u8 *y) 62 | { 63 | return vn(x,y,16); 64 | } 65 | 66 | int crypto_verify_32(const u8 *x,const u8 *y) 67 | { 68 | return vn(x,y,32); 69 | } 70 | 71 | sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h) 72 | { 73 | u32 w[16],x[16],y[16],t[4]; 74 | int i,j,m; 75 | 76 | FOR(i,4) { 77 | x[5*i] = ld32(c+4*i); 78 | x[1+i] = ld32(k+4*i); 79 | x[6+i] = ld32(in+4*i); 80 | x[11+i] = ld32(k+16+4*i); 81 | } 82 | 83 | FOR(i,16) y[i] = x[i]; 84 | 85 | FOR(i,17) { //Salsa17 mod 86 | FOR(j,4) { 87 | FOR(m,4) t[m] = x[(5*j+4*m)%16]; 88 | t[1] ^= L32(t[0]+t[3], 7); 89 | t[2] ^= L32(t[1]+t[0], 9); 90 | t[3] ^= L32(t[2]+t[1],13); 91 | t[0] ^= L32(t[3]+t[2],18); 92 | FOR(m,4) w[4*j+(j+m)%4] = t[m]; 93 | } 94 | FOR(m,16) x[m] = w[m]; 95 | } 96 | 97 | if (h) { 98 | FOR(i,16) x[i] += y[i]; 99 | FOR(i,4) { 100 | x[5*i] -= ld32(c+4*i); 101 | x[6+i] -= ld32(in+4*i); 102 | } 103 | FOR(i,4) { 104 | st32(out+4*i,x[5*i]); 105 | st32(out+16+4*i,x[6+i]); 106 | } 107 | } else 108 | FOR(i,16) st32(out + 4 * i,x[i] + y[i]); 109 | } 110 | 111 | int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) 112 | { 113 | core(out,in,k,c,0); 114 | return 0; 115 | } 116 | 117 | int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) 118 | { 119 | core(out,in,k,c,1); 120 | return 0; 121 | } 122 | 123 | static const u8 sigma[16] = "expand 32-byte k"; 124 | 125 | int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k) 126 | { 127 | u8 z[16],x[64]; 128 | u32 u,i; 129 | if (!b) return 0; 130 | FOR(i,16) z[i] = 0; 131 | FOR(i,8) z[i] = n[i]; 132 | while (b >= 64) { 133 | crypto_core_salsa20(x,z,k,sigma); 134 | FOR(i,64) c[i] = (m?m[i]:0) ^ x[i]; 135 | u = 1; 136 | for (i = 8;i < 16;++i) { 137 | u += (u32) z[i]; 138 | z[i] = u; 139 | u >>= 8; 140 | } 141 | b -= 64; 142 | c += 64; 143 | if (m) m += 64; 144 | } 145 | if (b) { 146 | crypto_core_salsa20(x,z,k,sigma); 147 | FOR(i,b) c[i] = (m?m[i]:0) ^ x[i]; 148 | } 149 | return 0; 150 | } 151 | 152 | int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k) 153 | { 154 | return crypto_stream_salsa20_xor(c,0,d,n,k); 155 | } 156 | 157 | int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k) 158 | { 159 | u8 s[32]; 160 | crypto_core_hsalsa20(s,n,k,sigma); 161 | return crypto_stream_salsa20(c,d,n+16,s); 162 | } 163 | 164 | int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) 165 | { 166 | u8 s[32]; 167 | crypto_core_hsalsa20(s,n,k,sigma); 168 | return crypto_stream_salsa20_xor(c,m,d,n+16,s); 169 | } 170 | 171 | sv add1305(u32 *h,const u32 *c) 172 | { 173 | u32 j,u = 0; 174 | FOR(j,17) { 175 | u += h[j] + c[j]; 176 | h[j] = u & 255; 177 | u >>= 8; 178 | } 179 | } 180 | 181 | static const u32 minusp[17] = { 182 | 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 183 | } ; 184 | 185 | int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k) 186 | { 187 | u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17]; 188 | 189 | FOR(j,17) r[j]=h[j]=0; 190 | FOR(j,16) r[j]=k[j]; 191 | r[3]&=15; 192 | r[4]&=252; 193 | r[7]&=15; 194 | r[8]&=252; 195 | r[11]&=15; 196 | r[12]&=252; 197 | r[15]&=15; 198 | 199 | while (n > 0) { 200 | FOR(j,17) c[j] = 0; 201 | for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j]; 202 | c[j] = 1; 203 | m += j; n -= j; 204 | add1305(h,c); 205 | FOR(i,17) { 206 | x[i] = 0; 207 | FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]); 208 | } 209 | FOR(i,17) h[i] = x[i]; 210 | u = 0; 211 | FOR(j,16) { 212 | u += h[j]; 213 | h[j] = u & 255; 214 | u >>= 8; 215 | } 216 | u += h[16]; h[16] = u & 3; 217 | u = 5 * (u >> 2); 218 | FOR(j,16) { 219 | u += h[j]; 220 | h[j] = u & 255; 221 | u >>= 8; 222 | } 223 | u += h[16]; h[16] = u; 224 | } 225 | 226 | FOR(j,17) g[j] = h[j]; 227 | add1305(h,minusp); 228 | s = -(h[16] >> 7); 229 | FOR(j,17) h[j] ^= s & (g[j] ^ h[j]); 230 | 231 | FOR(j,16) c[j] = k[j + 16]; 232 | c[16] = 0; 233 | add1305(h,c); 234 | FOR(j,16) out[j] = h[j]; 235 | return 0; 236 | } 237 | 238 | int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k) 239 | { 240 | u8 x[16]; 241 | crypto_onetimeauth(x,m,n,k); 242 | return crypto_verify_16(h,x); 243 | } 244 | 245 | int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) 246 | { 247 | int i; 248 | if (d < 32) return -1; 249 | crypto_stream_xor(c,m,d,n,k); 250 | crypto_onetimeauth(c + 16,c + 32,d - 32,c); 251 | FOR(i,16) c[i] = 0; 252 | return 0; 253 | } 254 | 255 | int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) 256 | { 257 | int i; 258 | u8 x[32]; 259 | if (d < 32) return -1; 260 | crypto_stream(x,32,n,k); 261 | if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1; 262 | crypto_stream_xor(m,c,d,n,k); 263 | FOR(i,32) m[i] = 0; 264 | return 0; 265 | } 266 | 267 | sv set25519(gf r, const gf a) 268 | { 269 | int i; 270 | FOR(i,16) r[i]=a[i]; 271 | } 272 | 273 | sv car25519(gf o) 274 | { 275 | int i; 276 | i64 c; 277 | FOR(i,16) { 278 | o[i]+=(1LL<<16); 279 | c=o[i]>>16; 280 | o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15); 281 | o[i]-=c<<16; 282 | } 283 | } 284 | 285 | sv sel25519(gf p,gf q,int b) 286 | { 287 | i64 t,i,c=~(b-1); 288 | FOR(i,16) { 289 | t= c&(p[i]^q[i]); 290 | p[i]^=t; 291 | q[i]^=t; 292 | } 293 | } 294 | 295 | sv pack25519(u8 *o,const gf n) 296 | { 297 | int i,j,b; 298 | gf m,t; 299 | FOR(i,16) t[i]=n[i]; 300 | car25519(t); 301 | car25519(t); 302 | car25519(t); 303 | FOR(j,2) { 304 | m[0]=t[0]-0xffed; 305 | for(i=1;i<15;i++) { 306 | m[i]=t[i]-0xffff-((m[i-1]>>16)&1); 307 | m[i-1]&=0xffff; 308 | } 309 | m[15]=t[15]-0x7fff-((m[14]>>16)&1); 310 | b=(m[15]>>16)&1; 311 | m[14]&=0xffff; 312 | sel25519(t,m,1-b); 313 | } 314 | FOR(i,16) { 315 | o[2*i]=t[i]&0xff; 316 | o[2*i+1]=t[i]>>8; 317 | } 318 | } 319 | 320 | static int neq25519(const gf a, const gf b) 321 | { 322 | u8 c[32],d[32]; 323 | pack25519(c,a); 324 | pack25519(d,b); 325 | return crypto_verify_32(c,d); 326 | } 327 | 328 | static u8 par25519(const gf a) 329 | { 330 | u8 d[32]; 331 | pack25519(d,a); 332 | return d[0]&1; 333 | } 334 | 335 | sv unpack25519(gf o, const u8 *n) 336 | { 337 | int i; 338 | FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8); 339 | o[15]&=0x7fff; 340 | } 341 | 342 | sv A(gf o,const gf a,const gf b) 343 | { 344 | int i; 345 | FOR(i,16) o[i]=a[i]+b[i]; 346 | } 347 | 348 | sv Z(gf o,const gf a,const gf b) 349 | { 350 | int i; 351 | FOR(i,16) o[i]=a[i]-b[i]; 352 | } 353 | 354 | sv M(gf o,const gf a,const gf b) 355 | { 356 | i64 i,j,t[31]; 357 | FOR(i,31) t[i]=0; 358 | FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j]; 359 | FOR(i,15) t[i]+=38*t[i+16]; 360 | FOR(i,16) o[i]=t[i]; 361 | car25519(o); 362 | car25519(o); 363 | } 364 | 365 | sv S(gf o,const gf a) 366 | { 367 | M(o,a,a); 368 | } 369 | 370 | sv inv25519(gf o,const gf i) 371 | { 372 | gf c; 373 | int a; 374 | FOR(a,16) c[a]=i[a]; 375 | for(a=253;a>=0;a--) { 376 | S(c,c); 377 | if(a!=2&&a!=4) M(c,c,i); 378 | } 379 | FOR(a,16) o[a]=c[a]; 380 | } 381 | 382 | sv pow2523(gf o,const gf i) 383 | { 384 | gf c; 385 | int a; 386 | FOR(a,16) c[a]=i[a]; 387 | for(a=250;a>=0;a--) { 388 | S(c,c); 389 | if(a!=1) M(c,c,i); 390 | } 391 | FOR(a,16) o[a]=c[a]; 392 | } 393 | 394 | int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p) 395 | { 396 | u8 z[32]; 397 | i64 x[80],r,i; 398 | gf a,b,c,d,e,f; 399 | FOR(i,31) z[i]=n[i]; 400 | z[31]=(n[31]&127)|64; 401 | z[0]&=248; 402 | unpack25519(x,p); 403 | FOR(i,16) { 404 | b[i]=x[i]; 405 | d[i]=a[i]=c[i]=0; 406 | } 407 | a[0]=d[0]=1; 408 | for(i=254;i>=0;--i) { 409 | r=(z[i>>3]>>(i&7))&1; 410 | sel25519(a,b,r); 411 | sel25519(c,d,r); 412 | A(e,a,c); 413 | Z(a,a,c); 414 | A(c,b,d); 415 | Z(b,b,d); 416 | S(d,e); 417 | S(f,a); 418 | M(a,c,a); 419 | M(c,b,e); 420 | A(e,a,c); 421 | Z(a,a,c); 422 | S(b,a); 423 | Z(c,d,f); 424 | M(a,c,_121665); 425 | A(a,a,d); 426 | M(c,c,a); 427 | M(a,d,f); 428 | M(d,b,x); 429 | S(b,e); 430 | sel25519(a,b,r); 431 | sel25519(c,d,r); 432 | } 433 | FOR(i,16) { 434 | x[i+16]=a[i]; 435 | x[i+32]=c[i]; 436 | x[i+48]=b[i]; 437 | x[i+64]=d[i]; 438 | } 439 | inv25519(x+32,x+32); 440 | M(x+16,x+16,x+32); 441 | pack25519(q,x+16); 442 | return 0; 443 | } 444 | 445 | int crypto_scalarmult_base(u8 *q,const u8 *n) 446 | { 447 | return crypto_scalarmult(q,n,_9); 448 | } 449 | 450 | int crypto_box_keypair(u8 *y,u8 *x) 451 | { 452 | randombytes(x,32); 453 | return crypto_scalarmult_base(y,x); 454 | } 455 | 456 | int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x) 457 | { 458 | u8 s[32]; 459 | crypto_scalarmult(s,x,y); 460 | return crypto_core_hsalsa20(k,_0,s,sigma); 461 | } 462 | 463 | int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) 464 | { 465 | return crypto_secretbox(c,m,d,n,k); 466 | } 467 | 468 | int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) 469 | { 470 | return crypto_secretbox_open(m,c,d,n,k); 471 | } 472 | 473 | int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x) 474 | { 475 | u8 k[32]; 476 | crypto_box_beforenm(k,y,x); 477 | return crypto_box_afternm(c,m,d,n,k); 478 | } 479 | 480 | int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x) 481 | { 482 | u8 k[32]; 483 | crypto_box_beforenm(k,y,x); 484 | return crypto_box_open_afternm(m,c,d,n,k); 485 | } 486 | 487 | static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); } 488 | static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); } 489 | static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); } 490 | static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); } 491 | static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); } 492 | static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); } 493 | static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); } 494 | 495 | static const u64 K[80] = 496 | { 497 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 498 | 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 499 | 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 500 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 501 | 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 502 | 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 503 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 504 | 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 505 | 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 506 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 507 | 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 508 | 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 509 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 510 | 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 511 | 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 512 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 513 | 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 514 | 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 515 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 516 | 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 517 | }; 518 | 519 | int crypto_hashblocks(u8 *x,const u8 *m,u64 n) 520 | { 521 | u64 z[8],b[8],a[8],w[16],t; 522 | int i,j; 523 | 524 | FOR(i,8) z[i] = a[i] = dl64(x + 8 * i); 525 | 526 | while (n >= 128) { 527 | FOR(i,16) w[i] = dl64(m + 8 * i); 528 | 529 | FOR(i,80) { 530 | FOR(j,8) b[j] = a[j]; 531 | t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16]; 532 | b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]); 533 | b[3] += t; 534 | FOR(j,8) a[(j+1)%8] = b[j]; 535 | if (i%16 == 15) 536 | FOR(j,16) 537 | w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]); 538 | } 539 | 540 | FOR(i,8) { a[i] += z[i]; z[i] = a[i]; } 541 | 542 | m += 128; 543 | n -= 128; 544 | } 545 | 546 | FOR(i,8) ts64(x+8*i,z[i]); 547 | 548 | return n; 549 | } 550 | 551 | static const u8 iv[64] = { 552 | 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 553 | 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 554 | 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 555 | 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 556 | 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 557 | 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 558 | 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 559 | 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 560 | } ; 561 | 562 | int crypto_hash(u8 *out,const u8 *m,u64 n) 563 | { 564 | u8 h[64],x[256]; 565 | u64 i,b = n; 566 | 567 | FOR(i,64) h[i] = iv[i]; 568 | 569 | crypto_hashblocks(h,m,n); 570 | m += n; 571 | n &= 127; 572 | m -= n; 573 | 574 | FOR(i,256) x[i] = 0; 575 | FOR(i,n) x[i] = m[i]; 576 | x[n] = 128; 577 | 578 | n = 256-128*(n<112); 579 | x[n-9] = b >> 61; 580 | ts64(x+n-8,b<<3); 581 | crypto_hashblocks(h,x,n); 582 | 583 | FOR(i,64) out[i] = h[i]; 584 | 585 | return 0; 586 | } 587 | 588 | sv add(gf p[4],gf q[4]) 589 | { 590 | gf a,b,c,d,t,e,f,g,h; 591 | 592 | Z(a, p[1], p[0]); 593 | Z(t, q[1], q[0]); 594 | M(a, a, t); 595 | A(b, p[0], p[1]); 596 | A(t, q[0], q[1]); 597 | M(b, b, t); 598 | M(c, p[3], q[3]); 599 | M(c, c, D2); 600 | M(d, p[2], q[2]); 601 | A(d, d, d); 602 | Z(e, b, a); 603 | Z(f, d, c); 604 | A(g, d, c); 605 | A(h, b, a); 606 | 607 | M(p[0], e, f); 608 | M(p[1], h, g); 609 | M(p[2], g, f); 610 | M(p[3], e, h); 611 | } 612 | 613 | sv cswap(gf p[4],gf q[4],u8 b) 614 | { 615 | int i; 616 | FOR(i,4) 617 | sel25519(p[i],q[i],b); 618 | } 619 | 620 | sv pack(u8 *r,gf p[4]) 621 | { 622 | gf tx, ty, zi; 623 | inv25519(zi, p[2]); 624 | M(tx, p[0], zi); 625 | M(ty, p[1], zi); 626 | pack25519(r, ty); 627 | r[31] ^= par25519(tx) << 7; 628 | } 629 | 630 | sv scalarmult(gf p[4],gf q[4],const u8 *s) 631 | { 632 | int i; 633 | set25519(p[0],gf0); 634 | set25519(p[1],gf1); 635 | set25519(p[2],gf1); 636 | set25519(p[3],gf0); 637 | for (i = 255;i >= 0;--i) { 638 | u8 b = (s[i/8]>>(i&7))&1; 639 | cswap(p,q,b); 640 | add(q,p); 641 | add(p,p); 642 | cswap(p,q,b); 643 | } 644 | } 645 | 646 | sv scalarbase(gf p[4],const u8 *s) 647 | { 648 | gf q[4]; 649 | set25519(q[0],X); 650 | set25519(q[1],Y); 651 | set25519(q[2],gf1); 652 | M(q[3],X,Y); 653 | scalarmult(p,q,s); 654 | } 655 | 656 | int crypto_sign_keypair(u8 *pk, u8 *sk) 657 | { 658 | u8 d[64]; 659 | gf p[4]; 660 | int i; 661 | 662 | randombytes(sk, 32); 663 | crypto_hash(d, sk, 32); 664 | d[0] &= 248; 665 | d[31] &= 127; 666 | d[31] |= 64; 667 | 668 | scalarbase(p,d); 669 | pack(pk,p); 670 | 671 | FOR(i,32) sk[32 + i] = pk[i]; 672 | return 0; 673 | } 674 | 675 | static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10}; 676 | 677 | sv modL(u8 *r,i64 x[64]) 678 | { 679 | i64 carry,i,j; 680 | for (i = 63;i >= 32;--i) { 681 | carry = 0; 682 | for (j = i - 32;j < i - 12;++j) { 683 | x[j] += carry - 16 * x[i] * L[j - (i - 32)]; 684 | carry = (x[j] + 128) >> 8; 685 | x[j] -= carry << 8; 686 | } 687 | x[j] += carry; 688 | x[i] = 0; 689 | } 690 | carry = 0; 691 | FOR(j,32) { 692 | x[j] += carry - (x[31] >> 4) * L[j]; 693 | carry = x[j] >> 8; 694 | x[j] &= 255; 695 | } 696 | FOR(j,32) x[j] -= carry * L[j]; 697 | FOR(i,32) { 698 | x[i+1] += x[i] >> 8; 699 | r[i] = x[i] & 255; 700 | } 701 | } 702 | 703 | sv reduce(u8 *r) 704 | { 705 | i64 x[64],i; 706 | FOR(i,64) x[i] = (u64) r[i]; 707 | FOR(i,64) r[i] = 0; 708 | modL(r,x); 709 | } 710 | 711 | int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk) 712 | { 713 | u8 d[64],h[64],r[64]; 714 | i64 i,j,x[64]; 715 | gf p[4]; 716 | 717 | crypto_hash(d, sk, 32); 718 | d[0] &= 248; 719 | d[31] &= 127; 720 | d[31] |= 64; 721 | 722 | *smlen = n+64; 723 | FOR(i,n) sm[64 + i] = m[i]; 724 | FOR(i,32) sm[32 + i] = d[32 + i]; 725 | 726 | crypto_hash(r, sm+32, n+32); 727 | reduce(r); 728 | scalarbase(p,r); 729 | pack(sm,p); 730 | 731 | FOR(i,32) sm[i+32] = sk[i+32]; 732 | crypto_hash(h,sm,n + 64); 733 | reduce(h); 734 | 735 | FOR(i,64) x[i] = 0; 736 | FOR(i,32) x[i] = (u64) r[i]; 737 | FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j]; 738 | modL(sm + 32,x); 739 | 740 | return 0; 741 | } 742 | 743 | static int unpackneg(gf r[4],const u8 p[32]) 744 | { 745 | gf t, chk, num, den, den2, den4, den6; 746 | set25519(r[2],gf1); 747 | unpack25519(r[1],p); 748 | S(num,r[1]); 749 | M(den,num,D); 750 | Z(num,num,r[2]); 751 | A(den,r[2],den); 752 | 753 | S(den2,den); 754 | S(den4,den2); 755 | M(den6,den4,den2); 756 | M(t,den6,num); 757 | M(t,t,den); 758 | 759 | pow2523(t,t); 760 | M(t,t,num); 761 | M(t,t,den); 762 | M(t,t,den); 763 | M(r[0],t,den); 764 | 765 | S(chk,r[0]); 766 | M(chk,chk,den); 767 | if (neq25519(chk, num)) M(r[0],r[0],I); 768 | 769 | S(chk,r[0]); 770 | M(chk,chk,den); 771 | if (neq25519(chk, num)) return -1; 772 | 773 | if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]); 774 | 775 | M(r[3],r[0],r[1]); 776 | return 0; 777 | } 778 | 779 | int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk) 780 | { 781 | int i; 782 | u8 t[32],h[64]; 783 | gf p[4],q[4]; 784 | 785 | *mlen = -1; 786 | if (n < 64) return -1; 787 | 788 | if (unpackneg(q,pk)) return -1; 789 | 790 | FOR(i,n) m[i] = sm[i]; 791 | FOR(i,32) m[i+32] = pk[i]; 792 | crypto_hash(h,m,n); 793 | reduce(h); 794 | scalarmult(p,q,h); 795 | 796 | scalarbase(q,sm + 32); 797 | add(p,q); 798 | pack(t,p); 799 | 800 | n -= 64; 801 | if (crypto_verify_32(sm, t)) { 802 | FOR(i,n) m[i] = 0; 803 | return -1; 804 | } 805 | 806 | FOR(i,n) m[i] = sm[i + 64]; 807 | *mlen = n; 808 | return 0; 809 | } 810 | -------------------------------------------------------------------------------- /TweetnaclMod/tweetnacl.h: -------------------------------------------------------------------------------- 1 | #ifndef TWEETNACL_H 2 | #define TWEETNACL_H 3 | #define crypto_auth_PRIMITIVE "hmacsha512256" 4 | #define crypto_auth crypto_auth_hmacsha512256 5 | #define crypto_auth_verify crypto_auth_hmacsha512256_verify 6 | #define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES 7 | #define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES 8 | #define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION 9 | #define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION 10 | #define crypto_auth_hmacsha512256_tweet_BYTES 32 11 | #define crypto_auth_hmacsha512256_tweet_KEYBYTES 32 12 | extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); 13 | extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); 14 | #define crypto_auth_hmacsha512256_tweet_VERSION "-" 15 | #define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet 16 | #define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify 17 | #define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES 18 | #define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES 19 | #define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION 20 | #define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet" 21 | #define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305" 22 | #define crypto_box crypto_box_curve25519xsalsa20poly1305 23 | #define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open 24 | #define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair 25 | #define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm 26 | #define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm 27 | #define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm 28 | #define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES 29 | #define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES 30 | #define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES 31 | #define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES 32 | #define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES 33 | #define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES 34 | #define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION 35 | #define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION 36 | #define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32 37 | #define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32 38 | #define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32 39 | #define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24 40 | #define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32 41 | #define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16 42 | extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *); 43 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *); 44 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *); 45 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *); 46 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 47 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 48 | #define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-" 49 | #define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet 50 | #define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open 51 | #define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair 52 | #define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm 53 | #define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm 54 | #define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm 55 | #define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 56 | #define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 57 | #define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 58 | #define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 59 | #define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 60 | #define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 61 | #define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION 62 | #define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet" 63 | #define crypto_core_PRIMITIVE "salsa20" 64 | #define crypto_core crypto_core_salsa20 65 | #define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES 66 | #define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES 67 | #define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES 68 | #define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES 69 | #define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION 70 | #define crypto_core_VERSION crypto_core_salsa20_VERSION 71 | #define crypto_core_salsa20_tweet_OUTPUTBYTES 64 72 | #define crypto_core_salsa20_tweet_INPUTBYTES 16 73 | #define crypto_core_salsa20_tweet_KEYBYTES 32 74 | #define crypto_core_salsa20_tweet_CONSTBYTES 16 75 | extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *); 76 | #define crypto_core_salsa20_tweet_VERSION "-" 77 | #define crypto_core_salsa20 crypto_core_salsa20_tweet 78 | #define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES 79 | #define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES 80 | #define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES 81 | #define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES 82 | #define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION 83 | #define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet" 84 | #define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32 85 | #define crypto_core_hsalsa20_tweet_INPUTBYTES 16 86 | #define crypto_core_hsalsa20_tweet_KEYBYTES 32 87 | #define crypto_core_hsalsa20_tweet_CONSTBYTES 16 88 | extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *); 89 | #define crypto_core_hsalsa20_tweet_VERSION "-" 90 | #define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet 91 | #define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES 92 | #define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES 93 | #define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES 94 | #define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES 95 | #define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION 96 | #define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet" 97 | #define crypto_hashblocks_PRIMITIVE "sha512" 98 | #define crypto_hashblocks crypto_hashblocks_sha512 99 | #define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES 100 | #define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES 101 | #define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION 102 | #define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION 103 | #define crypto_hashblocks_sha512_tweet_STATEBYTES 64 104 | #define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128 105 | extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long); 106 | #define crypto_hashblocks_sha512_tweet_VERSION "-" 107 | #define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet 108 | #define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES 109 | #define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES 110 | #define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION 111 | #define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet" 112 | #define crypto_hashblocks_sha256_tweet_STATEBYTES 32 113 | #define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64 114 | extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long); 115 | #define crypto_hashblocks_sha256_tweet_VERSION "-" 116 | #define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet 117 | #define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES 118 | #define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES 119 | #define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION 120 | #define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet" 121 | #define crypto_hash_PRIMITIVE "sha512" 122 | #define crypto_hash crypto_hash_sha512 123 | #define crypto_hash_BYTES crypto_hash_sha512_BYTES 124 | #define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION 125 | #define crypto_hash_VERSION crypto_hash_sha512_VERSION 126 | #define crypto_hash_sha512_tweet_BYTES 64 127 | extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long); 128 | #define crypto_hash_sha512_tweet_VERSION "-" 129 | #define crypto_hash_sha512 crypto_hash_sha512_tweet 130 | #define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES 131 | #define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION 132 | #define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet" 133 | #define crypto_hash_sha256_tweet_BYTES 32 134 | extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long); 135 | #define crypto_hash_sha256_tweet_VERSION "-" 136 | #define crypto_hash_sha256 crypto_hash_sha256_tweet 137 | #define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES 138 | #define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION 139 | #define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet" 140 | #define crypto_onetimeauth_PRIMITIVE "poly1305" 141 | #define crypto_onetimeauth crypto_onetimeauth_poly1305 142 | #define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify 143 | #define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES 144 | #define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES 145 | #define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION 146 | #define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION 147 | #define crypto_onetimeauth_poly1305_tweet_BYTES 16 148 | #define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32 149 | extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); 150 | extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); 151 | #define crypto_onetimeauth_poly1305_tweet_VERSION "-" 152 | #define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet 153 | #define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify 154 | #define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES 155 | #define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES 156 | #define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION 157 | #define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet" 158 | #define crypto_scalarmult_PRIMITIVE "curve25519" 159 | #define crypto_scalarmult crypto_scalarmult_curve25519 160 | #define crypto_scalarmult_base crypto_scalarmult_curve25519_base 161 | #define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES 162 | #define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES 163 | #define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION 164 | #define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION 165 | #define crypto_scalarmult_curve25519_tweet_BYTES 32 166 | #define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32 167 | extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *); 168 | extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *); 169 | #define crypto_scalarmult_curve25519_tweet_VERSION "-" 170 | #define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet 171 | #define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base 172 | #define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES 173 | #define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES 174 | #define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION 175 | #define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet" 176 | #define crypto_secretbox_PRIMITIVE "xsalsa20poly1305" 177 | #define crypto_secretbox crypto_secretbox_xsalsa20poly1305 178 | #define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open 179 | #define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES 180 | #define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES 181 | #define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES 182 | #define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES 183 | #define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION 184 | #define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION 185 | #define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32 186 | #define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24 187 | #define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32 188 | #define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16 189 | extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 190 | extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 191 | #define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-" 192 | #define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet 193 | #define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open 194 | #define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 195 | #define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 196 | #define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 197 | #define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 198 | #define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION 199 | #define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet" 200 | #define crypto_sign_PRIMITIVE "ed25519" 201 | #define crypto_sign crypto_sign_ed25519 202 | #define crypto_sign_open crypto_sign_ed25519_open 203 | #define crypto_sign_keypair crypto_sign_ed25519_keypair 204 | #define crypto_sign_BYTES crypto_sign_ed25519_BYTES 205 | #define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES 206 | #define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES 207 | #define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION 208 | #define crypto_sign_VERSION crypto_sign_ed25519_VERSION 209 | #define crypto_sign_ed25519_tweet_BYTES 64 210 | #define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32 211 | #define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64 212 | extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 213 | extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); 214 | extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *); 215 | #define crypto_sign_ed25519_tweet_VERSION "-" 216 | #define crypto_sign_ed25519 crypto_sign_ed25519_tweet 217 | #define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open 218 | #define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair 219 | #define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES 220 | #define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES 221 | #define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES 222 | #define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION 223 | #define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet" 224 | #define crypto_stream_PRIMITIVE "xsalsa20" 225 | #define crypto_stream crypto_stream_xsalsa20 226 | #define crypto_stream_xor crypto_stream_xsalsa20_xor 227 | #define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES 228 | #define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES 229 | #define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION 230 | #define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION 231 | #define crypto_stream_xsalsa20_tweet_KEYBYTES 32 232 | #define crypto_stream_xsalsa20_tweet_NONCEBYTES 24 233 | extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 234 | extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 235 | #define crypto_stream_xsalsa20_tweet_VERSION "-" 236 | #define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet 237 | #define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor 238 | #define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES 239 | #define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES 240 | #define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION 241 | #define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet" 242 | #define crypto_stream_salsa20_tweet_KEYBYTES 32 243 | #define crypto_stream_salsa20_tweet_NONCEBYTES 8 244 | extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 245 | extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); 246 | #define crypto_stream_salsa20_tweet_VERSION "-" 247 | #define crypto_stream_salsa20 crypto_stream_salsa20_tweet 248 | #define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor 249 | #define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES 250 | #define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES 251 | #define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION 252 | #define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet" 253 | #define crypto_verify_PRIMITIVE "16" 254 | #define crypto_verify crypto_verify_16 255 | #define crypto_verify_BYTES crypto_verify_16_BYTES 256 | #define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION 257 | #define crypto_verify_VERSION crypto_verify_16_VERSION 258 | #define crypto_verify_16_tweet_BYTES 16 259 | extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *); 260 | #define crypto_verify_16_tweet_VERSION "-" 261 | #define crypto_verify_16 crypto_verify_16_tweet 262 | #define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES 263 | #define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION 264 | #define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet" 265 | #define crypto_verify_32_tweet_BYTES 32 266 | extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *); 267 | #define crypto_verify_32_tweet_VERSION "-" 268 | #define crypto_verify_32 crypto_verify_32_tweet 269 | #define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES 270 | #define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION 271 | #define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet" 272 | #endif 273 | -------------------------------------------------------------------------------- /TweetnaclMod/tweetnaclmodule.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "tweetnacl.h" 4 | 5 | #if PY_VERSION_HEX < 0x02060000 6 | #define PyBytes_FromStringAndSize PyString_FromStringAndSize 7 | #define PyBytes_AS_STRING PyString_AS_STRING 8 | #define _PyBytes_Resize _PyString_Resize 9 | #endif 10 | 11 | #if PY_VERSION_HEX < 0x02030000 12 | #define PyMODINIT_FUNC DL_EXPORT(void) 13 | #endif 14 | 15 | #if PY_VERSION_HEX < 0x02050000 16 | typedef int Py_ssize_t; 17 | #endif 18 | 19 | #if PY_MAJOR_VERSION < 2 20 | void PyModule_AddIntConstant(PyObject *m, const char *name, long value) { 21 | 22 | PyObject *v, *d; 23 | 24 | d = PyModule_GetDict(m); 25 | if (!d) return; 26 | 27 | v = PyInt_FromLong(value); 28 | if(!v){ PyErr_Clear(); return; } 29 | PyDict_SetItemString(d, name, v); 30 | Py_DECREF(v); 31 | return; 32 | } 33 | void PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) { 34 | 35 | PyObject *v, *d; 36 | 37 | d = PyModule_GetDict(m); 38 | if (!d) return; 39 | 40 | v = PyString_FromString(value); 41 | if(!v){ PyErr_Clear(); return; } 42 | PyDict_SetItemString(d, name, v); 43 | Py_DECREF(v); 44 | return; 45 | } 46 | #endif 47 | 48 | 49 | PyObject *naclexception(const char *text) { 50 | PyErr_SetString(PyExc_ValueError, text); 51 | return (PyObject *)0; 52 | } 53 | 54 | 55 | /* API: a = crypto_onetimeauth(m,k); */ 56 | PyObject *pycrypto_onetimeauth(PyObject *self, PyObject *args, PyObject *kw) { 57 | 58 | const unsigned char *m, *k; 59 | Py_ssize_t msize = 0, ksize = 0; 60 | static const char *kwlist[] = {"m", "k", 0}; 61 | PyObject *ret; 62 | 63 | if (!PyArg_ParseTupleAndKeywords(args, kw, 64 | "|s#s#:crypto_onetimeauth", 65 | (char **)kwlist, 66 | (char **)&m, &msize, 67 | (char **)&k, &ksize)) { 68 | return (PyObject *)0; 69 | } 70 | 71 | if (ksize != crypto_onetimeauth_KEYBYTES) 72 | return naclexception("incorrect key length"); 73 | 74 | ret = PyBytes_FromStringAndSize((char *)0, crypto_onetimeauth_BYTES); 75 | if (!ret) return ret; 76 | crypto_onetimeauth( 77 | (unsigned char *)PyBytes_AS_STRING(ret), 78 | m, 79 | msize, 80 | k 81 | ); 82 | return ret; 83 | } 84 | 85 | const char pycrypto_onetimeauth__doc__[]= 86 | "crypto_onetimeauth(m,k) -> a\n\n\ 87 | The crypto_onetimeauth function authenticates a message m\n\ 88 | using a secret key k. The function returns an authenticator a.\n\ 89 | The authenticator length is always crypto_onetimeauth_BYTES.\n\ 90 | The function raises an exception if len(k) is not crypto_onetimeauth_KEYBYTES.\n\ 91 | This uses Poly1305.\n\ 92 | "; 93 | 94 | 95 | /* API: crypto_onetimeauth_verify(a,m,k); */ 96 | PyObject *pycrypto_onetimeauth_verify(PyObject *self, PyObject *args, PyObject *kw) { 97 | 98 | unsigned char *m, *k, *a; 99 | Py_ssize_t msize = 0, ksize = 0, alen = 0; 100 | static const char *kwlist[] = {"a", "m", "k", 0}; 101 | 102 | if (!PyArg_ParseTupleAndKeywords(args, kw, 103 | "|s#s#s#:crypto_onetimeauth_verify", 104 | (char **)kwlist, 105 | (char **)&a, &alen, 106 | (char **)&m, &msize, 107 | (char **)&k, &ksize)) { 108 | return (PyObject *)0; 109 | } 110 | 111 | if (alen != crypto_onetimeauth_BYTES) 112 | return naclexception("incorrect authenticator length"); 113 | 114 | if (ksize != crypto_onetimeauth_KEYBYTES) 115 | return naclexception("incorrect key length"); 116 | 117 | if (crypto_onetimeauth_verify(a, m, msize, k) != 0) { 118 | return naclexception("invalid authenticator"); 119 | } 120 | 121 | Py_INCREF(Py_None); 122 | return Py_None; 123 | } 124 | 125 | const char pycrypto_onetimeauth_verify__doc__[]= 126 | "crypto_onetimeauth_verify(a,m,k)\n\n\ 127 | The crypto_onetimeauth_verify function checks that:\n\ 128 | len(k) is crypto_onetimeauth_KEYBYTES;\n\ 129 | len(a) is crypto_onetimeauth_BYTES;\n\ 130 | and a is a correct authenticator of a message m under the secret key k.\n\ 131 | If any of these checks fail, the function raises an exception.\n\ 132 | This uses Poly1305.\n\ 133 | "; 134 | 135 | 136 | /* API: h = crypto_hash(m); */ 137 | PyObject *pycrypto_hash(PyObject *self, PyObject *args, PyObject *kw) { 138 | 139 | const unsigned char *m; 140 | Py_ssize_t msize = 0; 141 | static const char *kwlist[] = {"m", 0}; 142 | PyObject *ret; 143 | 144 | if (!PyArg_ParseTupleAndKeywords(args, kw, 145 | "|s#:crypto_hash", 146 | (char **)kwlist, 147 | (char **)&m, &msize)) { 148 | return (PyObject *)0; 149 | } 150 | 151 | ret = PyBytes_FromStringAndSize((char *)0, crypto_hash_BYTES); 152 | if (!ret) return ret; 153 | 154 | crypto_hash( 155 | (unsigned char *)PyBytes_AS_STRING(ret), 156 | m, 157 | msize 158 | ); 159 | 160 | return ret; 161 | } 162 | 163 | const char pycrypto_hash__doc__[]= 164 | "crypto_hash(m) -> h\n\n\ 165 | The crypto_hash function hashes a message m.\n\ 166 | It returns a hash h. The output length len(h) is always crypto_hash_BYTES.\n\ 167 | This uses SHA512.\n\ 168 | "; 169 | 170 | 171 | /* API: crypto_verify_16(x,y); */ 172 | PyObject *pycrypto_verify_16(PyObject *self, PyObject *args, PyObject *kw) { 173 | 174 | const unsigned char *x, *y; 175 | Py_ssize_t xlen = 0, ylen = 0; 176 | static const char *kwlist[] = {"x", "y", 0}; 177 | 178 | if (!PyArg_ParseTupleAndKeywords(args, kw, 179 | "|s#s#:crypto_verify_16", 180 | (char **) kwlist, 181 | (char **)&x, &xlen, 182 | (char **)&y, &ylen)) { 183 | return (PyObject *)0; 184 | } 185 | 186 | if (xlen != crypto_verify_16_BYTES) 187 | return naclexception("incorrect x-string length"); 188 | if (ylen != crypto_verify_16_BYTES) 189 | return naclexception("incorrect y-string length"); 190 | if (crypto_verify_16(x, y) != 0) 191 | return naclexception("strings doesn't match"); 192 | 193 | Py_INCREF(Py_None); 194 | return Py_None; 195 | } 196 | 197 | const char pycrypto_verify_16__doc__[]= 198 | "crypto_verify_16(x,y)\n\n\ 199 | The crypto_verify_16 function checks that:\n\ 200 | len(x) is crypto_verify_16_BYTES;\n\ 201 | len(y) is crypto_verify_16_BYTES;\n\ 202 | and check if strings x and y has same content.\n\ 203 | If any of these checks fail, the function raises an exception.\n\ 204 | The time taken by crypto_verify_16 is independent of the contents of x and y.\n\ 205 | "; 206 | 207 | 208 | /* API: crypto_verify_32(x,y); */ 209 | PyObject *pycrypto_verify_32(PyObject *self, PyObject *args, PyObject *kw) { 210 | 211 | const unsigned char *x, *y; 212 | Py_ssize_t xlen = 0, ylen = 0; 213 | static const char *kwlist[] = {"x", "y", 0}; 214 | 215 | if (!PyArg_ParseTupleAndKeywords(args, kw, 216 | "|s#s#:crypto_verify_32", 217 | (char **) kwlist, 218 | (char **)&x, &xlen, 219 | (char **)&y, &ylen)) { 220 | return (PyObject *)0; 221 | } 222 | 223 | if (xlen != crypto_verify_32_BYTES) 224 | return naclexception("incorrect x-string length"); 225 | if (ylen != crypto_verify_32_BYTES) 226 | return naclexception("incorrect y-string length"); 227 | if (crypto_verify_32(x, y) != 0) 228 | return naclexception("strings doesn't match"); 229 | 230 | Py_INCREF(Py_None); 231 | return Py_None; 232 | } 233 | 234 | const char pycrypto_verify_32__doc__[]= 235 | "crypto_verify_32(x,y)\n\n\ 236 | The crypto_verify_32 function checks that:\n\ 237 | len(x) is crypto_verify_32_BYTES;\n\ 238 | len(y) is crypto_verify_32_BYTES;\n\ 239 | and check if strings x and y has same content.\n\ 240 | If any of these checks fail, the function raises an exception.\n\ 241 | The time taken by crypto_verify_32 is independent of the contents of x and y.\n\ 242 | "; 243 | 244 | 245 | /* API: crypto_scalarmult(n,p); */ 246 | PyObject *pycrypto_scalarmult(PyObject *self, PyObject *args, PyObject *kw) { 247 | 248 | const unsigned char *n, *p; 249 | Py_ssize_t nlen = 0, plen = 0; 250 | static const char *kwlist[] = {"n", "p", 0}; 251 | PyObject *ret; 252 | 253 | if (!PyArg_ParseTupleAndKeywords(args, kw, 254 | "|s#s#:crypto_scalarmult", 255 | (char **)kwlist, 256 | (char **)&n, &nlen, 257 | (char **)&p, &plen)) { 258 | return (PyObject *)0; 259 | } 260 | 261 | if (nlen != crypto_scalarmult_SCALARBYTES) 262 | return naclexception("incorrect scalar length"); 263 | if (plen != crypto_scalarmult_BYTES) 264 | return naclexception("incorrect element length"); 265 | 266 | ret = PyBytes_FromStringAndSize((char *)0, crypto_scalarmult_BYTES); 267 | if (!ret) return ret; 268 | 269 | crypto_scalarmult( 270 | (unsigned char *)PyBytes_AS_STRING(ret), 271 | n, 272 | p 273 | ); 274 | 275 | return ret; 276 | } 277 | 278 | const char pycrypto_scalarmult__doc__[]= 279 | "crypto_scalarmult(n) -> q\n\n\ 280 | This function multiplies a group element p by an integer n.\n\ 281 | It returns the resulting group element q of length crypto_scalarmult_BYTES.\n\ 282 | The function raises an exception if len(p) is not crypto_scalarmult_BYTES.\n\ 283 | It also raises an exception if len(n) is not crypto_scalarmult_SCALARBYTES.\n\ 284 | This uses Curve25519.\n\ 285 | "; 286 | 287 | 288 | /* API: crypto_scalarmult_base(n); */ 289 | PyObject *pycrypto_scalarmult_base(PyObject *self, PyObject *args, PyObject *kw) { 290 | 291 | const unsigned char *n; 292 | Py_ssize_t nlen = 0; 293 | static const char *kwlist[] = {"n", 0}; 294 | PyObject *ret; 295 | 296 | if (!PyArg_ParseTupleAndKeywords(args, kw, 297 | "|s#:crypto_scalarmult_base", 298 | (char **)kwlist, 299 | (char **)&n, &nlen)) { 300 | return (PyObject *)0; 301 | } 302 | 303 | if (nlen != crypto_scalarmult_SCALARBYTES) 304 | return naclexception("incorrect scalar length"); 305 | 306 | ret = PyBytes_FromStringAndSize((char *)0, crypto_scalarmult_BYTES); 307 | if (!ret) return ret; 308 | 309 | crypto_scalarmult_base( 310 | (unsigned char *)PyBytes_AS_STRING(ret), 311 | n 312 | ); 313 | return ret; 314 | } 315 | 316 | const char pycrypto_scalarmult_base__doc__[]= 317 | "crypto_scalarmult_base(n,p) -> q\n\n\ 318 | The crypto_scalarmult_base function computes\n\ 319 | the scalar product of a standard group element and an integer n.\n\ 320 | It returns the resulting group element q of length crypto_scalarmult_BYTES.\n\ 321 | It raises an exception if len(n) is not crypto_scalarmult_SCALARBYTES.\n\ 322 | This uses Curve25519 and the standard base point '9'.\n\ 323 | "; 324 | 325 | 326 | /* API: c = crypto_stream(clen,n,k); */ 327 | PyObject *pycrypto_stream(PyObject *self, PyObject *args, PyObject *kw) { 328 | 329 | const unsigned char *n, *k; 330 | Py_ssize_t nsize = 0, ksize = 0, clen = 0; 331 | static const char *kwlist[] = {"clen", "n", "k", 0}; 332 | PyObject *ret; 333 | 334 | if (!PyArg_ParseTupleAndKeywords(args, kw, 335 | #if PY_VERSION_HEX < 0x02050000 336 | "|is#s#:crypto_stream", 337 | #else 338 | "|ns#s#:crypto_stream", 339 | #endif 340 | 341 | (char **) kwlist, 342 | &clen, 343 | (char **)&n, &nsize, 344 | (char **)&k, &ksize)) { 345 | return (PyObject *)0; 346 | } 347 | 348 | if (nsize != crypto_stream_NONCEBYTES) return naclexception("incorrect nonce length"); 349 | if (ksize != crypto_stream_KEYBYTES) return naclexception("incorrect key length"); 350 | if (clen < 0) return naclexception("incorrect clen"); 351 | 352 | ret = PyBytes_FromStringAndSize((char *)0, clen); 353 | if (!ret) return ret; 354 | 355 | crypto_stream( 356 | (unsigned char *)PyBytes_AS_STRING(ret), 357 | clen, 358 | n, 359 | k 360 | ); 361 | 362 | return ret; 363 | } 364 | 365 | const char pycrypto_stream__doc__[]= 366 | "crypto_stream(clen,n,k) -> c\n\n\ 367 | The crypto_stream function produces a clen-byte stream c\n\ 368 | as a function of a secret key k and a nonce n.\n\ 369 | The function raises an exception:\n\ 370 | if len(k) is not crypto_stream_KEYBYTES;\n\ 371 | if len(n) is not crypto_stream_NONCEBYTES;\n\ 372 | if clen is smaller than 0.\n\ 373 | This uses XSalsa20, with a 24-byte nonce.\n\ 374 | "; 375 | 376 | 377 | /* API: c = crypto_stream_xor(m,n,k); */ 378 | PyObject *pycrypto_stream_xor(PyObject *self, PyObject *args, PyObject *kw) { 379 | 380 | const unsigned char *m, *n, *k; 381 | Py_ssize_t msize = 0, nsize = 0, ksize = 0; 382 | static const char *kwlist[] = {"m", "n", "k", 0}; 383 | PyObject *ret; 384 | 385 | if (!PyArg_ParseTupleAndKeywords(args, kw, 386 | "|s#s#s#:crypto_stream", 387 | (char **) kwlist, 388 | (char **)&m, &msize, 389 | (char **)&n, &nsize, 390 | (char **)&k, &ksize)) { 391 | return (PyObject *)0; 392 | } 393 | 394 | if (nsize != crypto_stream_NONCEBYTES) return naclexception("incorrect nonce length"); 395 | if (ksize != crypto_stream_KEYBYTES) return naclexception("incorrect key length"); 396 | 397 | ret = PyBytes_FromStringAndSize((char *)0, msize); 398 | if (!ret) return ret; 399 | 400 | crypto_stream_xor( 401 | (unsigned char *) PyBytes_AS_STRING(ret), 402 | m, msize, 403 | n, 404 | k 405 | ); 406 | return ret; 407 | } 408 | 409 | const char pycrypto_stream_xor__doc__[]= 410 | "crypto_stream_xor(m,n,k) -> c\n\n\ 411 | The crypto_stream_xor function encrypts a message m using a secret key k\n\ 412 | and a nonce n. The crypto_stream_xor function returns the ciphertext c.\n\ 413 | The function raises an exception:\n\ 414 | if len(k) is not crypto_stream_KEYBYTES;\n\ 415 | if len(n) is not crypto_stream_NONCEBYTES.\n\ 416 | This uses XSalsa20, with a 24-byte nonce.\n\ 417 | "; 418 | 419 | 420 | /* API: sm = crypto_sign(m,sk); */ 421 | PyObject *pycrypto_sign(PyObject *self, PyObject *args, PyObject *kw) { 422 | 423 | Py_ssize_t mlen = 0, sksize = 0; 424 | const unsigned char *sk, *m; 425 | static const char *kwlist[] = {"m", "sk", 0}; 426 | PyObject *ret; 427 | unsigned long long smlen; 428 | 429 | if (!PyArg_ParseTupleAndKeywords(args, kw, 430 | "|s#s#:crypto_sign", 431 | (char **) kwlist, 432 | (char **)&m, &mlen, 433 | (char **)&sk, &sksize)) { 434 | return (PyObject *)0; 435 | } 436 | 437 | if (sksize != crypto_sign_SECRETKEYBYTES) 438 | return naclexception("incorrect secret-key length"); 439 | 440 | ret = PyBytes_FromStringAndSize((char *)0, mlen + crypto_sign_BYTES); 441 | if (!ret) return ret; 442 | 443 | if (crypto_sign( 444 | (unsigned char *)PyBytes_AS_STRING(ret), 445 | &smlen, 446 | m, 447 | mlen, 448 | sk 449 | ) != 0) { 450 | Py_DECREF(ret); 451 | return naclexception("crypto_sign returns nonzero"); 452 | } 453 | _PyBytes_Resize(&ret, smlen); 454 | return ret; 455 | } 456 | 457 | const char pycrypto_sign__doc__[]= 458 | "crypto_sign(m,sk) -> sm\n\n\ 459 | The crypto_sign function signs a message m using the sender's secret key sk.\n\ 460 | The crypto_sign function returns the resulting signed message sm.\n\ 461 | The function raises an exception if len(sk) is not crypto_sign_SECRETKEYBYTES.\n\ 462 | This uses Ed25519.\n\ 463 | "; 464 | 465 | 466 | /* API: m = crypto_sign_open(sm,pk); */ 467 | PyObject *pycrypto_sign_open(PyObject *self, PyObject *args, PyObject *kw) { 468 | 469 | const unsigned char *sm, *pk; 470 | Py_ssize_t smlen=0, pksize=0; 471 | static const char *kwlist[] = {"sm", "pk", 0}; 472 | PyObject *ret; 473 | unsigned long long mlen; 474 | 475 | if (!PyArg_ParseTupleAndKeywords(args, kw, 476 | "|s#s#:crypto_sign_open", 477 | (char **)kwlist, 478 | (char **)&sm, &smlen, 479 | (char **)&pk, &pksize)) { 480 | return (PyObject *)0; 481 | } 482 | 483 | if (pksize != crypto_sign_PUBLICKEYBYTES) 484 | return naclexception("incorrect public-key length"); 485 | 486 | ret = PyBytes_FromStringAndSize((char *)0, smlen); 487 | if (!ret) return ret; 488 | 489 | if (crypto_sign_open( 490 | (unsigned char *)PyBytes_AS_STRING(ret), 491 | &mlen, 492 | sm, 493 | smlen, 494 | pk 495 | ) != 0) { 496 | Py_DECREF(ret); 497 | return naclexception("ciphertext fails verification"); 498 | } 499 | _PyBytes_Resize(&ret, mlen); 500 | return ret; 501 | } 502 | 503 | const char pycrypto_sign_open__doc__[]= 504 | "crypto_sign_open(sm,pk) -> m\n\n\ 505 | The crypto_sign_open function verifies the signature in\n\ 506 | sm using the receiver's secret key sk.\n\ 507 | The crypto_sign_open function returns the message m.\n\n\ 508 | If the signature fails verification, crypto_sign_open raises an exception.\n\ 509 | The function also raises an exception if len(pk) is not crypto_sign_PUBLICKEYBYTES.\n\ 510 | This uses Ed25519.\n\ 511 | "; 512 | 513 | 514 | /* API: (pk,sk) = crypto_sign_keypair(); */ 515 | PyObject *pycrypto_sign_keypair(PyObject *self) { 516 | 517 | PyObject *pypk, *pysk, *ret; 518 | 519 | pypk = PyBytes_FromStringAndSize((char *)0, crypto_sign_PUBLICKEYBYTES); 520 | if (!pypk) return (PyObject *)0; 521 | 522 | pysk = PyBytes_FromStringAndSize((char *)0, crypto_sign_SECRETKEYBYTES); 523 | if (!pysk) { 524 | Py_DECREF(pypk); 525 | return (PyObject *)0; 526 | } 527 | ret = PyTuple_New(2); 528 | if (!ret) { 529 | Py_DECREF(pypk); 530 | Py_DECREF(pysk); 531 | return (PyObject *)0; 532 | } 533 | PyTuple_SET_ITEM(ret, 0, pypk); 534 | PyTuple_SET_ITEM(ret, 1, pysk); 535 | 536 | crypto_sign_keypair( 537 | (unsigned char *)PyBytes_AS_STRING(pypk), 538 | (unsigned char *)PyBytes_AS_STRING(pysk) 539 | ); 540 | 541 | return ret; 542 | } 543 | 544 | const char pycrypto_sign_keypair__doc__[]= 545 | "crypto_sign_keypair() -> (pk,sk)\n\n\ 546 | The crypto_sign_keypair function randomly generates a secret key and\n\ 547 | a corresponding public key. It returns tuple containing the secret key in sk and\n\ 548 | public key in pk.\n\ 549 | It guarantees that sk has crypto_sign_SECRETKEYBYTES bytes\n\ 550 | and that pk has crypto_sign_PUBLICKEYBYTES bytes.\n\ 551 | This uses Ed25519.\n\ 552 | "; 553 | 554 | 555 | /* API: c = crypto_secretbox(m,n,k); */ 556 | PyObject *pycrypto_secretbox(PyObject *self, PyObject *args, PyObject *kw) { 557 | 558 | const unsigned char *m, *n, *k; 559 | Py_ssize_t msize = 0, nsize = 0, ksize = 0; 560 | static const char *kwlist[] = {"m", "n", "k", 0}; 561 | PyObject *ret; 562 | long long i; 563 | unsigned long long mlen; 564 | unsigned char *mpad; 565 | unsigned char *cpad; 566 | 567 | if (!PyArg_ParseTupleAndKeywords(args, kw, 568 | "|s#s#s#:crypto_secretbox", 569 | (char **)kwlist, 570 | (char **)&m, &msize, 571 | (char **)&n, &nsize, 572 | (char **)&k, &ksize)) { 573 | return (PyObject *)0; 574 | } 575 | 576 | if (nsize != crypto_secretbox_NONCEBYTES) return naclexception("incorrect nonce length"); 577 | if (ksize != crypto_secretbox_KEYBYTES) return naclexception("incorrect key length"); 578 | 579 | mlen = msize + crypto_secretbox_ZEROBYTES; 580 | mpad = PyMem_Malloc(mlen); 581 | if (!mpad) return PyErr_NoMemory(); 582 | cpad = PyMem_Malloc(mlen); 583 | if (!cpad) { 584 | PyMem_Free(mpad); 585 | return PyErr_NoMemory(); 586 | } 587 | 588 | for (i = 0; i < crypto_secretbox_ZEROBYTES; ++i) mpad[i] = 0; 589 | for (i = crypto_secretbox_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_secretbox_ZEROBYTES]; 590 | 591 | crypto_secretbox(cpad, mpad, mlen, n, k); 592 | 593 | ret = PyBytes_FromStringAndSize( 594 | (char *)cpad + crypto_secretbox_BOXZEROBYTES, 595 | mlen - crypto_secretbox_BOXZEROBYTES 596 | ); 597 | 598 | PyMem_Free(mpad); 599 | PyMem_Free(cpad); 600 | return ret; 601 | } 602 | 603 | const char pycrypto_secretbox__doc__[]= 604 | "crypto_secretbox(m,n,k) -> c\n\n\ 605 | The crypto_secretbox function encrypts and authenticates\n\ 606 | a message m using a secret key k and a nonce n. \n\ 607 | The crypto_secretbox function returns the resulting ciphertext c. \n\ 608 | The function raises an exception if len(k) is not crypto_secretbox_KEYBYTES.\n\ 609 | The function also raises an exception if len(n) is not crypto_secretbox_NONCEBYTES.\n\ 610 | This uses XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\ 611 | "; 612 | 613 | 614 | /* API: m = crypto_secretbox_open(c,n,k); */ 615 | PyObject *pycrypto_secretbox_open(PyObject *self, PyObject *args, PyObject *kw) { 616 | 617 | const unsigned char *c, *n, *k; 618 | Py_ssize_t csize = 0, nsize = 0, ksize = 0; 619 | static const char *kwlist[] = {"c", "n", "k", 0}; 620 | PyObject *ret; 621 | long long i; 622 | unsigned long long clen; 623 | unsigned char *mpad; 624 | unsigned char *cpad; 625 | 626 | if (!PyArg_ParseTupleAndKeywords(args, kw, 627 | "|s#s#s#:crypto_secretbox_open", 628 | (char **)kwlist, 629 | (char **)&c, &csize, 630 | (char **)&n, &nsize, 631 | (char **)&k, &ksize)) { 632 | return (PyObject *)0; 633 | } 634 | 635 | if (nsize != crypto_secretbox_NONCEBYTES) return naclexception("incorrect nonce length"); 636 | if (ksize != crypto_secretbox_KEYBYTES) return naclexception("incorrect key length"); 637 | 638 | clen = csize + crypto_secretbox_BOXZEROBYTES; 639 | mpad = PyMem_Malloc(clen); 640 | if (!mpad) return PyErr_NoMemory(); 641 | cpad = PyMem_Malloc(clen); 642 | if (!cpad) { 643 | PyMem_Free(mpad); 644 | return PyErr_NoMemory(); 645 | } 646 | 647 | for (i = 0; i < crypto_secretbox_BOXZEROBYTES; ++i) cpad[i] = 0; 648 | for (i = crypto_secretbox_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_secretbox_BOXZEROBYTES]; 649 | 650 | if (crypto_secretbox_open(mpad, cpad, clen, n, k) != 0) { 651 | PyMem_Free(mpad); 652 | PyMem_Free(cpad); 653 | return naclexception("ciphertext fails verification"); 654 | } 655 | if (clen < crypto_secretbox_ZEROBYTES) { 656 | PyMem_Free(mpad); 657 | PyMem_Free(cpad); 658 | return naclexception("ciphertext too short"); 659 | } 660 | 661 | ret = PyBytes_FromStringAndSize( 662 | (char *)mpad + crypto_secretbox_ZEROBYTES, 663 | clen - crypto_secretbox_ZEROBYTES 664 | ); 665 | 666 | PyMem_Free(mpad); 667 | PyMem_Free(cpad); 668 | return ret; 669 | } 670 | 671 | const char pycrypto_secretbox_open__doc__[]= 672 | "crypto_secretbox_open(c,n,k) -> m\n\n\ 673 | The crypto_secretbox_open function verifies and decrypts \n\ 674 | a ciphertext c using a secret key k and a nonce n.\n\ 675 | The crypto_secretbox_open function returns the resulting plaintext m.\n\ 676 | If the ciphertext fails verification, crypto_secretbox_open raises an exception.\n\ 677 | The function also raises an exception if len(k) is not crypto_secretbox_KEYBYTES,\n\ 678 | or if len(n) is not crypto_secretbox_NONCEBYTES.\n\ 679 | This uses XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\ 680 | "; 681 | 682 | 683 | /* C API: c = crypto_box(m,n,pk,sk); */ 684 | PyObject *pycrypto_box(PyObject *self, PyObject *args, PyObject *kw) { 685 | 686 | const unsigned char *m, *n, *pk, *sk; 687 | Py_ssize_t msize = 0, nsize = 0, pksize = 0, sksize = 0; 688 | static const char *kwlist[] = {"m", "n", "pk", "sk", 0}; 689 | PyObject *ret; 690 | long long i; 691 | unsigned long long mlen; 692 | unsigned char *mpad; 693 | unsigned char *cpad; 694 | 695 | if (!PyArg_ParseTupleAndKeywords(args, kw, 696 | "|s#s#s#s#:crypto_box", 697 | (char **)kwlist, 698 | (char **)&m, &msize, 699 | (char **)&n, &nsize, 700 | (char **)&pk, &pksize, 701 | (char **)&sk, &sksize)) { 702 | return (PyObject *)0; 703 | } 704 | 705 | if (nsize != crypto_box_NONCEBYTES) return naclexception("incorrect nonce length"); 706 | if (pksize != crypto_box_PUBLICKEYBYTES) return naclexception("incorrect public-key length"); 707 | if (sksize != crypto_box_SECRETKEYBYTES) return naclexception("incorrect secret-key length"); 708 | 709 | mlen = msize + crypto_box_ZEROBYTES; 710 | mpad = PyMem_Malloc(mlen); 711 | if (!mpad) return PyErr_NoMemory(); 712 | cpad = PyMem_Malloc(mlen); 713 | if (!cpad) { 714 | PyMem_Free(mpad); 715 | return PyErr_NoMemory(); 716 | } 717 | 718 | for (i = 0; i < crypto_box_ZEROBYTES; ++i) mpad[i] = 0; 719 | for (i = crypto_box_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_box_ZEROBYTES]; 720 | 721 | crypto_box(cpad, mpad, mlen, n, pk, sk); 722 | 723 | ret = PyBytes_FromStringAndSize( 724 | (char *)cpad + crypto_box_BOXZEROBYTES, 725 | mlen - crypto_box_BOXZEROBYTES 726 | ); 727 | 728 | PyMem_Free(mpad); 729 | PyMem_Free(cpad); 730 | return ret; 731 | } 732 | 733 | const char pycrypto_box__doc__[]= 734 | "crypto_box(m,n,pk,sk) -> c\n\n\ 735 | The crypto_box function encrypts and authenticates a message m\n\ 736 | using the sender's secret key sk, the receiver's public key pk,\n\ 737 | and a nonce n. The crypto_box function returns the resulting ciphertext c.\n\ 738 | The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES\n\ 739 | or if len(pk) is not crypto_box_PUBLICKEYBYTES\n\ 740 | or if len(n) is not crypto_box_NONCEBYTES.\n\ 741 | This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\ 742 | "; 743 | 744 | 745 | /* API: m = crypto_box_open(c,n,pk,sk); */ 746 | PyObject *pycrypto_box_open(PyObject *self, PyObject *args, PyObject *kw) { 747 | 748 | const unsigned char *c, *n, *pk, *sk; 749 | Py_ssize_t csize = 0, nsize = 0, pksize = 0, sksize = 0; 750 | static const char *kwlist[] = {"c", "n", "pk", "sk", 0}; 751 | PyObject *ret; 752 | long long i; 753 | unsigned long long clen; 754 | unsigned char *mpad; 755 | unsigned char *cpad; 756 | 757 | if (!PyArg_ParseTupleAndKeywords(args, kw, 758 | "|s#s#s#s#:crypto_box_open", 759 | (char **)kwlist, 760 | (char **)&c, &csize, 761 | (char **)&n, &nsize, 762 | (char **)&pk, &pksize, 763 | (char **)&sk, &sksize)) { 764 | return (PyObject *)0; 765 | } 766 | 767 | if (nsize != crypto_box_NONCEBYTES) return naclexception("incorrect nonce length"); 768 | if (pksize != crypto_box_PUBLICKEYBYTES) return naclexception("incorrect public-key length"); 769 | if (sksize != crypto_box_SECRETKEYBYTES) return naclexception("incorrect secret-key length"); 770 | 771 | clen = csize + crypto_box_BOXZEROBYTES; 772 | mpad = PyMem_Malloc(clen); 773 | if (!mpad) return PyErr_NoMemory(); 774 | cpad = PyMem_Malloc(clen); 775 | if (!cpad) { 776 | PyMem_Free(mpad); 777 | return PyErr_NoMemory(); 778 | } 779 | 780 | for (i = 0; i < crypto_box_BOXZEROBYTES; ++i) cpad[i] = 0; 781 | for (i = crypto_box_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES]; 782 | 783 | if (crypto_box_open(mpad, cpad, clen, n, pk, sk) != 0) { 784 | PyMem_Free(mpad); 785 | PyMem_Free(cpad); 786 | return naclexception("ciphertext fails verification"); 787 | } 788 | if (clen < crypto_box_ZEROBYTES) { 789 | PyMem_Free(mpad); 790 | PyMem_Free(cpad); 791 | return naclexception("ciphertext too short"); 792 | } 793 | ret = PyBytes_FromStringAndSize( 794 | (char *)mpad + crypto_box_ZEROBYTES, 795 | clen - crypto_box_ZEROBYTES 796 | ); 797 | PyMem_Free(mpad); 798 | PyMem_Free(cpad); 799 | return ret; 800 | 801 | } 802 | 803 | const char pycrypto_box_open__doc__[]= 804 | "crypto_box_open(c,n,pk,sk) -> m\n\n\ 805 | The crypto_box_open function verifies and decrypts\n\ 806 | a ciphertext c using the receiver's secret key sk,\n\ 807 | the sender's public key pk, and a nonce n.\n\ 808 | The crypto_box_open function returns the resulting plaintext m.\n\ 809 | The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES\n\ 810 | or if len(pk) is not crypto_box_PUBLICKEYBYTES\n\ 811 | or if len(n) is not crypto_box_NONCEBYTES.\n\ 812 | This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\ 813 | "; 814 | 815 | 816 | /* API: (pk,sk) = crypto_box_keypair(); */ 817 | PyObject *pycrypto_box_keypair(PyObject *self) { 818 | 819 | PyObject *pypk, *pysk, *ret; 820 | 821 | pypk = PyBytes_FromStringAndSize((char *)0, crypto_box_PUBLICKEYBYTES); 822 | if (!pypk) return (PyObject *)0; 823 | 824 | pysk = PyBytes_FromStringAndSize((char *)0, crypto_box_SECRETKEYBYTES); 825 | if (!pysk) { 826 | Py_DECREF(pypk); 827 | return (PyObject *)0; 828 | } 829 | ret = PyTuple_New(2); 830 | if (!ret) { 831 | Py_DECREF(pypk); 832 | Py_DECREF(pysk); 833 | return (PyObject *)0; 834 | } 835 | PyTuple_SET_ITEM(ret, 0, pypk); 836 | PyTuple_SET_ITEM(ret, 1, pysk); 837 | 838 | crypto_box_keypair( 839 | (unsigned char *)PyBytes_AS_STRING(pypk), 840 | (unsigned char *)PyBytes_AS_STRING(pysk) 841 | ); 842 | 843 | return ret; 844 | } 845 | 846 | const char pycrypto_box_keypair__doc__[]= 847 | "crypto_box_keypair() -> (pk,sk)\n\n\ 848 | The crypto_box_keypair function randomly generates a secret key and\n\ 849 | a corresponding public key. It returns tuple containing the secret key in sk and\n\ 850 | public key in pk.\n\ 851 | It guarantees that sk has crypto_box_SECRETKEYBYTES bytes\n\ 852 | and that pk has crypto_box_PUBLICKEYBYTES bytes.\n\ 853 | This uses Curve25519.\n\ 854 | "; 855 | 856 | 857 | /* API: s = crypto_box_beforenm(pk,sk); */ 858 | PyObject *pycrypto_box_beforenm(PyObject *self, PyObject *args, PyObject *kw) { 859 | 860 | const unsigned char *pk, *sk; 861 | Py_ssize_t pklen=0, sklen=0; 862 | static const char *kwlist[] = {"pk", "sk", 0}; 863 | PyObject *ret; 864 | 865 | if (!PyArg_ParseTupleAndKeywords(args, kw, 866 | "|s#s#:crypto_box_beforenm", 867 | (char **) kwlist, 868 | (char **)&pk, &pklen, 869 | (char **)&sk, &sklen)) { 870 | return (PyObject *)0; 871 | } 872 | 873 | 874 | if (pklen != crypto_box_PUBLICKEYBYTES) 875 | return naclexception("incorrect public-key length"); 876 | if (sklen != crypto_box_SECRETKEYBYTES) 877 | return naclexception("incorrect secret-key length"); 878 | 879 | ret = PyBytes_FromStringAndSize((char *)0, crypto_box_BEFORENMBYTES); 880 | if (!ret) return ret; 881 | crypto_box_beforenm((unsigned char *)PyBytes_AS_STRING(ret), pk, sk); 882 | return ret; 883 | } 884 | 885 | const char pycrypto_box_beforenm__doc__[]= 886 | "crypto_box_beforenm(pk,sk) -> s\n\n\ 887 | Function crypto_box_beforenm computes a shared secret s from \n\ 888 | public key pk and secret key sk\n\ 889 | The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES.\n\ 890 | It also raises an exception if len(pk) is not crypto_box_PUBLICKEYBYTES.\n\ 891 | This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\ 892 | "; 893 | 894 | 895 | /* API: c = crypto_box_afternm(m,n,k); */ 896 | PyObject *pycrypto_box_afternm(PyObject *self, PyObject *args, PyObject *kw) { 897 | 898 | const unsigned char *m, *n, *k; 899 | Py_ssize_t msize = 0, nsize = 0, ksize = 0; 900 | static const char *kwlist[] = {"m", "n", "k", 0}; 901 | PyObject *ret; 902 | long long i; 903 | unsigned long long mlen; 904 | unsigned char *mpad; 905 | unsigned char *cpad; 906 | 907 | if (!PyArg_ParseTupleAndKeywords(args, kw, 908 | "|s#s#s#:crypto_box_afternm", 909 | (char **)kwlist, 910 | (char **)&m, &msize, 911 | (char **)&n, &nsize, 912 | (char **)&k, &ksize)) { 913 | return (PyObject *)0; 914 | } 915 | 916 | if (nsize != crypto_box_NONCEBYTES) return naclexception("incorrect nonce length"); 917 | if (ksize != crypto_box_BEFORENMBYTES) return naclexception("incorrect key length"); 918 | 919 | mlen = msize + crypto_box_ZEROBYTES; 920 | mpad = PyMem_Malloc(mlen); 921 | if (!mpad) return PyErr_NoMemory(); 922 | cpad = PyMem_Malloc(mlen); 923 | if (!cpad) { 924 | PyMem_Free(mpad); 925 | return PyErr_NoMemory(); 926 | } 927 | 928 | for (i = 0; i < crypto_box_ZEROBYTES; ++i) mpad[i] = 0; 929 | for (i = crypto_box_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_box_ZEROBYTES]; 930 | 931 | crypto_box_afternm(cpad, mpad, mlen, n, k); 932 | 933 | ret = PyBytes_FromStringAndSize( 934 | (char *)cpad + crypto_box_BOXZEROBYTES, 935 | mlen - crypto_box_BOXZEROBYTES 936 | ); 937 | 938 | PyMem_Free(mpad); 939 | PyMem_Free(cpad); 940 | return ret; 941 | } 942 | 943 | const char pycrypto_box_afternm__doc__[]= 944 | "crypto_box_afternm(m,n,k) -> c\n\n\ 945 | The crypto_box_afternm function encrypts and authenticates\n\ 946 | a message m using a secret key k and a nonce n. \n\ 947 | The crypto_box_afternm function returns the resulting ciphertext c. \n\ 948 | The function raises an exception if len(k) is not crypto_box_BEFORENMBYTES.\n\ 949 | The function also raises an exception if len(n) is not crypto_box_NONCEBYTES.\n\ 950 | This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\ 951 | "; 952 | 953 | 954 | /* API: m = crypto_box_open_afternm(c,n,k); */ 955 | PyObject *pycrypto_box_open_afternm(PyObject *self, PyObject *args, PyObject *kw) { 956 | 957 | const unsigned char *c, *n, *k; 958 | Py_ssize_t csize = 0, nsize = 0, ksize = 0; 959 | static const char *kwlist[] = {"c", "n", "k", 0}; 960 | PyObject *ret; 961 | long long i; 962 | unsigned long long clen; 963 | unsigned char *mpad; 964 | unsigned char *cpad; 965 | 966 | if (!PyArg_ParseTupleAndKeywords(args, kw, 967 | "|s#s#s#:crypto_box_open_afternm", 968 | (char **)kwlist, 969 | (char **)&c, &csize, 970 | (char **)&n, &nsize, 971 | (char **)&k, &ksize)) { 972 | return (PyObject *)0; 973 | } 974 | 975 | if (nsize != crypto_box_NONCEBYTES) return naclexception("incorrect nonce length"); 976 | if (ksize != crypto_box_BEFORENMBYTES) return naclexception("incorrect key length"); 977 | 978 | clen = csize + crypto_box_BOXZEROBYTES; 979 | mpad = PyMem_Malloc(clen); 980 | if (!mpad) return PyErr_NoMemory(); 981 | cpad = PyMem_Malloc(clen); 982 | if (!cpad) { 983 | PyMem_Free(mpad); 984 | return PyErr_NoMemory(); 985 | } 986 | 987 | for (i = 0; i < crypto_box_BOXZEROBYTES; ++i) cpad[i] = 0; 988 | for (i = crypto_box_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES]; 989 | 990 | if (crypto_box_open_afternm(mpad, cpad, clen, n, k) != 0) { 991 | PyMem_Free(mpad); 992 | PyMem_Free(cpad); 993 | return naclexception("ciphertext fails verification"); 994 | } 995 | if (clen < crypto_box_ZEROBYTES) { 996 | PyMem_Free(mpad); 997 | PyMem_Free(cpad); 998 | return naclexception("ciphertext too short"); 999 | } 1000 | 1001 | ret = PyBytes_FromStringAndSize( 1002 | (char *)mpad + crypto_box_ZEROBYTES, 1003 | clen - crypto_box_ZEROBYTES 1004 | ); 1005 | 1006 | PyMem_Free(mpad); 1007 | PyMem_Free(cpad); 1008 | return ret; 1009 | } 1010 | 1011 | const char pycrypto_box_open_afternm__doc__[]= 1012 | "crypto_box_open_afternm(c,n,k) -> m\n\n\ 1013 | The crypto_box_open_afternm function verifies and decrypts \n\ 1014 | a ciphertext c using a secret key k and a nonce n.\n\ 1015 | The crypto_box_open_afternm function returns the resulting plaintext m.\n\ 1016 | If the ciphertext fails verification, crypto_box_open_afternm raises an exception.\n\ 1017 | The function also raises an exception if len(k) is not crypto_box_BEFORENMBYTES,\n\ 1018 | or if len(n) is not crypto_box_NONCEBYTES.\n\ 1019 | This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\ 1020 | "; 1021 | 1022 | static PyMethodDef nacl_methods[] = { 1023 | {"crypto_onetimeauth", (PyCFunction)pycrypto_onetimeauth, METH_VARARGS | METH_KEYWORDS, pycrypto_onetimeauth__doc__}, 1024 | {"crypto_onetimeauth_verify", (PyCFunction)pycrypto_onetimeauth_verify, METH_VARARGS | METH_KEYWORDS, pycrypto_onetimeauth_verify__doc__}, 1025 | {"crypto_hash", (PyCFunction)pycrypto_hash, METH_VARARGS | METH_KEYWORDS, pycrypto_hash__doc__}, 1026 | {"crypto_verify_16", (PyCFunction)pycrypto_verify_16, METH_VARARGS | METH_KEYWORDS, pycrypto_verify_16__doc__}, 1027 | {"crypto_verify_32", (PyCFunction)pycrypto_verify_32, METH_VARARGS | METH_KEYWORDS, pycrypto_verify_32__doc__}, 1028 | {"crypto_scalarmult", (PyCFunction)pycrypto_scalarmult, METH_VARARGS | METH_KEYWORDS, pycrypto_scalarmult__doc__}, 1029 | {"crypto_scalarmult_base", (PyCFunction)pycrypto_scalarmult_base, METH_VARARGS | METH_KEYWORDS, pycrypto_scalarmult_base__doc__}, 1030 | {"crypto_stream", (PyCFunction)pycrypto_stream, METH_VARARGS | METH_KEYWORDS, pycrypto_stream__doc__}, 1031 | {"crypto_stream_xor", (PyCFunction)pycrypto_stream_xor, METH_VARARGS | METH_KEYWORDS, pycrypto_stream_xor__doc__}, 1032 | {"crypto_sign", (PyCFunction)pycrypto_sign, METH_VARARGS | METH_KEYWORDS, pycrypto_sign__doc__}, 1033 | {"crypto_sign_open", (PyCFunction)pycrypto_sign_open, METH_VARARGS | METH_KEYWORDS, pycrypto_sign_open__doc__}, 1034 | {"crypto_sign_keypair", (PyCFunction)pycrypto_sign_keypair, METH_VARARGS | METH_KEYWORDS, pycrypto_sign_keypair__doc__}, 1035 | {"crypto_secretbox", (PyCFunction)pycrypto_secretbox, METH_VARARGS | METH_KEYWORDS, pycrypto_secretbox__doc__}, 1036 | {"crypto_secretbox_open", (PyCFunction)pycrypto_secretbox_open, METH_VARARGS | METH_KEYWORDS, pycrypto_secretbox_open__doc__}, 1037 | {"crypto_box", (PyCFunction)pycrypto_box, METH_VARARGS | METH_KEYWORDS, pycrypto_box__doc__}, 1038 | {"crypto_box_open", (PyCFunction)pycrypto_box_open, METH_VARARGS | METH_KEYWORDS, pycrypto_box_open__doc__}, 1039 | {"crypto_box_keypair", (PyCFunction)pycrypto_box_keypair, METH_VARARGS | METH_KEYWORDS, pycrypto_box_keypair__doc__}, 1040 | {"crypto_box_beforenm", (PyCFunction)pycrypto_box_beforenm, METH_VARARGS | METH_KEYWORDS, pycrypto_box_beforenm__doc__}, 1041 | {"crypto_box_afternm", (PyCFunction)pycrypto_box_afternm, METH_VARARGS | METH_KEYWORDS, pycrypto_box_afternm__doc__}, 1042 | {"crypto_box_open_afternm", (PyCFunction)pycrypto_box_open_afternm, METH_VARARGS | METH_KEYWORDS, pycrypto_box_open_afternm__doc__}, 1043 | {(void *)0, (void *)0} 1044 | }; 1045 | 1046 | void add_constants(PyObject *m) { 1047 | PyModule_AddStringConstant(m, "crypto_onetimeauth_PRIMITIVE", crypto_onetimeauth_PRIMITIVE); 1048 | PyModule_AddStringConstant(m, "crypto_onetimeauth_IMPLEMENTATION", crypto_onetimeauth_IMPLEMENTATION); 1049 | PyModule_AddStringConstant(m, "crypto_onetimeauth_VERSION", crypto_onetimeauth_VERSION); 1050 | PyModule_AddIntConstant(m, "crypto_onetimeauth_BYTES", crypto_onetimeauth_BYTES); 1051 | PyModule_AddIntConstant(m, "crypto_onetimeauth_KEYBYTES", crypto_onetimeauth_KEYBYTES); 1052 | PyModule_AddStringConstant(m, "crypto_hash_PRIMITIVE", crypto_hash_PRIMITIVE); 1053 | PyModule_AddStringConstant(m, "crypto_hash_IMPLEMENTATION", crypto_hash_IMPLEMENTATION); 1054 | PyModule_AddStringConstant(m, "crypto_hash_VERSION", crypto_hash_VERSION); 1055 | PyModule_AddIntConstant(m, "crypto_hash_BYTES", crypto_hash_BYTES); 1056 | PyModule_AddIntConstant(m, "crypto_verify_16_BYTES", crypto_verify_16_BYTES); 1057 | PyModule_AddStringConstant(m, "crypto_verify_16_IMPLEMENTATION", crypto_verify_16_IMPLEMENTATION); 1058 | PyModule_AddStringConstant(m, "crypto_verify_16_VERSION", crypto_verify_16_VERSION); 1059 | PyModule_AddIntConstant(m, "crypto_verify_32_BYTES", crypto_verify_32_BYTES); 1060 | PyModule_AddStringConstant(m, "crypto_verify_32_IMPLEMENTATION", crypto_verify_32_IMPLEMENTATION); 1061 | PyModule_AddStringConstant(m, "crypto_verify_32_VERSION", crypto_verify_32_VERSION); 1062 | PyModule_AddStringConstant(m, "crypto_scalarmult_PRIMITIVE", crypto_scalarmult_PRIMITIVE); 1063 | PyModule_AddStringConstant(m, "crypto_scalarmult_IMPLEMENTATION", crypto_scalarmult_IMPLEMENTATION); 1064 | PyModule_AddStringConstant(m, "crypto_scalarmult_VERSION", crypto_scalarmult_VERSION); 1065 | PyModule_AddIntConstant(m, "crypto_scalarmult_BYTES", crypto_scalarmult_BYTES); 1066 | PyModule_AddIntConstant(m, "crypto_scalarmult_SCALARBYTES", crypto_scalarmult_SCALARBYTES); 1067 | PyModule_AddStringConstant(m, "crypto_stream_PRIMITIVE", crypto_stream_PRIMITIVE); 1068 | PyModule_AddStringConstant(m, "crypto_stream_IMPLEMENTATION", crypto_stream_IMPLEMENTATION); 1069 | PyModule_AddStringConstant(m, "crypto_stream_VERSION", crypto_stream_VERSION); 1070 | PyModule_AddIntConstant(m, "crypto_stream_KEYBYTES", crypto_stream_KEYBYTES); 1071 | PyModule_AddIntConstant(m, "crypto_stream_NONCEBYTES", crypto_stream_NONCEBYTES); 1072 | PyModule_AddStringConstant(m, "crypto_sign_PRIMITIVE", crypto_sign_PRIMITIVE); 1073 | PyModule_AddStringConstant(m, "crypto_sign_IMPLEMENTATION", crypto_sign_IMPLEMENTATION); 1074 | PyModule_AddStringConstant(m, "crypto_sign_VERSION", crypto_sign_VERSION); 1075 | PyModule_AddIntConstant(m, "crypto_sign_BYTES", crypto_sign_BYTES); 1076 | PyModule_AddIntConstant(m, "crypto_sign_PUBLICKEYBYTES", crypto_sign_PUBLICKEYBYTES); 1077 | PyModule_AddIntConstant(m, "crypto_sign_SECRETKEYBYTES", crypto_sign_SECRETKEYBYTES); 1078 | PyModule_AddStringConstant(m, "crypto_secretbox_PRIMITIVE", crypto_secretbox_PRIMITIVE); 1079 | PyModule_AddStringConstant(m, "crypto_secretbox_IMPLEMENTATION", crypto_secretbox_IMPLEMENTATION); 1080 | PyModule_AddStringConstant(m, "crypto_secretbox_VERSION", crypto_secretbox_VERSION); 1081 | PyModule_AddIntConstant(m, "crypto_secretbox_KEYBYTES", crypto_secretbox_KEYBYTES); 1082 | PyModule_AddIntConstant(m, "crypto_secretbox_NONCEBYTES", crypto_secretbox_NONCEBYTES); 1083 | PyModule_AddIntConstant(m, "crypto_secretbox_ZEROBYTES", crypto_secretbox_ZEROBYTES); 1084 | PyModule_AddIntConstant(m, "crypto_secretbox_BOXZEROBYTES", crypto_secretbox_BOXZEROBYTES); 1085 | PyModule_AddStringConstant(m, "crypto_box_PRIMITIVE", crypto_box_PRIMITIVE); 1086 | PyModule_AddStringConstant(m, "crypto_box_IMPLEMENTATION", crypto_box_IMPLEMENTATION); 1087 | PyModule_AddStringConstant(m, "crypto_box_VERSION", crypto_box_VERSION); 1088 | PyModule_AddIntConstant(m, "crypto_box_PUBLICKEYBYTES", crypto_box_PUBLICKEYBYTES); 1089 | PyModule_AddIntConstant(m, "crypto_box_SECRETKEYBYTES", crypto_box_SECRETKEYBYTES); 1090 | PyModule_AddIntConstant(m, "crypto_box_BEFORENMBYTES", crypto_box_BEFORENMBYTES); 1091 | PyModule_AddIntConstant(m, "crypto_box_NONCEBYTES", crypto_box_NONCEBYTES); 1092 | PyModule_AddIntConstant(m, "crypto_box_ZEROBYTES", crypto_box_ZEROBYTES); 1093 | PyModule_AddIntConstant(m, "crypto_box_BOXZEROBYTES", crypto_box_BOXZEROBYTES); 1094 | return; 1095 | } 1096 | 1097 | #if PY_MAJOR_VERSION >= 3 1098 | struct PyModuleDef nacl_def = { 1099 | PyModuleDef_HEAD_INIT, 1100 | "_tweetnacl", 1101 | NULL, 1102 | -1, 1103 | nacl_methods, 1104 | NULL, NULL, NULL, NULL 1105 | }; 1106 | #endif 1107 | 1108 | #if PY_MAJOR_VERSION >= 3 1109 | PyMODINIT_FUNC PyInit__tweetnacl(void) { 1110 | #else 1111 | PyMODINIT_FUNC init_tweetnacl(void) { 1112 | #endif 1113 | PyObject *m; 1114 | unsigned char dummy[1]; 1115 | #if PY_MAJOR_VERSION >= 3 1116 | m = PyModule_Create( &nacl_def ); 1117 | if (!m) return m; 1118 | #else 1119 | m = Py_InitModule("_tweetnacl", nacl_methods); 1120 | if (!m) return; 1121 | #endif 1122 | add_constants(m); 1123 | #if PY_MAJOR_VERSION >= 3 1124 | return m; 1125 | #endif 1126 | } 1127 | 1128 | -------------------------------------------------------------------------------- /UDP/CryptoRC4.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from Crypto.Cipher import ARC4 4 | 5 | 6 | class Crypto: 7 | 8 | def __init__(self, key, nonce): 9 | self.key = key + nonce 10 | self.stream = ARC4.new(self.key) 11 | self.stream.encrypt(self.key) 12 | 13 | def decrypt(self, cipher): 14 | return self.stream.decrypt(cipher) 15 | -------------------------------------------------------------------------------- /UDP/packetEnum.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | udp_packet_enum = { 5 | # Client Packet 6 | 15620: 'KeepAlive', 7 | 17187: 'SectorCommand', 8 | 17104: 'EndClientTurnMessage', 9 | 10 | # Server Packet 11 | 26301: 'SectorHearbeat' 12 | } 13 | -------------------------------------------------------------------------------- /UDP/packetProcessor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from queue import Queue 4 | from threading import Thread 5 | from TCP.Packet.reader import Reader 6 | from UDP.packetEnum import udp_packet_enum 7 | 8 | 9 | class packetProcessor(Thread): 10 | 11 | def __init__(self, connection_dict, replay): 12 | self.queue = Queue() 13 | self.replay = replay 14 | self.is_running = True 15 | self.reader = Reader(b'') 16 | self.connection_dict = connection_dict 17 | Thread.__init__(self) 18 | 19 | def run(self): 20 | while self.is_running: 21 | host, packet = self.queue.get() 22 | 23 | if packet is not None: 24 | if len(packet) != 1400: 25 | self.reader.reinit(packet) 26 | packet_list = [] 27 | 28 | session_id = self.reader.read(10) 29 | host_dict = self.connection_dict[session_id][host] 30 | 31 | if self.reader.has_remaining_bytes: 32 | acks_count = self.reader.read_vint() 33 | 34 | for i in range(acks_count): 35 | self.reader.read_byte() 36 | 37 | if self.reader.has_remaining_bytes: 38 | chunks_count = self.reader.read_vint() 39 | 40 | for i in range(chunks_count): 41 | sequence_id = self.reader.read_byte() 42 | packet_id = self.reader.read_vint() 43 | packet_length = self.reader.read_vint() 44 | 45 | packet_list.append({ 46 | 'id': packet_id, 47 | 'packet_length': packet_length, 48 | 'sequence_id': sequence_id, 49 | 'payload': self.reader.read(packet_length) 50 | }) 51 | 52 | for packet in reversed(packet_list): 53 | if packet['sequence_id'] == host_dict['next_sequence_id']: 54 | packet_name = udp_packet_enum.get(packet['id'], packet['id']) 55 | print('[*] Received UDP chunk {} from {}, chunk length: {}'.format( 56 | packet_name, 57 | host, 58 | packet['packet_length'])) 59 | 60 | host_dict['next_sequence_id'] = (host_dict['next_sequence_id'] + 1) & 0xff 61 | decrypted = host_dict['crypto'].decrypt(packet['payload']) 62 | 63 | self.replay.save_udp_packet(session_id, packet_name, decrypted) 64 | 65 | self.queue.task_done() 66 | 67 | def stop(self): 68 | # Put a None packet in queue so it loop if queue is empty 69 | # then self.is_running is checked and while loop will be stoped 70 | self.queue.put([None, None]) 71 | self.is_running = False 72 | 73 | if self.connection_dict: 74 | self.replay.increment_index(self.replay.udp_session_index_path, self.replay.get_index(self.replay.udp_session_index_path)) 75 | -------------------------------------------------------------------------------- /UDP/protocol.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from UDP.CryptoRC4 import Crypto 4 | from TCP.Packet.reader import Reader 5 | from TCP.Packet.writer import Writer 6 | from UDP.packetProcessor import packetProcessor 7 | from twisted.internet.protocol import DatagramProtocol 8 | 9 | 10 | class UDPProtocol(DatagramProtocol): 11 | 12 | def __init__(self, listen_host, listen_port, replay): 13 | self.connection_dict = {} 14 | self.listen_host = listen_host 15 | self.listen_port = listen_port 16 | self.packetProcessor = packetProcessor(self.connection_dict, replay) 17 | 18 | self.packetProcessor.start() 19 | 20 | def build_udp_info_packet(self, client_host, data): 21 | udp_info_reader = Reader(data) 22 | udp_info_writer = Writer() 23 | 24 | server_port = udp_info_reader.read_vint() 25 | server_host = udp_info_reader.read_string() 26 | session_key = udp_info_reader.read_bytearray() 27 | nonce = udp_info_reader.read_string() 28 | 29 | print('[*] Received Udp Info Message with host: {}, port: {} !'.format(server_host, server_port)) 30 | 31 | self.connection_dict[session_key] = {} 32 | session = self.connection_dict[session_key] 33 | 34 | session['nonce'] = nonce 35 | session['client_port_setted'] = False 36 | 37 | print('Nonce: {}'.format(nonce.encode('utf-8').hex())) 38 | 39 | session[server_host] = { 40 | 'host': [client_host, None], 41 | 'next_sequence_id': 1, 42 | 'crypto': Crypto(b'fhsd6f86f67rt8fw78fw789we78r9789wer6re', nonce.encode('utf-8')) 43 | } 44 | 45 | session[client_host] = { 46 | 'host': [server_host, server_port], 47 | 'next_sequence_id': 1, 48 | 'crypto': Crypto(b'fhsd6f86f67rt8fw78fw789we78r9789wer6re', nonce.encode('utf-8')) 49 | } 50 | 51 | udp_info_writer.write_vint(self.listen_port) 52 | udp_info_writer.write_string(self.listen_host) 53 | udp_info_writer.write_bytearray(session_key) 54 | udp_info_writer.write_string(nonce) 55 | 56 | return udp_info_writer.getvalue() 57 | 58 | def datagramReceived(self, data, addr): 59 | self.packetProcessor.queue.put([addr[0], data]) 60 | 61 | session_key = data[:10] 62 | session = self.connection_dict[session_key] 63 | 64 | if not session['client_port_setted']: 65 | session['client_port_setted'] = True 66 | session[session[addr[0]]['host'][0]]['host'][1] = addr[1] 67 | 68 | self.transport.write(data, tuple(session[addr[0]]['host'])) 69 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Port": 9339, 3 | "UDPPort": 9339, 4 | "UDPHost": "127.0.0.1", 5 | "Hostname": "game.clashroyaleapp.com", 6 | "ServerKey": "4dd5e7bf4202cf5f032e4c4890ff52f9ab94ab7ca40dc963dde5e96803cf067c", 7 | "ReplayDirectory": "Replay" 8 | } -------------------------------------------------------------------------------- /hexdump.py: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/ImmortalPC/c340564823f283fe530b 2 | 3 | def hexdump( src, length=16, sep='.' ): 4 | ''' 5 | @brief Return {src} in hex dump. 6 | @param[in] length {Int} Nb Bytes by row. 7 | @param[in] sep {Char} For the text part, {sep} will be used for non ASCII char. 8 | @return {Str} The hexdump 9 | @note Full support for python2 and python3 ! 10 | ''' 11 | result = []; 12 | 13 | # Python3 support 14 | try: 15 | xrange(0,1); 16 | except NameError: 17 | xrange = range; 18 | 19 | for i in xrange(0, len(src), length): 20 | subSrc = src[i:i+length]; 21 | hexa = ''; 22 | isMiddle = False; 23 | for h in xrange(0,len(subSrc)): 24 | if h == length/2: 25 | hexa += ' '; 26 | h = subSrc[h]; 27 | if not isinstance(h, int): 28 | h = ord(h); 29 | h = hex(h).replace('0x',''); 30 | if len(h) == 1: 31 | h = '0'+h; 32 | hexa += h+' '; 33 | hexa = hexa.strip(' '); 34 | text = ''; 35 | for c in subSrc: 36 | if not isinstance(c, int): 37 | c = ord(c); 38 | if 0x20 <= c < 0x7F: 39 | text += chr(c); 40 | else: 41 | text += sep; 42 | result.append(('%08X: %-'+str(length*(2+1)+1)+'s |%s|') % (i, hexa, text)); 43 | 44 | return '\n'.join(result); -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | frida 2 | twisted 3 | pycryptodome -------------------------------------------------------------------------------- /urandom_hook.js: -------------------------------------------------------------------------------- 1 | var readPtr = Module.findExportByName('libc.so', 'read'); 2 | 3 | var read = new NativeFunction(readPtr, 'int', ['int', 'pointer', 'int']); 4 | 5 | 6 | Interceptor.replace(readPtr, 7 | new NativeCallback(function(fd, buf, count) { 8 | // Since the only time the game read 32 bytes on a file 9 | // is when he generate sk from /dev/urandom we don't have to deal with 10 | // file descriptor to be sure 32 bytes are read on /dev/urandom 11 | 12 | if (count == 32) { 13 | // 32 times 0x00 seems to trigger the game and make it crash 14 | // so let's use a random value 15 | 16 | Memory.writeByteArray(buf, [0x85, 0x98, 0x0a, 0xb6, 0x07, 0x5c, 0xc1, 0x97, 17 | 0xab, 0x8d, 0xe0, 0xfa, 0xba, 0x3c, 0x69, 0x96, 18 | 0x82, 0xb4, 0x59, 0x97, 0x93, 0x65, 0x43, 0x51, 19 | 0x44, 0x48, 0x2f, 0x5e, 0xba, 0xe8, 0x21, 0x45]) 20 | 21 | return 32 22 | } 23 | else { 24 | return read(fd, buf, count) 25 | } 26 | }, 'int', ['int', 'pointer', 'int']) 27 | ) 28 | --------------------------------------------------------------------------------