/*
* 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;
}