/* * Slitheen - a decoy routing system for censorship resistance * Copyright (C) 2017 Cecylia Bocovich (cbocovic@uwaterloo.ca) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with the OpenSSL library (or a modified version of that library), * containing parts covered by the terms of the OpenSSL Licence and the * SSLeay license, the licensors of this Program grant you additional * permission to convey the resulting work. Corresponding Source for a * non-source form of such a combination shall include the source code * for the parts of the OpenSSL library used as well as that of the covered * work. */ #include #include #include #include #include #include #include #include #include #include "ptwist.h" #include "tagging.h" //look for key list byte maingen[PTWIST_BYTES]; byte twistgen[PTWIST_BYTES]; byte mainpub[PTWIST_BYTES]; byte twistpub[PTWIST_BYTES]; static void gen_tag(byte *tag, byte stored_key[16], const byte *context, size_t context_len) { byte seckey[PTWIST_BYTES]; byte sharedsec[PTWIST_BYTES+context_len]; byte usetwist; byte taghashout[32]; #if PTWIST_PUZZLE_STRENGTH > 0 size_t puzzle_len = 16+PTWIST_RESP_BYTES; byte value_to_hash[puzzle_len]; byte hashout[32]; bn_t Rbn, Hbn; int i, len, sign; #endif memset(tag, 0xAA, PTWIST_TAG_BYTES); /* Use the main or the twist curve? */ RAND_bytes(&usetwist, 1); usetwist &= 1; /* Create seckey*G and seckey*Y */ RAND_bytes(seckey, PTWIST_BYTES); ptwist_pointmul(tag, usetwist ? twistgen : maingen, seckey); ptwist_pointmul(sharedsec, usetwist ? twistpub : mainpub, seckey); /* Create the tag hash keys */ memmove(sharedsec+PTWIST_BYTES, context, context_len); SHA256(sharedsec, PTWIST_BYTES + context_len, taghashout); #if PTWIST_PUZZLE_STRENGTH > 0 /* The puzzle is to find a response R such that SHA256(K || R) starts with PTWIST_PUZZLE_STRENGTH bits of 0s. K is the first 128 bits of the above hash tag keys. */ /* Construct our response to the puzzle. Start looking for R in a * random place. */ memmove(value_to_hash, taghashout, 16); RAND_bytes(value_to_hash+16, PTWIST_RESP_BYTES); value_to_hash[16+PTWIST_RESP_BYTES-1] &= PTWIST_RESP_MASK; while(1) { unsigned int firstbits; md_map_sh256(hashout, value_to_hash, puzzle_len); #if PTWIST_PUZZLE_STRENGTH < 32 /* This assumes that you're on an architecture that doesn't care * about alignment, and is little endian. */ firstbits = *(unsigned int*)hashout; if ((firstbits & PTWIST_PUZZLE_MASK) == 0) { break; } /* Increment R and try again. */ for(i=0;i 128" #endif memmove(stored_key, taghashout+16, 16); } int generate_slitheen_id(byte *slitheen_id, byte stored_key[16]) { FILE *fp; int res; byte *tag; /* Create the generators */ memset(maingen, 0, PTWIST_BYTES); maingen[0] = 2; memset(twistgen, 0, PTWIST_BYTES); /* Read the public keys */ fp = fopen("pubkey", "rb"); if (fp == NULL) { perror("fopen"); exit(1); } res = fread(mainpub, PTWIST_BYTES, 1, fp); if (res < 1) { perror("fread"); exit(1); } res = fread(twistpub, PTWIST_BYTES, 1, fp); if (res < 1) { perror("fread"); exit(1); } fclose(fp); tag = slitheen_id; gen_tag(tag, stored_key, (const byte *)"context", 7); return 0; }