#include #include #include #include #include "ptwist.h" byte maingen[PTWIST_BYTES]; byte twistgen[PTWIST_BYTES]; byte mainpub[PTWIST_BYTES]; byte twistpub[PTWIST_BYTES]; static void gen_tag(byte tag[PTWIST_TAG_BYTES], byte 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, 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(key, taghashout+16, 16); } int main(int argc, char **argv) { FILE *fp; int res; int i; byte tag[PTWIST_TAG_BYTES]; int numtags = argc > 1 ? atoi(argv[1]) : 10; /* 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); fp = fopen("tags", "wb"); if (fp == NULL) { perror("fopen"); exit(1); } for(i=0;i