File size: 3,582 Bytes
e462a34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env node
"use strict";
/* Independently written GF(2) cyclic-polynomial exact 10^13-step solver.
   This does NOT share the Python matrix implementation.
   Software test only; no physical quantum or gravity observation.
*/
const fs=require("node:fs"),crypto=require("node:crypto");
const N=81, MASK=(1n<<81n)-1n, STEPS=10000000000000n;
const TAG="ASOLARIA-81-3PHYSICAL-GF2-V1";
const LAWS=[[0,1],[0,2],[0,1,3],[0,4,7],[0,1,5,9]];
const SEATS=["seat-1","seat-2","seat-3"];
const sha=s=>crypto.createHash("sha256").update(s,"ascii").digest("hex");
function chk(b,reason){if(!b)throw Error(reason);}
function challenge(p){
  const c=JSON.parse(fs.readFileSync(p,"utf8"));
  chk(c.schema===TAG,"wrong schema");
  chk(c.steps===Number(STEPS)&&c.waves===12&&c.bodies===81,"wrong horizon");
  chk(JSON.stringify(c.laws)===JSON.stringify(LAWS),"law drift");
  chk(JSON.stringify(Object.keys(c.seat_commitments).sort())===JSON.stringify(SEATS),"needs 3 seats");
  chk(/^[0-9a-f]{32}$/.test(c.nonce),"bad challenge");
  for(const s of SEATS)chk(/^[0-9a-f]{64}$/.test(c.seat_commitments[s]),"bad commitment");
  return c;
}
function rotate(v,k){
  if(k===0)return v&MASK;
  return ((v<<BigInt(k)) | (v>>BigInt(N-k)))&MASK;
}
function convolution(a,b){
  let out=0n,bit=0;
  while(a>0n){
    if(a&1n)out ^= rotate(b,bit);
    a >>= 1n; bit++;
  }
  return out&MASK;
}
function powered(taps,horizon){
  let operator=0n;
  for(const t of taps)operator^=1n<<BigInt(t);
  let out=1n;
  while(horizon>0n){
    if(horizon&1n)out=convolution(out,operator);
    operator=convolution(operator,operator);
    horizon >>= 1n;
  }
  return out;
}
function direct(taps,state){
  let out=0n;
  for(const t of taps)out ^= rotate(state,t);
  return out;
}
function selfTest(){
  for(const taps of LAWS)for(const n of [0,1,2,3,9,21]){
    const poly=powered(taps,BigInt(n));
    for(const body of [0,1,40,80]){
      let slow=1n<<BigInt(body);
      for(let i=0;i<n;i++)slow=direct(taps,slow);
      chk(convolution(poly,1n<<BigInt(body))===slow,"small-step mismatch");
    }
  }
}
function build(c){
  const master=sha(TAG+"|"+c.nonce+"|"+SEATS.map(s=>c.seat_commitments[s]).join("|"));
  const lines=["PORTAL|schema="+TAG+"|nonce="+c.nonce+"|master="+master+
      "|steps="+STEPS+"|laws=5|waves=12|bodies=81|json=0"];
  for(let index=0;index<LAWS.length;index++){
    const op=powered(LAWS[index],STEPS);
    for(let wave=0;wave<12;wave++){
      for(let body=0;body<N;body++){
        const digest=sha(master+"|"+index+"|"+wave+"|"+body);
        const state=(BigInt("0x"+digest)&MASK)^(1n<<BigInt(body));
        const out=convolution(op,state);
        const hex=out.toString(16).padStart(21,"0");
        const check=sha("ASOLARIA|STATE|"+index+"|"+wave+"|"+body+"|"+hex);
        lines.push("WAVE|law="+index+"|wave="+wave+"|body="+body+
          "|state="+hex+"|sha="+check+"|json=0");
      }
    }
  }
  chk(lines.length===4861,"row count mismatch");
  lines.push("END|records=4860|class=EXACT_GF2_DIGITAL_CALCULATION|json=0");
  return Buffer.from(lines.join("\n")+"\n","ascii");
}
function main(){
  const argv=process.argv.slice(2).filter(s=>s!=="--self-test");
  chk(argv.length===2,"usage: node evolve_gf2_node.js challenge.json result.hbp [--self-test]");
  if(process.argv.includes("--self-test"))selfTest();
  const data=build(challenge(argv[0]));
  fs.writeFileSync(argv[1],data);
  console.log(JSON.stringify({status:"PASS",records:4860,
    sha256:crypto.createHash("sha256").update(data).digest("hex"),
    algorithm:"GF2-cyclic-polynomial",steps:Number(STEPS)}));
}
main();