rclient.c 4.6 KB

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