rclient.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <openssl/rand.h>
  4. #include <openssl/sha.h>
  5. #include "ptwist.h"
  6. byte maingen[PTWIST_BYTES];
  7. byte twistgen[PTWIST_BYTES];
  8. byte mainpub[PTWIST_BYTES];
  9. byte twistpub[PTWIST_BYTES];
  10. static void gen_tag(byte tag[PTWIST_TAG_BYTES], byte key[16],
  11. const byte *context, size_t context_len)
  12. {
  13. byte seckey[PTWIST_BYTES];
  14. byte sharedsec[PTWIST_BYTES+context_len];
  15. byte usetwist;
  16. byte taghashout[32];
  17. #if PTWIST_PUZZLE_STRENGTH > 0
  18. size_t puzzle_len = 16+PTWIST_RESP_BYTES;
  19. byte value_to_hash[puzzle_len];
  20. byte hashout[32];
  21. bn_t Rbn, Hbn;
  22. int i, len, sign;
  23. #endif
  24. memset(tag, 0xAA, PTWIST_TAG_BYTES);
  25. /* Use the main or the twist curve? */
  26. RAND_bytes(&usetwist, 1);
  27. usetwist &= 1;
  28. /* Create seckey*G and seckey*Y */
  29. RAND_bytes(seckey, PTWIST_BYTES);
  30. ptwist_pointmul(tag, usetwist ? twistgen : maingen, seckey);
  31. ptwist_pointmul(sharedsec, usetwist ? twistpub : mainpub, seckey);
  32. /* Create the tag hash keys */
  33. memmove(sharedsec+PTWIST_BYTES, context, context_len);
  34. SHA256(sharedsec, PTWIST_BYTES, taghashout);
  35. #if PTWIST_PUZZLE_STRENGTH > 0
  36. /* The puzzle is to find a response R such that SHA256(K || R)
  37. starts with PTWIST_PUZZLE_STRENGTH bits of 0s. K is the first
  38. 128 bits of the above hash tag keys. */
  39. /* Construct our response to the puzzle. Start looking for R in a
  40. * random place. */
  41. memmove(value_to_hash, taghashout, 16);
  42. RAND_bytes(value_to_hash+16, PTWIST_RESP_BYTES);
  43. value_to_hash[16+PTWIST_RESP_BYTES-1] &= PTWIST_RESP_MASK;
  44. while(1) {
  45. unsigned int firstbits;
  46. md_map_sh256(hashout, value_to_hash, puzzle_len);
  47. #if PTWIST_PUZZLE_STRENGTH < 32
  48. /* This assumes that you're on an architecture that doesn't care
  49. * about alignment, and is little endian. */
  50. firstbits = *(unsigned int*)hashout;
  51. if ((firstbits & PTWIST_PUZZLE_MASK) == 0) {
  52. break;
  53. }
  54. /* Increment R and try again. */
  55. for(i=0;i<PTWIST_RESP_BYTES;++i) {
  56. if (++value_to_hash[16+i]) break;
  57. }
  58. value_to_hash[16+PTWIST_RESP_BYTES-1] &= PTWIST_RESP_MASK;
  59. #else
  60. #error "Code assumes PTWIST_PUZZLE_STRENGTH < 32"
  61. #endif
  62. }
  63. /*
  64. for(i=0;i<puzzle_len;++i) {
  65. printf("%02x", value_to_hash[i]);
  66. if ((i%4) == 3) printf(" ");
  67. }
  68. printf("\n");
  69. for(i=0;i<32;++i) {
  70. printf("%02x", hashout[i]);
  71. if ((i%4) == 3) printf(" ");
  72. }
  73. printf("\n");
  74. */
  75. /* When we get here, we have solved the puzzle. R is in
  76. * value_to_hash[16..16+PTWIST_RESP_BYTES-1], the hash output
  77. * hashout starts with PTWIST_PUZZLE_STRENGTH bits of 0s, and we'll
  78. * want to copy out H (the next PTWIST_HASH_SHOWBITS bits of the
  79. * hash output). The final tag is [seckey*G]_x || R || H . */
  80. bn_new(Rbn);
  81. bn_new(Hbn);
  82. bn_read_bin(Rbn, value_to_hash+16, PTWIST_RESP_BYTES, BN_POS);
  83. hashout[PTWIST_HASH_TOTBYTES-1] &= PTWIST_HASH_MASK;
  84. bn_read_bin(Hbn, hashout, PTWIST_HASH_TOTBYTES, BN_POS);
  85. bn_lsh(Hbn, Hbn, PTWIST_RESP_BITS-PTWIST_PUZZLE_STRENGTH);
  86. bn_add(Hbn, Hbn, Rbn);
  87. len = PTWIST_TAG_BYTES-PTWIST_BYTES;
  88. bn_write_bin(tag+PTWIST_BYTES, &len, &sign, Hbn);
  89. /*
  90. for(i=0;i<PTWIST_TAG_BYTES;++i) {
  91. printf("%02x", tag[i]);
  92. if ((i%4) == 3) printf(" ");
  93. }
  94. printf("\n");
  95. */
  96. bn_free(Rbn);
  97. bn_free(Hbn);
  98. #elif PTWIST_HASH_SHOWBITS <= 128
  99. /* We're not using a client puzzle, so the tag is [seckey*G]_x || H
  100. * where H is the first PTWIST_HASH_SHOWBITS bits of the above hash
  101. * output. The key generated is the last 128 bits of that output.
  102. * If there's no client puzzle, PTWIST_HASH_SHOWBITS must be a multiple
  103. * of 8. */
  104. memmove(tag+PTWIST_BYTES, taghashout, PTWIST_HASH_SHOWBITS/8);
  105. #else
  106. #error "No client puzzle used, but PWTIST_HASH_SHOWBITS > 128"
  107. #endif
  108. memmove(key, taghashout+16, 16);
  109. }
  110. int main(int argc, char **argv)
  111. {
  112. FILE *fp;
  113. int res;
  114. int i;
  115. byte tag[PTWIST_TAG_BYTES];
  116. int numtags = argc > 1 ? atoi(argv[1]) : 10;
  117. /* Create the generators */
  118. memset(maingen, 0, PTWIST_BYTES);
  119. maingen[0] = 2;
  120. memset(twistgen, 0, PTWIST_BYTES);
  121. /* Read the public keys */
  122. fp = fopen("pubkey", "rb");
  123. if (fp == NULL) {
  124. perror("fopen");
  125. exit(1);
  126. }
  127. res = fread(mainpub, PTWIST_BYTES, 1, fp);
  128. if (res < 1) {
  129. perror("fread");
  130. exit(1);
  131. }
  132. res = fread(twistpub, PTWIST_BYTES, 1, fp);
  133. if (res < 1) {
  134. perror("fread");
  135. exit(1);
  136. }
  137. fclose(fp);
  138. fp = fopen("tags", "wb");
  139. if (fp == NULL) {
  140. perror("fopen");
  141. exit(1);
  142. }
  143. for(i=0;i<numtags;++i) {
  144. byte key[16];
  145. #if 0
  146. int j;
  147. #endif
  148. gen_tag(tag, key, (const byte *)"context", 7);
  149. fwrite(tag, PTWIST_TAG_BYTES, 1, fp);
  150. #if 0
  151. for(j=0;j<16;++j) {
  152. printf("%02x", key[j]);
  153. }
  154. printf("\n");
  155. #endif
  156. }
  157. fclose(fp);
  158. return 0;
  159. }