tagging.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Slitheen - a decoy routing system for censorship resistance
  3. * Copyright (C) 2017 Cecylia Bocovich (cbocovic@uwaterloo.ca)
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, version 3.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * Additional permission under GNU GPL version 3 section 7
  18. *
  19. * If you modify this Program, or any covered work, by linking or combining
  20. * it with the OpenSSL library (or a modified version of that library),
  21. * containing parts covered by the terms of [name of library's license],
  22. * the licensors of this Program grant you additional permission to convey
  23. * the resulting work. {Corresponding Source for a non-source form of such
  24. * a combination shall include the source code for the parts of the OpenSSL
  25. * library used as well as that of the covered work.}
  26. */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdint.h>
  30. #include <openssl/rand.h>
  31. #include <openssl/sha.h>
  32. #include <openssl/ssl.h>
  33. #include <openssl/err.h>
  34. #include <openssl/ec.h>
  35. #include <openssl/bn.h>
  36. #include "ptwist.h"
  37. #include "tagging.h"
  38. //look for key list
  39. byte maingen[PTWIST_BYTES];
  40. byte twistgen[PTWIST_BYTES];
  41. byte mainpub[PTWIST_BYTES];
  42. byte twistpub[PTWIST_BYTES];
  43. static void gen_tag(byte *tag, byte stored_key[16],
  44. const byte *context, size_t context_len)
  45. {
  46. byte seckey[PTWIST_BYTES];
  47. byte sharedsec[PTWIST_BYTES+context_len];
  48. byte usetwist;
  49. byte taghashout[32];
  50. #if PTWIST_PUZZLE_STRENGTH > 0
  51. size_t puzzle_len = 16+PTWIST_RESP_BYTES;
  52. byte value_to_hash[puzzle_len];
  53. byte hashout[32];
  54. bn_t Rbn, Hbn;
  55. int i, len, sign;
  56. #endif
  57. memset(tag, 0xAA, PTWIST_TAG_BYTES);
  58. /* Use the main or the twist curve? */
  59. RAND_bytes(&usetwist, 1);
  60. usetwist &= 1;
  61. /* Create seckey*G and seckey*Y */
  62. RAND_bytes(seckey, PTWIST_BYTES);
  63. ptwist_pointmul(tag, usetwist ? twistgen : maingen, seckey);
  64. ptwist_pointmul(sharedsec, usetwist ? twistpub : mainpub, seckey);
  65. /* Create the tag hash keys */
  66. memmove(sharedsec+PTWIST_BYTES, context, context_len);
  67. SHA256(sharedsec, PTWIST_BYTES, taghashout);
  68. #if PTWIST_PUZZLE_STRENGTH > 0
  69. /* The puzzle is to find a response R such that SHA256(K || R)
  70. starts with PTWIST_PUZZLE_STRENGTH bits of 0s. K is the first
  71. 128 bits of the above hash tag keys. */
  72. /* Construct our response to the puzzle. Start looking for R in a
  73. * random place. */
  74. memmove(value_to_hash, taghashout, 16);
  75. RAND_bytes(value_to_hash+16, PTWIST_RESP_BYTES);
  76. value_to_hash[16+PTWIST_RESP_BYTES-1] &= PTWIST_RESP_MASK;
  77. while(1) {
  78. unsigned int firstbits;
  79. md_map_sh256(hashout, value_to_hash, puzzle_len);
  80. #if PTWIST_PUZZLE_STRENGTH < 32
  81. /* This assumes that you're on an architecture that doesn't care
  82. * about alignment, and is little endian. */
  83. firstbits = *(unsigned int*)hashout;
  84. if ((firstbits & PTWIST_PUZZLE_MASK) == 0) {
  85. break;
  86. }
  87. /* Increment R and try again. */
  88. for(i=0;i<PTWIST_RESP_BYTES;++i) {
  89. if (++value_to_hash[16+i]) break;
  90. }
  91. value_to_hash[16+PTWIST_RESP_BYTES-1] &= PTWIST_RESP_MASK;
  92. #else
  93. #error "Code assumes PTWIST_PUZZLE_STRENGTH < 32"
  94. #endif
  95. }
  96. /* When we get here, we have solved the puzzle. R is in
  97. * value_to_hash[16..16+PTWIST_RESP_BYTES-1], the hash output
  98. * hashout starts with PTWIST_PUZZLE_STRENGTH bits of 0s, and we'll
  99. * want to copy out H (the next PTWIST_HASH_SHOWBITS bits of the
  100. * hash output). The final tag is [seckey*G]_x || R || H . */
  101. bn_new(Rbn);
  102. bn_new(Hbn);
  103. bn_read_bin(Rbn, value_to_hash+16, PTWIST_RESP_BYTES, BN_POS);
  104. hashout[PTWIST_HASH_TOTBYTES-1] &= PTWIST_HASH_MASK;
  105. bn_read_bin(Hbn, hashout, PTWIST_HASH_TOTBYTES, BN_POS);
  106. bn_lsh(Hbn, Hbn, PTWIST_RESP_BITS-PTWIST_PUZZLE_STRENGTH);
  107. bn_add(Hbn, Hbn, Rbn);
  108. len = PTWIST_TAG_BYTES-PTWIST_BYTES;
  109. bn_write_bin(tag+PTWIST_BYTES, &len, &sign, Hbn);
  110. bn_free(Rbn);
  111. bn_free(Hbn);
  112. #elif PTWIST_HASH_SHOWBITS <= 128
  113. /* We're not using a client puzzle, so the tag is [seckey*G]_x || H
  114. * where H is the first PTWIST_HASH_SHOWBITS bits of the above hash
  115. * output. The key generated is the last 128 bits of that output.
  116. * If there's no client puzzle, PTWIST_HASH_SHOWBITS must be a multiple
  117. * of 8. */
  118. memmove(tag+PTWIST_BYTES, taghashout, PTWIST_HASH_SHOWBITS/8);
  119. #else
  120. #error "No client puzzle used, but PWTIST_HASH_SHOWBITS > 128"
  121. #endif
  122. memmove(stored_key, taghashout+16, 16);
  123. }
  124. int generate_slitheen_id(byte *slitheen_id, byte stored_key[16])
  125. {
  126. FILE *fp;
  127. int res;
  128. byte *tag;
  129. /* Create the generators */
  130. memset(maingen, 0, PTWIST_BYTES);
  131. maingen[0] = 2;
  132. memset(twistgen, 0, PTWIST_BYTES);
  133. /* Read the public keys */
  134. fp = fopen("pubkey", "rb");
  135. if (fp == NULL) {
  136. perror("fopen");
  137. exit(1);
  138. }
  139. res = fread(mainpub, PTWIST_BYTES, 1, fp);
  140. if (res < 1) {
  141. perror("fread");
  142. exit(1);
  143. }
  144. res = fread(twistpub, PTWIST_BYTES, 1, fp);
  145. if (res < 1) {
  146. perror("fread");
  147. exit(1);
  148. }
  149. fclose(fp);
  150. tag = slitheen_id;
  151. gen_tag(tag, stored_key, (const byte *)"context", 7);
  152. return 0;
  153. }