1
0

worker_batch.inc.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. void *CRYPTO_NAMESPACE(worker_batch)(void *task)
  2. {
  3. union pubonionunion pubonion;
  4. u8 * const pk = &pubonion.raw[PKPREFIX_SIZE];
  5. u8 secret[SKPREFIX_SIZE + SECRET_LEN];
  6. u8 * const sk = &secret[SKPREFIX_SIZE];
  7. u8 seed[SEED_LEN];
  8. u8 hashsrc[checksumstrlen + PUBLIC_LEN + 1];
  9. u8 wpk[PUBLIC_LEN + 1];
  10. ge_p3 ALIGN(16) ge_public;
  11. char *sname;
  12. // state to keep batch data
  13. ge_p3 ALIGN(16) ge_batch [BATCHNUM];
  14. fe ALIGN(16) tmp_batch[BATCHNUM];
  15. bytes32 ALIGN(16) pk_batch [BATCHNUM];
  16. size_t counter;
  17. size_t i;
  18. #ifdef STATISTICS
  19. struct statstruct *st = (struct statstruct *)task;
  20. #else
  21. (void) task;
  22. #endif
  23. PREFILTER
  24. memcpy(secret,skprefix,SKPREFIX_SIZE);
  25. wpk[PUBLIC_LEN] = 0;
  26. memset(&pubonion,0,sizeof(pubonion));
  27. memcpy(pubonion.raw,pkprefix,PKPREFIX_SIZE);
  28. // write version later as it will be overwritten by hash
  29. memcpy(hashsrc,checksumstr,checksumstrlen);
  30. hashsrc[checksumstrlen + PUBLIC_LEN] = 0x03; // version
  31. sname = makesname();
  32. initseed:
  33. #ifdef STATISTICS
  34. ++st->numrestart.v;
  35. #endif
  36. randombytes(seed,sizeof(seed));
  37. ed25519_seckey_expand(sk,seed);
  38. ge_scalarmult_base(&ge_public,sk);
  39. for (counter = 0;counter < SIZE_MAX-(8*BATCHNUM);counter += 8*BATCHNUM) {
  40. ge_p1p1 ALIGN(16) sum;
  41. if (unlikely(endwork))
  42. goto end;
  43. for (size_t b = 0;b < BATCHNUM;++b) {
  44. ge_batch[b] = ge_public;
  45. ge_add(&sum,&ge_public,&ge_eightpoint);
  46. ge_p1p1_to_p3(&ge_public,&sum);
  47. }
  48. // NOTE: leaves unfinished one bit at the very end
  49. ge_p3_batchtobytes_destructive_1(pk_batch,ge_batch,tmp_batch,BATCHNUM);
  50. #ifdef STATISTICS
  51. st->numcalc.v += BATCHNUM;
  52. #endif
  53. for (size_t b = 0;b < BATCHNUM;++b) {
  54. DOFILTER(i,pk_batch[b],{
  55. if (numwords > 1) {
  56. shiftpk(wpk,pk_batch[b],filter_len(i));
  57. size_t j;
  58. for (int w = 1;;) {
  59. DOFILTER(j,wpk,goto secondfind);
  60. goto next;
  61. secondfind:
  62. if (++w >= numwords)
  63. break;
  64. shiftpk(wpk,wpk,filter_len(j));
  65. }
  66. }
  67. // found!
  68. // finish it up
  69. ge_p3_batchtobytes_destructive_finish(pk_batch[b],&ge_batch[b]);
  70. // copy public key
  71. memcpy(pk,pk_batch[b],PUBLIC_LEN);
  72. // update secret key with counter
  73. addsztoscalar32(sk,counter + (b * 8));
  74. // sanity check
  75. if ((sk[0] & 248) != sk[0] || ((sk[31] & 63) | 64) != sk[31])
  76. goto initseed;
  77. ADDNUMSUCCESS;
  78. // calc checksum
  79. memcpy(&hashsrc[checksumstrlen],pk,PUBLIC_LEN);
  80. FIPS202_SHA3_256(hashsrc,sizeof(hashsrc),&pk[PUBLIC_LEN]);
  81. // version byte
  82. pk[PUBLIC_LEN + 2] = 0x03;
  83. // full name
  84. strcpy(base32_to(&sname[direndpos],pk,PUBONION_LEN),".onion");
  85. onionready(sname,secret,pubonion.raw,0);
  86. pk[PUBLIC_LEN] = 0; // what is this for?
  87. // don't reuse same seed
  88. goto initseed;
  89. });
  90. next:
  91. ;
  92. }
  93. }
  94. goto initseed;
  95. end:
  96. free(sname);
  97. POSTFILTER
  98. sodium_memzero(secret,sizeof(secret));
  99. sodium_memzero(seed,sizeof(seed));
  100. return 0;
  101. }