prime.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. #include "config.h"
  2. #include <stdbool.h>
  3. #include <stddef.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <sys/time.h>
  7. #include <gmp.h>
  8. #include "compat.h"
  9. #include "miner.h"
  10. #define nMaxSieveSize 1000000u
  11. #define nPrimeTableLimit nMaxSieveSize
  12. #define nPrimorialTableLimit 100000u
  13. #define PRIME_COUNT 78498
  14. #define PRIMORIAL_COUNT 9592
  15. static
  16. unsigned vPrimes[PRIME_COUNT];
  17. mpz_t bnTwoInverses[PRIME_COUNT];
  18. mpz_t vPrimorials[PRIMORIAL_COUNT];
  19. static
  20. int64_t GetTimeMicros()
  21. {
  22. struct timeval tv;
  23. cgtime(&tv);
  24. return ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec;
  25. }
  26. static
  27. int64_t GetTimeMillis()
  28. {
  29. return GetTimeMicros() / 1000;
  30. }
  31. static
  32. int64_t GetTime()
  33. {
  34. return GetTimeMicros() / 1000000;
  35. }
  36. static
  37. bool error(const char *fmt, ...)
  38. {
  39. puts(fmt); // FIXME
  40. return false;
  41. }
  42. mpz_t bnTwo;
  43. void GeneratePrimeTable()
  44. {
  45. mpz_init_set_ui(bnTwo, 2);
  46. mpz_t bnOne;
  47. mpz_init_set_ui(bnOne, 1);
  48. mpz_t *bnLastPrimorial = &bnOne;
  49. unsigned i = 0;
  50. // Generate prime table using sieve of Eratosthenes
  51. bool vfComposite[nPrimeTableLimit] = {false};
  52. for (unsigned int nFactor = 2; nFactor * nFactor < nPrimeTableLimit; nFactor++)
  53. {
  54. if (vfComposite[nFactor])
  55. continue;
  56. for (unsigned int nComposite = nFactor * nFactor; nComposite < nPrimeTableLimit; nComposite += nFactor)
  57. vfComposite[nComposite] = true;
  58. }
  59. for (unsigned int n = 2; n < nPrimeTableLimit; n++)
  60. if (!vfComposite[n])
  61. {
  62. vPrimes[i] = n;
  63. if (n > 2)
  64. {
  65. // bnOne isn't 1 here, which is okay since it is no longer needed as 1 after prime 2
  66. mpz_init(bnTwoInverses[i]);
  67. mpz_set_ui(bnOne, n);
  68. if (!mpz_invert(bnTwoInverses[i], bnTwo, bnOne))
  69. quit(1, "mpz_invert of 2 failed for prime %u", n);
  70. }
  71. if (n < nPrimorialTableLimit)
  72. {
  73. mpz_init(vPrimorials[i]);
  74. mpz_mul_ui(vPrimorials[i], *bnLastPrimorial, n);
  75. bnLastPrimorial = &vPrimorials[i];
  76. }
  77. ++i;
  78. }
  79. mpz_clear(bnOne);
  80. applog(LOG_DEBUG, "GeneratePrimeTable() : prime table [1, %d] generated with %lu primes", nPrimeTableLimit, (unsigned long)i);
  81. }
  82. #define nFractionalBits 24
  83. #define TARGET_FRACTIONAL_MASK ((1u << nFractionalBits) - 1)
  84. #define TARGET_LENGTH_MASK (~TARGET_FRACTIONAL_MASK)
  85. // Check Fermat probable primality test (2-PRP): 2 ** (n-1) = 1 (mod n)
  86. // true: n is probable prime
  87. // false: n is composite; set fractional length in the nLength output
  88. static
  89. bool FermatProbablePrimalityTest(mpz_t *n, unsigned int *pnLength)
  90. {
  91. mpz_t a, e, r;
  92. mpz_init_set_ui(a, 2); // base; Fermat witness
  93. mpz_init(e);
  94. mpz_sub_ui(e, *n, 1);
  95. mpz_init(r);
  96. mpz_powm(r, a, e, *n);
  97. mpz_clear(a);
  98. mpz_clear(e);
  99. if (!mpz_cmp_ui(r, 1))
  100. {
  101. mpz_clear(r);
  102. return true;
  103. }
  104. // Failed Fermat test, calculate fractional length
  105. // nFractionalLength = ( (n-r) << nFractionalBits ) / n
  106. mpz_sub(r, *n, r);
  107. mpz_mul_2exp(r, r, nFractionalBits);
  108. mpz_fdiv_q(r, r, *n);
  109. unsigned int nFractionalLength = mpz_get_ui(r);
  110. mpz_clear(r);
  111. if (nFractionalLength >= (1 << nFractionalBits))
  112. return error("FermatProbablePrimalityTest() : fractional assert");
  113. *pnLength = (*pnLength & TARGET_LENGTH_MASK) | nFractionalLength;
  114. return false;
  115. }
  116. static
  117. unsigned int TargetGetLength(unsigned int nBits)
  118. {
  119. return ((nBits & TARGET_LENGTH_MASK) >> nFractionalBits);
  120. }
  121. static
  122. void TargetIncrementLength(unsigned int *pnBits)
  123. {
  124. *pnBits += (1 << nFractionalBits);
  125. }
  126. // Test probable primality of n = 2p +/- 1 based on Euler, Lagrange and Lifchitz
  127. // fSophieGermain:
  128. // true: n = 2p+1, p prime, aka Cunningham Chain of first kind
  129. // false: n = 2p-1, p prime, aka Cunningham Chain of second kind
  130. // Return values
  131. // true: n is probable prime
  132. // false: n is composite; set fractional length in the nLength output
  133. static
  134. bool EulerLagrangeLifchitzPrimalityTest(mpz_t *n, bool fSophieGermain, unsigned int *pnLength)
  135. {
  136. mpz_t a, e, r;
  137. mpz_init_set_ui(a, 2);
  138. mpz_init(e);
  139. mpz_sub_ui(e, *n, 1);
  140. mpz_fdiv_q_2exp(e, e, 1);
  141. mpz_init(r);
  142. mpz_powm(r, a, e, *n);
  143. mpz_clear(a);
  144. mpz_clear(e);
  145. unsigned nMod8 = mpz_fdiv_ui(*n, 8);
  146. bool fPassedTest = false;
  147. if (fSophieGermain && (nMod8 == 7)) // Euler & Lagrange
  148. fPassedTest = !mpz_cmp_ui(r, 1);
  149. else if (nMod8 == (fSophieGermain ? 3 : 5)) // Lifchitz
  150. {
  151. mpz_t mp;
  152. mpz_init_set_ui(mp, 1);
  153. mpz_add(mp, r, mp);
  154. fPassedTest = !mpz_cmp(mp, *n);
  155. mpz_clear(mp);
  156. }
  157. else if ((!fSophieGermain) && (nMod8 == 1)) // LifChitz
  158. fPassedTest = !mpz_cmp_ui(r, 1);
  159. else
  160. {
  161. mpz_clear(r);
  162. return error("EulerLagrangeLifchitzPrimalityTest() : invalid n %% 8 = %d, %s", nMod8, (fSophieGermain? "first kind" : "second kind"));
  163. }
  164. if (fPassedTest)
  165. {
  166. mpz_clear(r);
  167. return true;
  168. }
  169. // Failed test, calculate fractional length
  170. // derive Fermat test remainder
  171. mpz_mul(r, r, r);
  172. mpz_fdiv_r(r, r, *n);
  173. // nFractionalLength = ( (n-r) << nFractionalBits ) / n
  174. mpz_sub(r, *n, r);
  175. mpz_mul_2exp(r, r, nFractionalBits);
  176. mpz_fdiv_q(r, r, *n);
  177. unsigned int nFractionalLength = mpz_get_ui(r);
  178. mpz_clear(r);
  179. if (nFractionalLength >= (1 << nFractionalBits))
  180. return error("EulerLagrangeLifchitzPrimalityTest() : fractional assert");
  181. *pnLength = (*pnLength & TARGET_LENGTH_MASK) | nFractionalLength;
  182. return false;
  183. }
  184. // Test Probable Cunningham Chain for: n
  185. // fSophieGermain:
  186. // true - Test for Cunningham Chain of first kind (n, 2n+1, 4n+3, ...)
  187. // false - Test for Cunningham Chain of second kind (n, 2n-1, 4n-3, ...)
  188. // Return value:
  189. // true - Probable Cunningham Chain found (length at least 2)
  190. // false - Not Cunningham Chain
  191. static
  192. bool ProbableCunninghamChainTest(mpz_t *n, bool fSophieGermain, bool fFermatTest, unsigned int *pnProbableChainLength)
  193. {
  194. #ifdef SUPERDEBUG
  195. printf("ProbableCunninghamChainTest(");
  196. mpz_out_str(stdout, 0x10, *n);
  197. printf(", %d, %d, %u)\n", (int)fSophieGermain, (int)fFermatTest, *pnProbableChainLength);
  198. #endif
  199. *pnProbableChainLength = 0;
  200. mpz_t N;
  201. mpz_init_set(N, *n);
  202. // Fermat test for n first
  203. if (!FermatProbablePrimalityTest(&N, pnProbableChainLength))
  204. {
  205. mpz_clear(N);
  206. return false;
  207. }
  208. #ifdef SUPERDEBUG
  209. printf("N=");
  210. mpz_out_str(stdout, 0x10, N);
  211. printf("\n");
  212. #endif
  213. // Euler-Lagrange-Lifchitz test for the following numbers in chain
  214. while (true)
  215. {
  216. TargetIncrementLength(pnProbableChainLength);
  217. mpz_add(N, N, N);
  218. if (fSophieGermain)
  219. mpz_add_ui(N, N, 1);
  220. else
  221. mpz_sub_ui(N, N, 1);
  222. if (fFermatTest)
  223. {
  224. if (!FermatProbablePrimalityTest(&N, pnProbableChainLength))
  225. break;
  226. }
  227. else
  228. {
  229. #ifdef SUPERDEBUG
  230. if (!fSophieGermain)
  231. {
  232. printf("EulerLagrangeLifchitzPrimalityTest(");
  233. mpz_out_str(stdout, 0x10, N);
  234. printf(", 1, %d)\n", *pnProbableChainLength);
  235. }
  236. #endif
  237. if (!EulerLagrangeLifchitzPrimalityTest(&N, fSophieGermain, pnProbableChainLength))
  238. break;
  239. }
  240. }
  241. mpz_clear(N);
  242. #ifdef SUPERDEBUG
  243. printf("PCCT => %u (%u)\n", TargetGetLength(*pnProbableChainLength), *pnProbableChainLength);
  244. #endif
  245. return (TargetGetLength(*pnProbableChainLength) >= 2);
  246. }
  247. static
  248. unsigned int TargetFromInt(unsigned int nLength)
  249. {
  250. return (nLength << nFractionalBits);
  251. }
  252. // Test probable prime chain for: nOrigin
  253. // Return value:
  254. // true - Probable prime chain found (one of nChainLength meeting target)
  255. // false - prime chain too short (none of nChainLength meeting target)
  256. static
  257. bool ProbablePrimeChainTest(mpz_t *bnPrimeChainOrigin, unsigned int nBits, bool fFermatTest, unsigned int *pnChainLengthCunningham1, unsigned int *pnChainLengthCunningham2, unsigned int *pnChainLengthBiTwin)
  258. {
  259. *pnChainLengthCunningham1 = 0;
  260. *pnChainLengthCunningham2 = 0;
  261. *pnChainLengthBiTwin = 0;
  262. mpz_t mp;
  263. mpz_init(mp);
  264. // Test for Cunningham Chain of first kind
  265. mpz_sub_ui(mp, *bnPrimeChainOrigin, 1);
  266. ProbableCunninghamChainTest(&mp, true, fFermatTest, pnChainLengthCunningham1);
  267. // Test for Cunningham Chain of second kind
  268. mpz_add_ui(mp, *bnPrimeChainOrigin, 1);
  269. ProbableCunninghamChainTest(&mp, false, fFermatTest, pnChainLengthCunningham2);
  270. mpz_clear(mp);
  271. // Figure out BiTwin Chain length
  272. // BiTwin Chain allows a single prime at the end for odd length chain
  273. *pnChainLengthBiTwin = (TargetGetLength(*pnChainLengthCunningham1) > TargetGetLength(*pnChainLengthCunningham2)) ? (*pnChainLengthCunningham2 + TargetFromInt(TargetGetLength(*pnChainLengthCunningham2)+1)) : (*pnChainLengthCunningham1 + TargetFromInt(TargetGetLength(*pnChainLengthCunningham1)));
  274. return (*pnChainLengthCunningham1 >= nBits || *pnChainLengthCunningham2 >= nBits || *pnChainLengthBiTwin >= nBits);
  275. }
  276. struct SieveOfEratosthenes {
  277. bool valid;
  278. unsigned int nSieveSize; // size of the sieve
  279. unsigned int nBits; // target of the prime chain to search for
  280. mpz_t hashBlockHeader; // block header hash
  281. mpz_t bnFixedFactor; // fixed factor to derive the chain
  282. // bitmaps of the sieve, index represents the variable part of multiplier
  283. bool vfCompositeCunningham1[1000000];
  284. bool vfCompositeCunningham2[1000000];
  285. bool vfCompositeBiTwin[1000000];
  286. unsigned int nPrimeSeq; // prime sequence number currently being processed
  287. unsigned int nCandidateMultiplier; // current candidate for power test
  288. };
  289. static
  290. void psieve_reset(struct SieveOfEratosthenes *psieve)
  291. {
  292. mpz_clear(psieve->hashBlockHeader);
  293. mpz_clear(psieve->bnFixedFactor);
  294. psieve->valid = false;
  295. }
  296. static
  297. void psieve_init(struct SieveOfEratosthenes *psieve, unsigned nSieveSize, unsigned nBits, mpz_t *hashBlockHeader, mpz_t *bnFixedMultiplier)
  298. {
  299. assert(!psieve->valid);
  300. *psieve = (struct SieveOfEratosthenes){
  301. .valid = true,
  302. .nSieveSize = nSieveSize,
  303. .nBits = nBits,
  304. };
  305. mpz_init_set(psieve->hashBlockHeader, *hashBlockHeader);
  306. mpz_init(psieve->bnFixedFactor);
  307. mpz_mul(psieve->bnFixedFactor, *bnFixedMultiplier, *hashBlockHeader);
  308. }
  309. // Weave sieve for the next prime in table
  310. // Return values:
  311. // True - weaved another prime; nComposite - number of composites removed
  312. // False - sieve already completed
  313. static
  314. bool psieve_Weave(struct SieveOfEratosthenes *psieve)
  315. {
  316. unsigned nPrime = vPrimes[psieve->nPrimeSeq];
  317. if (psieve->nPrimeSeq >= PRIME_COUNT || nPrime >= psieve->nSieveSize)
  318. return false; // sieve has been completed
  319. if (mpz_fdiv_ui(psieve->bnFixedFactor, nPrime) == 0)
  320. {
  321. // Nothing in the sieve is divisible by this prime
  322. ++psieve->nPrimeSeq;
  323. return true;
  324. }
  325. // Find the modulo inverse of fixed factor
  326. mpz_t bnFixedInverse, p;
  327. mpz_init(bnFixedInverse);
  328. mpz_init_set_ui(p, nPrime);
  329. if (!mpz_invert(bnFixedInverse, psieve->bnFixedFactor, p))
  330. {
  331. mpz_clear(p);
  332. mpz_clear(bnFixedInverse);
  333. return error("CSieveOfEratosthenes::Weave(): BN_mod_inverse of fixed factor failed for prime #%u=%u", psieve->nPrimeSeq, nPrime);
  334. }
  335. mpz_clear(p);
  336. mpz_t *pbnTwoInverse = &bnTwoInverses[psieve->nPrimeSeq];
  337. mpz_t mp;
  338. mpz_init(mp);
  339. // Weave the sieve for the prime
  340. unsigned int nChainLength = TargetGetLength(psieve->nBits);
  341. for (unsigned int nBiTwinSeq = 0; nBiTwinSeq < 2 * nChainLength; nBiTwinSeq++)
  342. {
  343. // Find the first number that's divisible by this prime
  344. int nDelta = ((nBiTwinSeq % 2 == 0) ? (-1) : 1);
  345. mpz_mul_ui(mp, bnFixedInverse, nPrime - nDelta);
  346. unsigned int nSolvedMultiplier = mpz_fdiv_ui(mp, nPrime);
  347. if (nBiTwinSeq % 2 == 1)
  348. mpz_mul(bnFixedInverse, bnFixedInverse, *pbnTwoInverse); // for next number in chain
  349. if (nBiTwinSeq < nChainLength)
  350. for (unsigned int nVariableMultiplier = nSolvedMultiplier; nVariableMultiplier < psieve->nSieveSize; nVariableMultiplier += nPrime)
  351. psieve->vfCompositeBiTwin[nVariableMultiplier] = true;
  352. if (((nBiTwinSeq & 1u) == 0))
  353. for (unsigned int nVariableMultiplier = nSolvedMultiplier; nVariableMultiplier < psieve->nSieveSize; nVariableMultiplier += nPrime)
  354. psieve->vfCompositeCunningham1[nVariableMultiplier] = true;
  355. if (((nBiTwinSeq & 1u) == 1u))
  356. for (unsigned int nVariableMultiplier = nSolvedMultiplier; nVariableMultiplier < psieve->nSieveSize; nVariableMultiplier += nPrime)
  357. psieve->vfCompositeCunningham2[nVariableMultiplier] = true;
  358. }
  359. mpz_clear(mp);
  360. mpz_clear(bnFixedInverse);
  361. ++psieve->nPrimeSeq;
  362. return true;
  363. }
  364. static
  365. bool psieve_GetNextCandidateMultiplier(struct SieveOfEratosthenes *psieve, unsigned int *pnVariableMultiplier)
  366. {
  367. while (true)
  368. {
  369. psieve->nCandidateMultiplier++;
  370. if (psieve->nCandidateMultiplier >= psieve->nSieveSize)
  371. {
  372. psieve->nCandidateMultiplier = 0;
  373. return false;
  374. }
  375. if (!psieve->vfCompositeCunningham1[psieve->nCandidateMultiplier] ||
  376. !psieve->vfCompositeCunningham2[psieve->nCandidateMultiplier] ||
  377. !psieve->vfCompositeBiTwin[psieve->nCandidateMultiplier])
  378. {
  379. *pnVariableMultiplier = psieve->nCandidateMultiplier;
  380. return true;
  381. }
  382. }
  383. }
  384. // Get total number of candidates for power test
  385. static
  386. unsigned int psieve_GetCandidateCount(struct SieveOfEratosthenes *psieve)
  387. {
  388. unsigned int nCandidates = 0;
  389. for (unsigned int nMultiplier = 0; nMultiplier < psieve->nSieveSize; nMultiplier++)
  390. {
  391. if (!psieve->vfCompositeCunningham1[nMultiplier] || !psieve->vfCompositeCunningham2[nMultiplier] || !psieve->vfCompositeBiTwin[nMultiplier])
  392. nCandidates++;
  393. }
  394. return nCandidates;
  395. }
  396. // Mine probable prime chain of form: n = h * p# +/- 1
  397. bool MineProbablePrimeChain(struct SieveOfEratosthenes *psieve, const uint8_t *header, mpz_t *hash, mpz_t *bnFixedMultiplier, bool *pfNewBlock, unsigned *pnTriedMultiplier, unsigned *pnProbableChainLength, unsigned *pnTests, unsigned *pnPrimesHit, struct work *work)
  398. {
  399. const uint32_t *pnbits = (void*)&header[72];
  400. *pnProbableChainLength = 0;
  401. *pnTests = 0;
  402. *pnPrimesHit = 0;
  403. if (*pfNewBlock && psieve->valid)
  404. {
  405. // Must rebuild the sieve
  406. psieve_reset(psieve);
  407. }
  408. *pfNewBlock = false;
  409. int64_t nStart, nCurrent; // microsecond timer
  410. if (!psieve->valid)
  411. {
  412. // Build sieve
  413. nStart = GetTimeMicros();
  414. #ifdef SUPERDEBUG
  415. fprintf(stderr, "psieve_init(?, %u, %08x, ", nMaxSieveSize, *pnbits);
  416. mpz_out_str(stderr, 0x10, *hash);
  417. fprintf(stderr, ", ");
  418. mpz_out_str(stderr, 0x10, *bnFixedMultiplier);
  419. fprintf(stderr, ")\n");
  420. #endif
  421. psieve_init(psieve, nMaxSieveSize, *pnbits, hash, bnFixedMultiplier);
  422. while (psieve_Weave(psieve));
  423. applog(LOG_DEBUG, "MineProbablePrimeChain() : new sieve (%u/%u) ready in %uus", psieve_GetCandidateCount(psieve), nMaxSieveSize, (unsigned int) (GetTimeMicros() - nStart));
  424. }
  425. mpz_t bnChainOrigin;
  426. mpz_init(bnChainOrigin);
  427. nStart = GetTimeMicros();
  428. nCurrent = nStart;
  429. while (nCurrent - nStart < 10000 && nCurrent >= nStart)
  430. {
  431. ++*pnTests;
  432. if (!psieve_GetNextCandidateMultiplier(psieve, pnTriedMultiplier))
  433. {
  434. // power tests completed for the sieve
  435. psieve_reset(psieve);
  436. *pfNewBlock = true; // notify caller to change nonce
  437. mpz_clear(bnChainOrigin);
  438. return false;
  439. }
  440. #ifdef SUPERDEBUG
  441. printf("nTriedMultiplier=%d\n", *pnTriedMultiplier=640150);
  442. #endif
  443. mpz_mul(bnChainOrigin, *hash, *bnFixedMultiplier);
  444. mpz_mul_ui(bnChainOrigin, bnChainOrigin, *pnTriedMultiplier);
  445. unsigned int nChainLengthCunningham1 = 0;
  446. unsigned int nChainLengthCunningham2 = 0;
  447. unsigned int nChainLengthBiTwin = 0;
  448. #ifdef SUPERDEBUG
  449. printf("ProbablePrimeChainTest(bnChainOrigin=");
  450. mpz_out_str(stdout, 0x10, bnChainOrigin);
  451. printf(", nbits=%08lx, false, %d, %d, %d)\n", (unsigned long)*pnbits, nChainLengthCunningham1, nChainLengthCunningham2, nChainLengthBiTwin);
  452. #endif
  453. if (ProbablePrimeChainTest(&bnChainOrigin, *pnbits, false, &nChainLengthCunningham1, &nChainLengthCunningham2, &nChainLengthBiTwin))
  454. {
  455. // bnChainOrigin is not used again, so recycled here for the result
  456. // block.bnPrimeChainMultiplier = *bnFixedMultiplier * *pnTriedMultiplier;
  457. mpz_mul_ui(bnChainOrigin, *bnFixedMultiplier, *pnTriedMultiplier);
  458. size_t exportsz, resultoff;
  459. uint8_t *export = mpz_export(NULL, &exportsz, -1, 1, -1, 0, bnChainOrigin);
  460. assert(exportsz < 250); // FIXME: bitcoin varint
  461. resultoff = 1;
  462. if (export[0] & 0x80)
  463. ++resultoff;
  464. uint8_t *result = malloc(exportsz + resultoff);
  465. result[0] = exportsz + resultoff - 1;
  466. result[1] = '\0';
  467. memcpy(&result[resultoff], export, exportsz);
  468. if (mpz_sgn(bnChainOrigin) < 0)
  469. result[1] |= 0x80;
  470. free(export);
  471. work->sig = result;
  472. work->sigsz = exportsz + resultoff;
  473. char hex[1 + (work->sigsz * 2)];
  474. bin2hex(hex, work->sig, work->sigsz);
  475. applog(LOG_DEBUG, "SIGNATURE: %s\n", hex);
  476. // printf("Probable prime chain found for block=%s!!\n Target: %s\n Length: (%s %s %s)\n", block.GetHash().GetHex().c_str(),
  477. // TargetToString(nbits).c_str(), TargetToString(nChainLengthCunningham1).c_str(), TargetToString(nChainLengthCunningham2).c_str(), TargetToString(nChainLengthBiTwin).c_str());
  478. applog(LOG_DEBUG, "Probable prime chain found for block");
  479. *pnProbableChainLength = nChainLengthCunningham1;
  480. if (*pnProbableChainLength < nChainLengthCunningham2)
  481. *pnProbableChainLength = nChainLengthCunningham2;
  482. if (*pnProbableChainLength < nChainLengthBiTwin)
  483. *pnProbableChainLength = nChainLengthBiTwin;
  484. mpz_clear(bnChainOrigin);
  485. return true;
  486. }
  487. *pnProbableChainLength = nChainLengthCunningham1;
  488. if (*pnProbableChainLength < nChainLengthCunningham2)
  489. *pnProbableChainLength = nChainLengthCunningham2;
  490. if (*pnProbableChainLength < nChainLengthBiTwin)
  491. *pnProbableChainLength = nChainLengthBiTwin;
  492. if(TargetGetLength(*pnProbableChainLength) >= 1)
  493. ++*pnPrimesHit;
  494. nCurrent = GetTimeMicros();
  495. }
  496. mpz_clear(bnChainOrigin);
  497. return false; // stop as timed out
  498. }
  499. // Checks that the high bit is set, and low bit is clear (ie, divisible by 2)
  500. static
  501. bool check_ends(const uint8_t *hash)
  502. {
  503. return (hash[31] & 0x80) && !(hash[0] & 1);
  504. }
  505. static inline
  506. void set_mpz_to_hash(mpz_t *hash, const uint8_t *hashb)
  507. {
  508. mpz_import(*hash, 8, -1, 4, -1, 0, hashb);
  509. }
  510. struct prime_longterms {
  511. unsigned int nPrimorialHashFactor;
  512. int64_t nTimeExpected; // time expected to prime chain (micro-second)
  513. int64_t nTimeExpectedPrev; // time expected to prime chain last time
  514. bool fIncrementPrimorial; // increase or decrease primorial factor
  515. unsigned current_prime;
  516. int64_t nHPSTimerStart;
  517. int64_t nLogTime;
  518. int64_t nPrimeCounter;
  519. int64_t nTestCounter;
  520. };
  521. static
  522. struct prime_longterms *get_prime_longterms()
  523. {
  524. struct bfgtls_data *bfgtls = get_bfgtls();
  525. struct prime_longterms *pl = bfgtls->prime_longterms;
  526. if (unlikely(!pl))
  527. {
  528. pl = bfgtls->prime_longterms = malloc(sizeof(*pl));
  529. *pl = (struct prime_longterms){
  530. .nPrimorialHashFactor = 7,
  531. .fIncrementPrimorial = true,
  532. .current_prime = 3, // index 3 is prime number 7
  533. .nHPSTimerStart = GetTimeMillis(),
  534. };
  535. }
  536. return pl;
  537. }
  538. bool prime(uint8_t *header, struct work *work)
  539. {
  540. struct prime_longterms *pl = get_prime_longterms();
  541. bool rv = false;
  542. uint32_t *nonce = (void*)(&header[76]);
  543. unsigned char hashb[32];
  544. mpz_t hash, bnPrimeMin;
  545. mpz_init(hash);
  546. mpz_init_set_ui(bnPrimeMin, 1);
  547. mpz_mul_2exp(bnPrimeMin, bnPrimeMin, 255);
  548. bool fNewBlock = true;
  549. unsigned int nTriedMultiplier = 0;
  550. struct SieveOfEratosthenes sieve = {
  551. .valid = false,
  552. };
  553. const unsigned nHashFactor = 210;
  554. // a valid header must hash to have the MSB set, and a multiple of nHashFactor
  555. while (true)
  556. {
  557. gen_hash(header, hashb, 80);
  558. if (check_ends(hashb))
  559. {
  560. set_mpz_to_hash(&hash, hashb);
  561. if (!mpz_fdiv_ui(hash, 105))
  562. break;
  563. }
  564. if (unlikely(*nonce == 0xffffffff))
  565. {
  566. mpz_clear(hash);
  567. mpz_clear(bnPrimeMin);
  568. return false;
  569. }
  570. ++*nonce;
  571. }
  572. {
  573. char hex[9];
  574. bin2hex(hex, nonce, 4);
  575. applog(LOG_DEBUG, "Pass 1 found: %s", hex);
  576. }
  577. // primorial fixed multiplier
  578. mpz_t bnPrimorial;
  579. mpz_init(bnPrimorial);
  580. unsigned int nRoundTests = 0;
  581. unsigned int nRoundPrimesHit = 0;
  582. int64_t nPrimeTimerStart = GetTimeMicros();
  583. if (pl->nTimeExpected > pl->nTimeExpectedPrev)
  584. pl->fIncrementPrimorial = !pl->fIncrementPrimorial;
  585. pl->nTimeExpectedPrev = pl->nTimeExpected;
  586. // dynamic adjustment of primorial multiplier
  587. if (pl->fIncrementPrimorial)
  588. {
  589. ++pl->current_prime;
  590. if (pl->current_prime >= PRIMORIAL_COUNT)
  591. quit(1, "primorial increment overflow");
  592. }
  593. else if (vPrimes[pl->current_prime] > pl->nPrimorialHashFactor)
  594. {
  595. if (!pl->current_prime)
  596. quit(1, "primorial decrement overflow");
  597. --pl->current_prime;
  598. }
  599. mpz_set(bnPrimorial, vPrimorials[pl->current_prime]);
  600. while (true)
  601. {
  602. unsigned int nTests = 0;
  603. unsigned int nPrimesHit = 0;
  604. mpz_t bnMultiplierMin;
  605. // bnMultiplierMin = bnPrimeMin * nHashFactor / hash + 1
  606. mpz_init(bnMultiplierMin);
  607. mpz_mul_ui(bnMultiplierMin, bnPrimeMin, nHashFactor);
  608. mpz_fdiv_q(bnMultiplierMin, bnMultiplierMin, hash);
  609. mpz_add_ui(bnMultiplierMin, bnMultiplierMin, 1);
  610. while (mpz_cmp(bnPrimorial, bnMultiplierMin) < 0)
  611. {
  612. ++pl->current_prime;
  613. if (pl->current_prime >= PRIMORIAL_COUNT)
  614. quit(1, "primorial minimum overflow");
  615. mpz_set(bnPrimorial, vPrimorials[pl->current_prime]);
  616. }
  617. mpz_clear(bnMultiplierMin);
  618. mpz_t bnFixedMultiplier;
  619. mpz_init(bnFixedMultiplier);
  620. // bnFixedMultiplier = (bnPrimorial > nHashFactor) ? (bnPrimorial / nHashFactor) : 1
  621. if (mpz_cmp_ui(bnPrimorial, nHashFactor) > 0)
  622. {
  623. mpz_t bnHashFactor;
  624. mpz_init_set_ui(bnHashFactor, nHashFactor);
  625. mpz_fdiv_q(bnFixedMultiplier, bnPrimorial, bnHashFactor);
  626. mpz_clear(bnHashFactor);
  627. }
  628. else
  629. mpz_set_ui(bnFixedMultiplier, 1);
  630. #ifdef SUPERDEBUG
  631. fprintf(stderr,"bnFixedMultiplier=");
  632. mpz_out_str(stderr, 0x10, bnFixedMultiplier);
  633. fprintf(stderr, " nPrimorialMultiplier=%u nTriedMultiplier=%u\n", vPrimes[pl->current_prime], nTriedMultiplier);
  634. #endif
  635. // mine for prime chain
  636. unsigned int nProbableChainLength;
  637. if (MineProbablePrimeChain(&sieve, header, &hash, &bnFixedMultiplier, &fNewBlock, &nTriedMultiplier, &nProbableChainLength, &nTests, &nPrimesHit, work))
  638. {
  639. // TODO CheckWork(pblock, *pwalletMain, reservekey);
  640. mpz_clear(bnFixedMultiplier);
  641. rv = true;
  642. break;
  643. }
  644. mpz_clear(bnFixedMultiplier);
  645. nRoundTests += nTests;
  646. nRoundPrimesHit += nPrimesHit;
  647. // Meter primes/sec
  648. if (pl->nHPSTimerStart == 0)
  649. {
  650. pl->nHPSTimerStart = GetTimeMillis();
  651. pl->nPrimeCounter = 0;
  652. pl->nTestCounter = 0;
  653. }
  654. else
  655. {
  656. pl->nPrimeCounter += nPrimesHit;
  657. pl->nTestCounter += nTests;
  658. }
  659. if (GetTimeMillis() - pl->nHPSTimerStart > 60000)
  660. {
  661. double dPrimesPerMinute = 60000.0 * pl->nPrimeCounter / (GetTimeMillis() - pl->nHPSTimerStart);
  662. double dPrimesPerSec = dPrimesPerMinute / 60.0;
  663. double dTestsPerMinute = 60000.0 * pl->nTestCounter / (GetTimeMillis() - pl->nHPSTimerStart);
  664. pl->nHPSTimerStart = GetTimeMillis();
  665. pl->nPrimeCounter = 0;
  666. pl->nTestCounter = 0;
  667. if (GetTime() - pl->nLogTime > 60)
  668. {
  669. pl->nLogTime = GetTime();
  670. applog(LOG_NOTICE, "primemeter %9.0f prime/h %9.0f test/h %5dpps", dPrimesPerMinute * 60.0, dTestsPerMinute * 60.0, (int)dPrimesPerSec);
  671. }
  672. }
  673. // Check for stop or if block needs to be rebuilt
  674. // TODO
  675. // boost::this_thread::interruption_point();
  676. // if (vNodes.empty())
  677. // break;
  678. if (fNewBlock /*|| pblock->nNonce >= 0xffff0000*/)
  679. break;
  680. // if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
  681. // break;
  682. // if (pindexPrev != pindexBest)
  683. // break;
  684. }
  685. mpz_clear(bnPrimorial);
  686. // Primecoin: estimate time to block
  687. pl->nTimeExpected = (GetTimeMicros() - nPrimeTimerStart) / max(1u, nRoundTests);
  688. pl->nTimeExpected = pl->nTimeExpected * max(1u, nRoundTests) / max(1u, nRoundPrimesHit);
  689. //TODO
  690. // for (unsigned int n = 1; n < TargetGetLength(pblock->nBits); n++)
  691. // nTimeExpected = nTimeExpected * max(1u, nRoundTests) * 3 / max(1u, nRoundPrimesHit);
  692. applog(LOG_DEBUG, "PrimecoinMiner() : Round primorial=%u tests=%u primes=%u expected=%us", vPrimes[pl->current_prime], nRoundTests, nRoundPrimesHit, (unsigned int)(pl->nTimeExpected/1000000));
  693. mpz_clear(hash);
  694. mpz_clear(bnPrimeMin);
  695. return rv;
  696. }
  697. #if 0
  698. void pmain()
  699. {
  700. setbuf(stderr, NULL);
  701. setbuf(stdout, NULL);
  702. GeneratePrimeTable();
  703. unsigned char array[80] = {
  704. 0x02,0x00,0x00,0x00,
  705. 0x59,0xf7,0x56,0x1c,0x21,0x25,0xc1,0xad,0x0d,0xee,0xbd,0x05,0xb8,0x41,0x38,0xab,
  706. 0x2e,0xfb,0x65,0x40,0xc8,0xc7,0xa3,0xef,0x90,0x3d,0x75,0x8c,0x03,0x1c,0x7a,0xcc,
  707. 0x8d,0x27,0x4d,0xeb,0x7b,0x6a,0xf8,0xe0,0x44,0x2d,0x7c,0xf6,0xb9,0x71,0x12,0xd8,
  708. 0x61,0x60,0x5b,0x1f,0xa5,0xa3,0xf7,0x4f,0x61,0xe3,0x59,0x67,0x03,0xc2,0xfb,0x56,
  709. 0xed,0x78,0xdb,0x51,
  710. 0xd5,0xbe,0x38,0x07,
  711. 0xe8,0x02,0x00,0x00,
  712. };
  713. prime(array);
  714. }
  715. #endif
  716. bool scanhash_prime(struct thr_info *thr, const unsigned char *pmidstate, unsigned char *pdata, unsigned char *phash1, unsigned char *phash, const unsigned char *ptarget, uint32_t max_nonce, uint32_t *last_nonce, uint32_t nonce)
  717. {
  718. struct work *work = (struct work *)(&pmidstate[-offsetof(struct work, midstate)]);
  719. unsigned char header[80];
  720. swap32yes(header, pdata, 80 / 4);
  721. #if 0
  722. memcpy(header,(unsigned char[80]){
  723. 0x02,0x00,0x00,0x00,
  724. 0x59,0xf7,0x56,0x1c,0x21,0x25,0xc1,0xad,0x0d,0xee,0xbd,0x05,0xb8,0x41,0x38,0xab,
  725. 0x2e,0xfb,0x65,0x40,0xc8,0xc7,0xa3,0xef,0x90,0x3d,0x75,0x8c,0x03,0x1c,0x7a,0xcc,
  726. 0x8d,0x27,0x4d,0xeb,0x7b,0x6a,0xf8,0xe0,0x44,0x2d,0x7c,0xf6,0xb9,0x71,0x12,0xd8,
  727. 0x61,0x60,0x5b,0x1f,0xa5,0xa3,0xf7,0x4f,0x61,0xe3,0x59,0x67,0x03,0xc2,0xfb,0x56,
  728. 0xed,0x78,0xdb,0x51,
  729. 0xd5,0xbe,0x38,0x07,
  730. 0xe8,0x02,0x00,0x00,
  731. },80);
  732. #endif
  733. bool rv = prime(header, work);
  734. swap32yes(pdata, header, 80 / 4);
  735. return rv;
  736. }