Advertisement
Guest User

Minecraft 1.19 Panorama seedcracking code [by andrew#0858]

a guest
Jun 17th, 2022
804
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.97 KB | None | 0 0
  1. //Minecraft 1.19 Panorama seedcracking code for CUDA
  2. //created by Andrew (andrew#0858) from Minecraft@Home
  3. //https://github.com/Gaider10
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stdint.h>
  8.  
  9. #define QPC_FREQUENCY 10000000
  10.  
  11. __device__ __host__ uint64_t qpc_tick_to_nano_time(uint64_t qpc_tick) {
  12.     return (uint64_t)((double)qpc_tick / (double)QPC_FREQUENCY * (double)1000000000);
  13. }
  14.  
  15. #define DEF_BASE_RANDOM_NEXT_LONG(random_type, random_name) \
  16. __device__ __host__ int64_t random_name##_next_long(random_type *rng) { \
  17.     return ((int64_t)random_name##_next(rng, 32) << 32) + (int64_t)random_name##_next(rng, 32); \
  18. }
  19.  
  20. #define RANDOM_MASK 281474976710655LLU
  21. #define RANDOM_MULTIPLIER 25214903917LLU
  22. #define RANDOM_ADDEND 11LLU
  23.  
  24. __device__ __host__ int32_t random_next(uint64_t *random, int bits) {
  25.     *random = (*random * RANDOM_MULTIPLIER + RANDOM_ADDEND) & RANDOM_MASK;
  26.     return *random >> 48 - bits;
  27. }
  28.  
  29. DEF_BASE_RANDOM_NEXT_LONG(uint64_t, random)
  30.  
  31. __device__ __host__ uint64_t nano_time_to_world_seed(uint64_t nano_time) {
  32.     uint64_t random = (nano_time ^ RANDOM_MULTIPLIER) & RANDOM_MASK;
  33.     return random_next_long(&random);
  34. }
  35.  
  36. #define XRSR_MIX1 0xbf58476d1ce4e5b9ULL
  37. #define XRSR_MIX2 0x94d049bb133111ebULL
  38. #define XRSR_MIX1_INVERSE 0x96de1b173f119089ULL
  39. #define XRSR_MIX2_INVERSE 0x319642b2d24d8ec3ULL
  40. #define XRSR_SILVER_RATIO 0x6a09e667f3bcc909ULL
  41. #define XRSR_GOLDEN_RATIO 0x9e3779b97f4a7c15ULL
  42.  
  43. typedef struct {
  44.     uint64_t lo;
  45.     uint64_t hi;
  46. } Xrsr;
  47.  
  48. __device__ __host__ uint64_t mix64(uint64_t a) {
  49.     a = (a ^ a >> 30) * XRSR_MIX1;
  50.     a = (a ^ a >> 27) * XRSR_MIX2;
  51.     return a ^ a >> 31;
  52. }
  53.  
  54. __device__ __host__ uint64_t fix64(uint64_t a) {
  55.     a = (a ^ a >> 31 ^ a >> 62) * XRSR_MIX2_INVERSE;
  56.     a = (a ^ a >> 27 ^ a >> 54) * XRSR_MIX1_INVERSE;
  57.     return a ^ a >> 30 ^ a >> 60;
  58. }
  59.  
  60. __device__ __host__ void xrsr_seed(Xrsr *xrsr, uint64_t seed) {
  61.     seed ^= XRSR_SILVER_RATIO;
  62.     xrsr->lo = mix64(seed);
  63.     xrsr->hi = mix64(seed + XRSR_GOLDEN_RATIO);
  64. }
  65.  
  66. __device__ __host__ uint64_t rol64(uint64_t a, int bits) {
  67.     return (a << bits) | (a >> 64 - bits);
  68. }
  69.  
  70. __device__ __host__ uint64_t xrsr_next_internal(Xrsr *xrsr) {
  71.     uint64_t l = xrsr->lo;
  72.     uint64_t m = xrsr->hi;
  73.     uint64_t r = rol64(l + m, 17) + l;
  74.     m ^= l;
  75.     xrsr->lo = rol64(l, 49) ^ m ^ m << 21;
  76.     xrsr->hi = rol64(m, 28);
  77.     return r;
  78. }
  79.  
  80. __device__ __host__ int32_t xrsr_next(Xrsr *xrsr, int bits) {
  81.     return (int32_t)(xrsr_next_internal(xrsr) >> (64 - bits));
  82. }
  83.  
  84. DEF_BASE_RANDOM_NEXT_LONG(Xrsr, xrsr)
  85.  
  86. __device__ __host__ void xrsr_set_decoration_seed(Xrsr *xrsr, uint64_t world_seed, int32_t chunk_x, int32_t chunk_z, int32_t index, int32_t step) {
  87.     xrsr_seed(xrsr, world_seed);
  88.     int64_t a = xrsr_next_long(xrsr) | 1LL;
  89.     int64_t b = xrsr_next_long(xrsr) | 1LL;
  90.     xrsr_seed(xrsr, ((a * (chunk_x * 16) + b * (chunk_z * 16)) ^ world_seed) + index + step * 10000);
  91. }
  92.  
  93. __device__ __host__ uint32_t xrsr_next_int_pow2(Xrsr *xrsr, int32_t bits) {
  94.     return (uint32_t)xrsr_next(xrsr, 31) >> (31 - bits);
  95. }
  96.  
  97. __constant__ uint16_t mask_lilypads_inside[16];
  98. // __constant__ uint32_t mask_lilypads_all[32];
  99. __device__ uint64_t found_buffer[1024];
  100. __device__ uint32_t found_count;
  101.  
  102. __global__
  103. void filter_first(uint64_t start) {
  104.     uint32_t index = blockIdx.x * blockDim.x + threadIdx.x;
  105.  
  106.     uint64_t qpc_tick = start | index;
  107.     // uint64_t nano_time = qpc_tick_to_nano_time(qpc_tick);
  108.     // uint64_t world_seed = nano_time_to_world_seed(nano_time);
  109.     uint64_t world_seed = (uint64_t)(int64_t)(int32_t)(uint32_t)qpc_tick;
  110.     Xrsr xrsr;
  111.     xrsr_set_decoration_seed(&xrsr, world_seed, 238, 34, 55, 9);
  112.  
  113.     // if (qpc_tick == 6527241171) {
  114.     //     printf("QPC MATCHING!!!\n");
  115.     // } else {
  116.     //     return;
  117.     // }
  118.  
  119.     int matching_count = 0;
  120.  
  121.     for (int count = 0; count < 4; count++) {
  122.         uint32_t patch_x = xrsr_next_int_pow2(&xrsr, 4);
  123.         uint32_t patch_z = xrsr_next_int_pow2(&xrsr, 4);
  124.  
  125.         bool patch_on_lilypad = (mask_lilypads_inside[patch_z] >> patch_x) & 1;
  126.  
  127.         for (int attempt = 0; attempt < 10; attempt++) {
  128.             uint32_t x = patch_x + xrsr_next_int_pow2(&xrsr, 3) - xrsr_next_int_pow2(&xrsr, 3);
  129.             uint32_t y = xrsr_next_int_pow2(&xrsr, 2) - xrsr_next_int_pow2(&xrsr, 2);
  130.             uint32_t z = patch_z + xrsr_next_int_pow2(&xrsr, 3) - xrsr_next_int_pow2(&xrsr, 3);
  131.  
  132.             // bool on_lilypad = (mask_lilypads_all[z + 8] >> (x + 8)) & 1;
  133.             bool on_lilypad = x < 16 && z < 16 && (mask_lilypads_inside[z] >> x) & 1;
  134.  
  135.             if (on_lilypad && (y == 0 || (patch_on_lilypad && y == (uint32_t)-1))) {
  136.                 matching_count += 1;
  137.             }
  138.         }
  139.     }
  140.  
  141.     // if (world_seed == ((uint64_t)-4026714142520107754LL)) {
  142.     //     printf("MATCHING COUNT ON SEED: %i\n", matching_count);
  143.     // }
  144.  
  145.     if (matching_count < 8) return;
  146.  
  147.     // if (world_seed == ((uint64_t)-4026714142520107754LL)) {
  148.     //     printf("DIDN'T FILTER OUT THE SEED!!!\n");
  149.     // }
  150.  
  151.     found_buffer[atomicAdd(&found_count, 1)] = world_seed;
  152. }
  153.  
  154. #define cudaCheckError(ans) { gpuAssert((ans), __FILE__, __LINE__); }
  155. inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort = true) {
  156.    if (code != cudaSuccess) {
  157.       fprintf(stderr, "Cuda Error: %s %s %d\n", cudaGetErrorString(code), file, line);
  158.       if (abort) exit(code);
  159.    }
  160. }
  161.  
  162. constexpr uint16_t reverse16(uint16_t v) {
  163.     v = (v & 0xFF00) >> 8 | (v & 0x00FF) << 8;
  164.     v = (v & 0xF0F0) >> 4 | (v & 0x0F0F) << 4;
  165.     v = (v & 0xCCCC) >> 2 | (v & 0x3333) << 2;
  166.     v = (v & 0xAAAA) >> 1 | (v & 0x5555) << 1;
  167.     return v;
  168. }
  169.  
  170. // look down facing north
  171. const uint16_t mask_lilypads_inside_host[16] = {
  172.     reverse16(0b0000000000000000),
  173.     reverse16(0b0000000000001000),
  174.     reverse16(0b0000001000000000),
  175.     reverse16(0b0000000000000100),
  176.     reverse16(0b0000001010000000),
  177.     reverse16(0b0000000000000000),
  178.     reverse16(0b0000000000100000),
  179.     reverse16(0b0000000000010000),
  180.     reverse16(0b0100011000000000),
  181.     reverse16(0b0000000000000000),
  182.     reverse16(0b0000000000000000),
  183.     reverse16(0b0000000000000000),
  184.     reverse16(0b0000100000000000),
  185.     reverse16(0b1000100000000000),
  186.     reverse16(0b0000000000000000),
  187.     reverse16(0b0000000000000000),
  188. };
  189. // const uint32_t mask_lilypads_all_host[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0b00000000000111111111100000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  190.  
  191. void init_constants() {
  192.     cudaCheckError( cudaMemcpyToSymbol(mask_lilypads_inside, mask_lilypads_inside_host, sizeof(mask_lilypads_inside_host)) );
  193.     // cudaCheckError( cudaMemcpyToSymbol(mask_lilypads_all, mask_lilypads_all_host, sizeof(mask_lilypads_all_host)) );
  194. }
  195.  
  196. constexpr uint32_t reverse32(uint32_t v) {
  197.     v = (v & 0xFFFF0000) >> 16 | (v & 0x0000FFFF) << 16;
  198.     v = (v & 0xFF00FF00) >>  8 | (v & 0x00FF00FF) <<  8;
  199.     v = (v & 0xF0F0F0F0) >>  4 | (v & 0x0F0F0F0F) <<  4;
  200.     v = (v & 0xCCCCCCCC) >>  2 | (v & 0x33333333) <<  2;
  201.     v = (v & 0xAAAAAAAA) >>  1 | (v & 0x55555555) <<  1;
  202.     return v;
  203. }
  204.  
  205. const uint32_t mask_lilypads_combined_host[16] = {
  206.     reverse32(0b00000000000000000000000000000000),
  207.     reverse32(0b00000000000000000000000000001000),
  208.     reverse32(0b00000000000000000000001000000000),
  209.     reverse32(0b00000000000000000000000000000100),
  210.     reverse32(0b00000000000000010000001010000000),
  211.     reverse32(0b00000000000011000000000000000000),
  212.     reverse32(0b00000100000100000000000000100000),
  213.     reverse32(0b00000000010000000000000000010000),
  214.     reverse32(0b00000000000000000100011000000000),
  215.     reverse32(0b00000000000000000000000000000000),
  216.     reverse32(0b00000000000001000000000000000000),
  217.     reverse32(0b00000000000000000000000000000000),
  218.     reverse32(0b00000000000000100000100000000000),
  219.     reverse32(0b00000000000000001000100000000000),
  220.     reverse32(0b00000000000000000000000000000000),
  221.     reverse32(0b00000000000001000000000000000000),
  222. };
  223.  
  224. bool test_2_host(uint64_t world_seed) {
  225.     int matching_count = 0;
  226.  
  227.     Xrsr xrsr;
  228.  
  229.     uint32_t generated[16] = { 0 };
  230.  
  231.     xrsr_set_decoration_seed(&xrsr, world_seed, 237, 34, 55, 9);
  232.     for (int count = 0; count < 4; count++) {
  233.         uint32_t patch_x = xrsr_next_int_pow2(&xrsr, 4);
  234.         uint32_t patch_z = xrsr_next_int_pow2(&xrsr, 4);
  235.  
  236.         bool patch_on_lilypad = (mask_lilypads_combined_host[patch_z] >> patch_x) & 1;
  237.  
  238.         for (int attempt = 0; attempt < 10; attempt++) {
  239.             uint32_t x = patch_x + xrsr_next_int_pow2(&xrsr, 3) - xrsr_next_int_pow2(&xrsr, 3);
  240.             uint32_t y = xrsr_next_int_pow2(&xrsr, 2) - xrsr_next_int_pow2(&xrsr, 2);
  241.             uint32_t z = patch_z + xrsr_next_int_pow2(&xrsr, 3) - xrsr_next_int_pow2(&xrsr, 3);
  242.  
  243.             if (x < 32 && z < 16) {
  244.                 if (!((generated[z] >> x) & 1)) {
  245.                     bool on_lilypad = (mask_lilypads_combined_host[z] >> x) & 1;
  246.                     if (on_lilypad && (y == 0 || (patch_on_lilypad && y == (uint32_t)-1))) {
  247.                         matching_count += 1;
  248.                         generated[z] |= 1 << x;
  249.                     }
  250.                 }
  251.             }
  252.         }
  253.     }
  254.  
  255.     xrsr_set_decoration_seed(&xrsr, world_seed, 238, 34, 55, 9);
  256.     for (int count = 0; count < 4; count++) {
  257.         uint32_t patch_x = xrsr_next_int_pow2(&xrsr, 4) + 16;
  258.         uint32_t patch_z = xrsr_next_int_pow2(&xrsr, 4);
  259.  
  260.         bool patch_on_lilypad = (mask_lilypads_combined_host[patch_z] >> patch_x) & 1;
  261.  
  262.         for (int attempt = 0; attempt < 10; attempt++) {
  263.             uint32_t x = patch_x + xrsr_next_int_pow2(&xrsr, 3) - xrsr_next_int_pow2(&xrsr, 3);
  264.             uint32_t y = xrsr_next_int_pow2(&xrsr, 2) - xrsr_next_int_pow2(&xrsr, 2);
  265.             uint32_t z = patch_z + xrsr_next_int_pow2(&xrsr, 3) - xrsr_next_int_pow2(&xrsr, 3);
  266.  
  267.             if (x < 32 && z < 16) {
  268.                 if (!((generated[z] >> x) & 1)) {
  269.                     bool on_lilypad = (mask_lilypads_combined_host[z] >> x) & 1;
  270.                     if (on_lilypad && (y == 0 || (patch_on_lilypad && y == (uint32_t)-1))) {
  271.                         matching_count += 1;
  272.                         generated[z] |= 1 << x;
  273.                     }
  274.                 }
  275.             }
  276.         }
  277.     }
  278.  
  279.     return matching_count >= 14;
  280. }
  281.  
  282. uint32_t found_count_host = 0;
  283. uint64_t found_buffer_host[1024];
  284.  
  285. #define COUNT(BITS) (1LLU << (BITS))
  286.  
  287. #define BLOCK_BITS 20
  288. #define BLOCK_COUNT COUNT(BLOCK_BITS)
  289. #define THREAD_BITS 8
  290. #define THREAD_COUNT COUNT(THREAD_BITS)
  291. #define RUN_BITS (BLOCK_BITS + THREAD_BITS)
  292. #define RUN_COUNT COUNT(RUN_BITS)
  293.  
  294. int main() {
  295.     init_constants();
  296.  
  297.     FILE *out = fopen("out.txt", "w");
  298.  
  299.     uint64_t start = 0;
  300.     const uint64_t end = COUNT(42);
  301.     while (start < end) {
  302.         clock_t clock_start = clock();
  303.  
  304.         found_count_host = 0;
  305.         cudaMemcpyToSymbol(found_count, &found_count_host, sizeof(found_count_host));
  306.  
  307.         filter_first<<<BLOCK_COUNT, THREAD_COUNT>>>(start);
  308.         cudaCheckError( cudaGetLastError() );
  309.         cudaCheckError( cudaDeviceSynchronize() );
  310.  
  311.         cudaMemcpyFromSymbol(&found_count_host, found_count, sizeof(found_count_host));
  312.         cudaMemcpyFromSymbol(&found_buffer_host, found_buffer, sizeof(uint64_t) * found_count_host);
  313.  
  314.         start += RUN_COUNT;
  315.  
  316.         clock_t clock_end = clock();
  317.  
  318.         // printf("Matching test 1 count: %i\n", found_count_host);
  319.         for (uint32_t i = 0; i < found_count_host; i++) {
  320.             uint64_t world_seed = found_buffer_host[i];
  321.             if (test_2_host(world_seed)) {
  322.                 printf("Matching test 2 seed: %lli\n", (int64_t)world_seed);
  323.                 fprintf(out, "%lli\n", (int64_t)world_seed);
  324.             }
  325.         }
  326.  
  327.         if (start % COUNT(32) == 0) {
  328.             double progress = (double)start / end;
  329.             double elapsed = (double)(clock_end - clock_start) / CLOCKS_PER_SEC;
  330.             printf("%fs %f%% %fM/s\n", elapsed, progress * 100, RUN_COUNT / elapsed / 1000000);
  331.         }
  332.     }
  333.  
  334.     return 0;
  335. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement