nano-pow 3.1.3 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +169 -0
- package/dist/main.min.js +177 -328
- package/dist/types.d.ts +105 -4
- package/docs/benchmarks.md +98 -0
- package/package.json +10 -8
- package/dist/cli.js +0 -185
- /package/{dist → docs}/nano-pow.1 +0 -0
package/dist/main.min.js
CHANGED
|
@@ -1,307 +1,48 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var compute_default = "struct UBO{blockhash:array<vec4<u32>,2>,seed:vec2<u32>,threshold:u32};@group(0)@binding(0)var<uniform> ubo:UBO;struct WORK{found:atomic<u32>,nonce:vec2<u32>,result:vec2<u32>};@group(0)@binding(1)var<storage,read_write>work:WORK;const BLAKE2B_IV=array<vec2<u32>,8>(vec2<u32>(0xF3BCC908u,0x6A09E667u),vec2<u32>(0x84CAA73Bu,0xBB67AE85u),vec2<u32>(0xFE94F82Bu,0x3C6EF372u),vec2<u32>(0x5F1D36F1u,0xA54FF53Au),vec2<u32>(0xADE682D1u,0x510E527Fu),vec2<u32>(0x2B3E6C1Fu,0x9B05688Cu),vec2<u32>(0xFB41BD6Bu,0x1F83D9ABu),vec2<u32>(0x137E2179u,0x5BE0CD19u));const BLAKE2B_PARAM=vec2<u32>(0x01010008u,0u);const BLAKE2B_INLEN=vec2<u32>(0x00000028u,0u);const BLAKE2B_FINAL=vec2<u32>(0xFFFFFFFFu,0xFFFFFFFFu);const BLAKE2B_INIT=array<vec2<u32>,16>(BLAKE2B_IV[0u]^ BLAKE2B_PARAM,BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u],BLAKE2B_IV[5u],BLAKE2B_IV[6u],BLAKE2B_IV[7u],BLAKE2B_IV[0u],BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u]^ BLAKE2B_INLEN,BLAKE2B_IV[5u],BLAKE2B_IV[6u]^ BLAKE2B_FINAL,BLAKE2B_IV[7u]);const Z=vec2(0u);const CARRY=vec4(1u,0u,1u,0u);const ROTATE_1=vec4(1u);const ROTATE_8=vec4(8u);const ROTATE_16=vec4(16u);const ROTATE_24=vec4(24u);const ROTATE_31=vec4(31u);var<workgroup> found:bool;@compute @workgroup_size(32)fn search(@builtin(global_invocation_id)global_id:vec3<u32>,@builtin(local_invocation_id)local_id:vec3<u32>){found=(local_id.x==0u&&atomicLoad(&work.found)!=0u);workgroupBarrier();if(found){return;}main(global_id);}@compute @workgroup_size(1)fn validate(@builtin(global_invocation_id)global_id:vec3<u32>){main(global_id);}fn main(id:vec3<u32>){let m0:vec2<u32>=ubo.seed ^ id.xy;let m1:vec2<u32>=ubo.blockhash[0u].xy;let m2:vec2<u32>=ubo.blockhash[0u].zw;let m3:vec2<u32>=ubo.blockhash[1u].xy;let m4:vec2<u32>=ubo.blockhash[1u].zw;var v01:vec4<u32>=vec4<u32>(BLAKE2B_INIT[0u],BLAKE2B_INIT[1u]);var v23:vec4<u32>=vec4<u32>(BLAKE2B_INIT[2u],BLAKE2B_INIT[3u]);var v45:vec4<u32>=vec4<u32>(BLAKE2B_INIT[4u],BLAKE2B_INIT[5u]);var v67:vec4<u32>=vec4<u32>(BLAKE2B_INIT[6u],BLAKE2B_INIT[7u]);var v89:vec4<u32>=vec4<u32>(BLAKE2B_INIT[8u],BLAKE2B_INIT[9u]);var vAB:vec4<u32>=vec4<u32>(BLAKE2B_INIT[10u],BLAKE2B_INIT[11u]);var vCD:vec4<u32>=vec4<u32>(BLAKE2B_INIT[12u],BLAKE2B_INIT[13u]);var vEF:vec4<u32>=vec4<u32>(BLAKE2B_INIT[14u],BLAKE2B_INIT[15u]);var v56:vec4<u32>;var vFC:vec4<u32>;var v74:vec4<u32>;var vDE:vec4<u32>;var s0:vec4<u32>;var s1:vec4<u32>;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m0,m2);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;v23+=vec4(m4,Z);v23.y+=u32(v23.x<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m3);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m4);v01.w+=u32(v01.z<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m2);v01.w+=u32(v01.z<m2.x);v23+=vec4(Z,m3);v23.w+=u32(v23.z<m3.x);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(Z,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01.z+=m3.x;v01.w+=m3.y+u32(v01.z<m3.x);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,m4)+vec4(0u,u32(v23.x+vec4(m1,m4).x<v23.x),0u,u32(v23.z+vec4(m1,m4).z<v23.z));vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m3)+vec4(Z,0u,u32(v01.z+vec4(Z,m3).z<v01.z));vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m1)+vec4(Z,0u,u32(v01.z+vec4(Z,m1).z<v01.z));vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m0,Z)+vec4(0u,u32(v23.x+vec4(m0,Z).x<v23.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,Z)+vec4(0u,u32(v01.x+vec4(m0,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m1,Z)+vec4(0u,u32(v01.x+vec4(m1,Z).x<v01.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m0,Z)+vec4(0u,u32(v23.x+vec4(m0,Z).x<v23.x),Z);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m4,Z)+vec4(0u,u32(v01.x+vec4(m4,Z).x<v01.x),Z);v23+=vec4(Z,m1)+vec4(Z,0u,u32(v23.z+vec4(Z,m1).z<v23.z));vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m1)+vec4(Z,0u,u32(v01.z+vec4(Z,m1).z<v01.z));v23+=vec4(Z,m4)+vec4(Z,0u,u32(v23.z+vec4(Z,m4).z<v23.z));vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,Z)+vec4(0u,u32(v01.x+vec4(m0,Z).x<v01.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m3)+vec4(Z,0u,u32(v01.z+vec4(Z,m3).z<v01.z));s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,Z)+vec4(0u,u32(v23.x+vec4(m1,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m2)+vec4(Z,0u,u32(v23.z+vec4(Z,m2).z<v23.z));vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,m4)+vec4(0u,u32(v01.x+vec4(m0,m4).x<v01.x),0u,u32(v01.z+vec4(m0,m4).z<v01.z));vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m0);v23.w+=u32(v23.z<m0.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m3,Z)+vec4(0u,u32(v23.x+vec4(m3,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,Z)+vec4(0u,u32(v23.x+vec4(m1,Z).x<v23.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m1);v23.w+=u32(v23.z<m1.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m2,m4);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m3,Z);v23.y+=u32(v23.x<m3.x);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m0);v23.w+=u32(v23.z<m0.x);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m0,m2);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;v23+=vec4(m4,Z);v23.y+=u32(v23.x<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m3);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m4);v01.w+=u32(v01.z<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m3);v23.w+=u32(v23.z<m3.x);vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;if((BLAKE2B_INIT[0u].y ^ v01.y ^ v89.y)>=ubo.threshold&&atomicLoad(&work.found)==0u){atomicStore(&work.found,1u);work.nonce=m0;work.result=(BLAKE2B_INIT[0u]^ v01.xy ^ v89.xy);}return;}";
|
|
5
|
-
|
|
6
|
-
// src/shaders/gl-downsample.ts
|
|
1
|
+
// src/lib/gl/gl-downsample.frag
|
|
2
|
+
var gl_downsample_default = `#version 300 es
|
|
3
|
+
#pragma vscode_glsllint_stage: frag
|
|
7
4
|
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
8
5
|
//! SPDX-License-Identifier: GPL-3.0-or-later
|
|
9
|
-
var NanoPowGlDownsampleShader = `#version 300 es
|
|
10
|
-
#pragma vscode_glsllint_stage: frag
|
|
11
6
|
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
12
7
|
precision highp float;
|
|
13
8
|
#else
|
|
14
9
|
precision mediump float;
|
|
15
10
|
#endif
|
|
16
|
-
precision highp int;
|
|
17
|
-
|
|
18
|
-
out uvec4 nonce;
|
|
19
|
-
|
|
20
|
-
// source texture to be downsampled
|
|
21
|
-
uniform highp usampler2D src;
|
|
11
|
+
precision highp int;out uvec4 nonce;uniform highp usampler2D src;void main(){nonce=uvec4(0u);vec2 inputSize=vec2(textureSize(src,0));vec2 texel=vec2(1.0)/inputSize;vec2 blockCoord=(floor(gl_FragCoord.xy)*2.0+vec2(0.5))/inputSize;uvec4 pixel=texture(src,blockCoord);nonce=pixel.x==0u?nonce:pixel;pixel=texture(src,blockCoord+vec2(texel.x,0.0));nonce=pixel.x==0u?nonce:pixel;pixel=texture(src,blockCoord+vec2(0.0,texel.y));nonce=pixel.x==0u?nonce:pixel;pixel=texture(src,blockCoord+vec2(texel.x,texel.y));nonce=pixel.x==0u?nonce:pixel;}`;
|
|
22
12
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
vec2 texel = vec2(1.0) / inputSize;
|
|
27
|
-
vec2 blockCoord = (floor(gl_FragCoord.xy) * 2.0 + vec2(0.5)) / inputSize;
|
|
28
|
-
|
|
29
|
-
uvec4 pixel = texture(src, blockCoord);
|
|
30
|
-
nonce = pixel.x == 0u ? nonce : pixel;
|
|
31
|
-
|
|
32
|
-
pixel = texture(src, blockCoord + vec2(texel.x, 0.0));
|
|
33
|
-
nonce = pixel.x == 0u ? nonce : pixel;
|
|
34
|
-
|
|
35
|
-
pixel = texture(src, blockCoord + vec2(0.0, texel.y));
|
|
36
|
-
nonce = pixel.x == 0u ? nonce : pixel;
|
|
37
|
-
|
|
38
|
-
pixel = texture(src, blockCoord + vec2(texel.x, texel.y));
|
|
39
|
-
nonce = pixel.x == 0u ? nonce : pixel;
|
|
40
|
-
}
|
|
41
|
-
`;
|
|
42
|
-
|
|
43
|
-
// src/shaders/gl-draw.ts
|
|
13
|
+
// src/lib/gl/gl-draw.frag
|
|
14
|
+
var gl_draw_default = `#version 300 es
|
|
15
|
+
#pragma vscode_glsllint_stage: frag
|
|
44
16
|
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
45
17
|
//! SPDX-FileContributor: Ben Green <ben@latenightsketches.com>
|
|
46
18
|
//! SPDX-License-Identifier: GPL-3.0-or-later AND MIT
|
|
47
|
-
var NanoPowGlDrawShader = `#version 300 es
|
|
48
|
-
#pragma vscode_glsllint_stage: frag
|
|
49
19
|
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
50
20
|
precision highp float;
|
|
51
21
|
#else
|
|
52
22
|
precision mediump float;
|
|
53
23
|
#endif
|
|
24
|
+
out uvec4 nonce;layout(std140)uniform UBO{uint blockhash[8];uvec2 threshold;bool validate;};layout(std140)uniform WORK{uvec2 seed;};const uvec2 BLAKE2B_IV[8]=uvec2[8](uvec2(0xF3BCC908u,0x6A09E667u),uvec2(0x84CAA73Bu,0xBB67AE85u),uvec2(0xFE94F82Bu,0x3C6EF372u),uvec2(0x5F1D36F1u,0xA54FF53Au),uvec2(0xADE682D1u,0x510E527Fu),uvec2(0x2B3E6C1Fu,0x9B05688Cu),uvec2(0xFB41BD6Bu,0x1F83D9ABu),uvec2(0x137E2179u,0x5BE0CD19u));const uvec2 BLAKE2B_PARAM=uvec2(0x01010008u,0u);const uvec2 BLAKE2B_INLEN=uvec2(0x00000028u,0u);const uvec2 BLAKE2B_FINAL=uvec2(0xFFFFFFFFu,0xFFFFFFFFu);const uvec2 BLAKE2B_INIT[16]=uvec2[16](BLAKE2B_IV[0u]^ BLAKE2B_PARAM,BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u],BLAKE2B_IV[5u],BLAKE2B_IV[6u],BLAKE2B_IV[7u],BLAKE2B_IV[0u],BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u]^ BLAKE2B_INLEN,BLAKE2B_IV[5u],BLAKE2B_IV[6u]^ BLAKE2B_FINAL,BLAKE2B_IV[7u]);const uint BLAKE2B_IV32_1=0x6A09E667u;const uvec4 ROTATE_1=uvec4(1u);const uvec4 ROTATE_8=uvec4(8u);const uvec4 ROTATE_16=uvec4(16u);const uvec4 ROTATE_24=uvec4(24u);const uvec4 ROTATE_31=uvec4(31u);uvec2 v[16];uvec2 m[16];void G(uint a0,uint b0,uint c0,uint d0,uvec2 x0,uvec2 y0,uint a1,uint b1,uint c1,uint d1,uvec2 x1,uvec2 y1){uvec4 a=uvec4(v[a0],v[a1]);uvec4 b=uvec4(v[b0],v[b1]);uvec4 c=uvec4(v[c0],v[c1]);uvec4 d=uvec4(v[d0],v[d1]);uvec4 mx=uvec4(x0,x1);uvec4 my=uvec4(y0,y1);a=a+b+uvec4(0u,uint(a.x+b.x<a.x),0u,uint(a.z+b.z<a.z));a=a+mx+uvec4(0u,uint(a.x+mx.x<a.x),0u,uint(a.z+mx.z<a.z));d=(d ^ a).yxwz;c=c+d+uvec4(0u,uint(c.x+d.x<c.x),0u,uint(c.z+d.z<c.z));b=((b ^ c)>>ROTATE_24)|((b ^ c)<<ROTATE_8).yxwz;a=a+b+uvec4(0u,uint(a.x+b.x<b.x),0u,uint(a.z+b.z<b.z));a=a+my+uvec4(0u,uint(a.x+my.x<a.x),0u,uint(a.z+my.z<a.z));d=((d ^ a)>>ROTATE_16)|((d ^ a)<<ROTATE_16).yxwz;c=c+d+uvec4(0u,uint(c.x+d.x<c.x),0u,uint(c.z+d.z<c.z));b=((b ^ c)>>ROTATE_31).yxwz|((b ^ c)<<ROTATE_1);v[a0]=a.xy;v[b0]=b.xy;v[c0]=c.xy;v[d0]=d.xy;v[a1]=a.zw;v[b1]=b.zw;v[c1]=c.zw;v[d1]=d.zw;}void main(){nonce=uvec4(0u);m[0u]=seed ^ uvec2(gl_FragCoord);m[1u]=uvec2(blockhash[0u],blockhash[1u]);m[2u]=uvec2(blockhash[2u],blockhash[3u]);m[3u]=uvec2(blockhash[4u],blockhash[5u]);m[4u]=uvec2(blockhash[6u],blockhash[7u]);v=BLAKE2B_INIT;G(0u,4u,8u,12u,m[0u],m[1u],1u,5u,9u,13u,m[2u],m[3u]);G(2u,6u,10u,14u,m[4u],m[5u],3u,7u,11u,15u,m[6u],m[7u]);G(0u,5u,10u,15u,m[8u],m[9u],1u,6u,11u,12u,m[10u],m[11u]);G(2u,7u,8u,13u,m[12u],m[13u],3u,4u,9u,14u,m[14u],m[15u]);G(0u,4u,8u,12u,m[14u],m[10u],1u,5u,9u,13u,m[4u],m[8u]);G(2u,6u,10u,14u,m[9u],m[15u],3u,7u,11u,15u,m[13u],m[6u]);G(0u,5u,10u,15u,m[1u],m[12u],1u,6u,11u,12u,m[0u],m[2u]);G(2u,7u,8u,13u,m[11u],m[7u],3u,4u,9u,14u,m[5u],m[3u]);G(0u,4u,8u,12u,m[11u],m[8u],1u,5u,9u,13u,m[12u],m[0u]);G(2u,6u,10u,14u,m[5u],m[2u],3u,7u,11u,15u,m[15u],m[13u]);G(0u,5u,10u,15u,m[10u],m[14u],1u,6u,11u,12u,m[3u],m[6u]);G(2u,7u,8u,13u,m[7u],m[1u],3u,4u,9u,14u,m[9u],m[4u]);G(0u,4u,8u,12u,m[7u],m[9u],1u,5u,9u,13u,m[3u],m[1u]);G(2u,6u,10u,14u,m[13u],m[12u],3u,7u,11u,15u,m[11u],m[14u]);G(0u,5u,10u,15u,m[2u],m[6u],1u,6u,11u,12u,m[5u],m[10u]);G(2u,7u,8u,13u,m[4u],m[0u],3u,4u,9u,14u,m[15u],m[8u]);G(0u,4u,8u,12u,m[9u],m[0u],1u,5u,9u,13u,m[5u],m[7u]);G(2u,6u,10u,14u,m[2u],m[4u],3u,7u,11u,15u,m[10u],m[15u]);G(0u,5u,10u,15u,m[14u],m[1u],1u,6u,11u,12u,m[11u],m[12u]);G(2u,7u,8u,13u,m[6u],m[8u],3u,4u,9u,14u,m[3u],m[13u]);G(0u,4u,8u,12u,m[2u],m[12u],1u,5u,9u,13u,m[6u],m[10u]);G(2u,6u,10u,14u,m[0u],m[11u],3u,7u,11u,15u,m[8u],m[3u]);G(0u,5u,10u,15u,m[4u],m[13u],1u,6u,11u,12u,m[7u],m[5u]);G(2u,7u,8u,13u,m[15u],m[14u],3u,4u,9u,14u,m[1u],m[9u]);G(0u,4u,8u,12u,m[12u],m[5u],1u,5u,9u,13u,m[1u],m[15u]);G(2u,6u,10u,14u,m[14u],m[13u],3u,7u,11u,15u,m[4u],m[10u]);G(0u,5u,10u,15u,m[0u],m[7u],1u,6u,11u,12u,m[6u],m[3u]);G(2u,7u,8u,13u,m[9u],m[2u],3u,4u,9u,14u,m[8u],m[11u]);G(0u,4u,8u,12u,m[13u],m[11u],1u,5u,9u,13u,m[7u],m[14u]);G(2u,6u,10u,14u,m[12u],m[1u],3u,7u,11u,15u,m[3u],m[9u]);G(0u,5u,10u,15u,m[5u],m[0u],1u,6u,11u,12u,m[15u],m[4u]);G(2u,7u,8u,13u,m[8u],m[6u],3u,4u,9u,14u,m[2u],m[10u]);G(0u,4u,8u,12u,m[6u],m[15u],1u,5u,9u,13u,m[14u],m[9u]);G(2u,6u,10u,14u,m[11u],m[3u],3u,7u,11u,15u,m[0u],m[8u]);G(0u,5u,10u,15u,m[12u],m[2u],1u,6u,11u,12u,m[13u],m[7u]);G(2u,7u,8u,13u,m[1u],m[4u],3u,4u,9u,14u,m[10u],m[5u]);G(0u,4u,8u,12u,m[10u],m[2u],1u,5u,9u,13u,m[8u],m[4u]);G(2u,6u,10u,14u,m[7u],m[6u],3u,7u,11u,15u,m[1u],m[5u]);G(0u,5u,10u,15u,m[15u],m[11u],1u,6u,11u,12u,m[9u],m[14u]);G(2u,7u,8u,13u,m[3u],m[12u],3u,4u,9u,14u,m[13u],m[0u]);G(0u,4u,8u,12u,m[0u],m[1u],1u,5u,9u,13u,m[2u],m[3u]);G(2u,6u,10u,14u,m[4u],m[5u],3u,7u,11u,15u,m[6u],m[7u]);G(0u,5u,10u,15u,m[8u],m[9u],1u,6u,11u,12u,m[10u],m[11u]);G(2u,7u,8u,13u,m[12u],m[13u],3u,4u,9u,14u,m[14u],m[15u]);G(0u,4u,8u,12u,m[14u],m[10u],1u,5u,9u,13u,m[4u],m[8u]);G(2u,6u,10u,14u,m[9u],m[15u],3u,7u,11u,15u,m[13u],m[6u]);G(0u,5u,10u,15u,m[1u],m[12u],1u,6u,11u,12u,m[0u],m[2u]);G(2u,7u,8u,13u,m[11u],m[7u],3u,4u,9u,14u,m[5u],m[3u]);uvec2 result=BLAKE2B_INIT[0u]^ v[0u]^ v[8u];if((validate&&uvec2(gl_FragCoord)==uvec2(0u))||(result.y>threshold.y||(result.y==threshold.y&&result.x>threshold.x))){nonce=uvec4((BLAKE2B_INIT[0u]^ v[0u]^ v[8u]),m[0u]).yxwz;}if(nonce.x==0u){discard;}}`;
|
|
54
25
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// blockhash - Array of precalculated block hash components
|
|
58
|
-
// threshold - 0xfffffff8 for send/change blocks, 0xfffffe00 for all else
|
|
59
|
-
// search - Checks all pixels if true, else only checks 1 pixel to validate
|
|
60
|
-
layout(std140) uniform UBO {
|
|
61
|
-
uint blockhash[8];
|
|
62
|
-
uint threshold;
|
|
63
|
-
bool search;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// Random work seed values
|
|
67
|
-
layout(std140) uniform WORK {
|
|
68
|
-
uvec2 seed;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Initialization vector defined by BLAKE2. Each vec2<u32> represents two halves
|
|
73
|
-
* of the original u64 value from the reference implementation. They appear
|
|
74
|
-
* reversed pairwise as defined below, but this is an illusion due to endianness:
|
|
75
|
-
* the \`x\` component of the vector is the low bits and the \`y\` component is the
|
|
76
|
-
* high bits, and if you laid the bits out individually, they would match the
|
|
77
|
-
* little-endian 64-bit representation.
|
|
78
|
-
*/
|
|
79
|
-
const uvec2 BLAKE2B_IV[8] = uvec2[8](
|
|
80
|
-
uvec2(0xF3BCC908u, 0x6A09E667u),
|
|
81
|
-
uvec2(0x84CAA73Bu, 0xBB67AE85u),
|
|
82
|
-
uvec2(0xFE94F82Bu, 0x3C6EF372u),
|
|
83
|
-
uvec2(0x5F1D36F1u, 0xA54FF53Au),
|
|
84
|
-
uvec2(0xADE682D1u, 0x510E527Fu),
|
|
85
|
-
uvec2(0x2B3E6C1Fu, 0x9B05688Cu),
|
|
86
|
-
uvec2(0xFB41BD6Bu, 0x1F83D9ABu),
|
|
87
|
-
uvec2(0x137E2179u, 0x5BE0CD19u)
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Parameter block as defined in BLAKE2 section 2.8 and configured as follows:
|
|
92
|
-
* maximal depth = 1, fanout = 1, digest byte length = 8
|
|
93
|
-
*/
|
|
94
|
-
const uvec2 BLAKE2B_PARAM = uvec2(0x01010008u, 0u);
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Message input length which is always 40 for Nano.
|
|
98
|
-
* 8 nonce bytes + 32 block hash bytes
|
|
99
|
-
*/
|
|
100
|
-
const uvec2 BLAKE2B_INLEN = uvec2(0x00000028u, 0u);
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Finalization flag as defined in BLAKE2 section 2.4 and set to ~0 since this is
|
|
104
|
-
* the final (and only) message block being hashed.
|
|
105
|
-
*/
|
|
106
|
-
const uvec2 BLAKE2B_FINAL = uvec2(0xFFFFFFFFu, 0xFFFFFFFFu);
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Fully initialized state array that is locally copied at each thread start.
|
|
110
|
-
* Application of each XOR is defined by BLAKE2 section 2.4 compression function.
|
|
111
|
-
*/
|
|
112
|
-
const uvec2 BLAKE2B_INIT[16] = uvec2[16](
|
|
113
|
-
BLAKE2B_IV[0u] ^ BLAKE2B_PARAM,
|
|
114
|
-
BLAKE2B_IV[1u],
|
|
115
|
-
BLAKE2B_IV[2u],
|
|
116
|
-
BLAKE2B_IV[3u],
|
|
117
|
-
BLAKE2B_IV[4u],
|
|
118
|
-
BLAKE2B_IV[5u],
|
|
119
|
-
BLAKE2B_IV[6u],
|
|
120
|
-
BLAKE2B_IV[7u],
|
|
121
|
-
BLAKE2B_IV[0u],
|
|
122
|
-
BLAKE2B_IV[1u],
|
|
123
|
-
BLAKE2B_IV[2u],
|
|
124
|
-
BLAKE2B_IV[3u],
|
|
125
|
-
BLAKE2B_IV[4u] ^ BLAKE2B_INLEN,
|
|
126
|
-
BLAKE2B_IV[5u],
|
|
127
|
-
BLAKE2B_IV[6u] ^ BLAKE2B_FINAL,
|
|
128
|
-
BLAKE2B_IV[7u]
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
// Defined separately from uint v[0].y below as the original value is required
|
|
132
|
-
// to calculate the second uint32 of the digest for threshold comparison
|
|
133
|
-
const uint BLAKE2B_IV32_1 = 0x6A09E667u;
|
|
134
|
-
|
|
135
|
-
// Used during G for vector bit rotations
|
|
136
|
-
const uvec4 ROTATE_1 = uvec4(1u);
|
|
137
|
-
const uvec4 ROTATE_8 = uvec4(8u);
|
|
138
|
-
const uvec4 ROTATE_16 = uvec4(16u);
|
|
139
|
-
const uvec4 ROTATE_24 = uvec4(24u);
|
|
140
|
-
const uvec4 ROTATE_31 = uvec4(31u);
|
|
141
|
-
|
|
142
|
-
// Iterated initialization vector
|
|
143
|
-
uvec2 v[16];
|
|
144
|
-
|
|
145
|
-
// Input data buffer
|
|
146
|
-
uvec2 m[16];
|
|
147
|
-
|
|
148
|
-
// G mixing function, compressing two subprocesses into one
|
|
149
|
-
void G (
|
|
150
|
-
uint a0, uint b0, uint c0, uint d0, uvec2 x0, uvec2 y0,
|
|
151
|
-
uint a1, uint b1, uint c1, uint d1, uvec2 x1, uvec2 y1
|
|
152
|
-
) {
|
|
153
|
-
uvec4 a = uvec4(v[a0], v[a1]);
|
|
154
|
-
uvec4 b = uvec4(v[b0], v[b1]);
|
|
155
|
-
uvec4 c = uvec4(v[c0], v[c1]);
|
|
156
|
-
uvec4 d = uvec4(v[d0], v[d1]);
|
|
157
|
-
uvec4 mx = uvec4(x0, x1);
|
|
158
|
-
uvec4 my = uvec4(y0, y1);
|
|
159
|
-
|
|
160
|
-
a = a + b + uvec4(0u, uint(a.x + b.x < a.x), 0u, uint(a.z + b.z < a.z));
|
|
161
|
-
a = a + mx + uvec4(0u, uint(a.x + mx.x < a.x), 0u, uint(a.z + mx.z < a.z));
|
|
162
|
-
d = (d ^ a).yxwz;
|
|
163
|
-
c = c + d + uvec4(0u, uint(c.x + d.x < c.x), 0u, uint(c.z + d.z < c.z));
|
|
164
|
-
b = ((b ^ c) >> ROTATE_24) | ((b ^ c) << ROTATE_8).yxwz;
|
|
165
|
-
a = a + b + uvec4(0u, uint(a.x + b.x < b.x), 0u, uint(a.z + b.z < b.z));
|
|
166
|
-
a = a + my + uvec4(0u, uint(a.x + my.x < a.x), 0u, uint(a.z + my.z < a.z));
|
|
167
|
-
d = ((d ^ a) >> ROTATE_16) | ((d ^ a) << ROTATE_16).yxwz;
|
|
168
|
-
c = c + d + uvec4(0u, uint(c.x + d.x < c.x), 0u, uint(c.z + d.z < c.z));
|
|
169
|
-
b = ((b ^ c) >> ROTATE_31).yxwz | ((b ^ c) << ROTATE_1);
|
|
170
|
-
|
|
171
|
-
v[a0] = a.xy;
|
|
172
|
-
v[b0] = b.xy;
|
|
173
|
-
v[c0] = c.xy;
|
|
174
|
-
v[d0] = d.xy;
|
|
175
|
-
v[a1] = a.zw;
|
|
176
|
-
v[b1] = b.zw;
|
|
177
|
-
v[c1] = c.zw;
|
|
178
|
-
v[d1] = d.zw;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
void main() {
|
|
182
|
-
// Initialize fragment output
|
|
183
|
-
nonce = uvec4(0u);
|
|
184
|
-
|
|
185
|
-
// Nonce uniquely differentiated by pixel location
|
|
186
|
-
m[0u] = seed ^ uvec2(gl_FragCoord);
|
|
187
|
-
|
|
188
|
-
// Block hash
|
|
189
|
-
m[1u] = uvec2(blockhash[0u], blockhash[1u]);
|
|
190
|
-
m[2u] = uvec2(blockhash[2u], blockhash[3u]);
|
|
191
|
-
m[3u] = uvec2(blockhash[4u], blockhash[5u]);
|
|
192
|
-
m[4u] = uvec2(blockhash[6u], blockhash[7u]);
|
|
193
|
-
|
|
194
|
-
// Reset v
|
|
195
|
-
v = BLAKE2B_INIT;
|
|
196
|
-
|
|
197
|
-
// Twelve rounds of G mixing
|
|
198
|
-
|
|
199
|
-
// Round 0
|
|
200
|
-
G(0u, 4u, 8u, 12u, m[0u], m[1u], 1u, 5u, 9u, 13u, m[2u], m[3u]);
|
|
201
|
-
G(2u, 6u, 10u, 14u, m[4u], m[5u], 3u, 7u, 11u, 15u, m[6u], m[7u]);
|
|
202
|
-
G(0u, 5u, 10u, 15u, m[8u], m[9u], 1u, 6u, 11u, 12u, m[10u], m[11u]);
|
|
203
|
-
G(2u, 7u, 8u, 13u, m[12u], m[13u], 3u, 4u, 9u, 14u, m[14u], m[15u]);
|
|
204
|
-
|
|
205
|
-
// Round 1
|
|
206
|
-
G(0u, 4u, 8u, 12u, m[14u], m[10u], 1u, 5u, 9u, 13u, m[4u], m[8u]);
|
|
207
|
-
G(2u, 6u, 10u, 14u, m[9u], m[15u], 3u, 7u, 11u, 15u, m[13u], m[6u]);
|
|
208
|
-
G(0u, 5u, 10u, 15u, m[1u], m[12u], 1u, 6u, 11u, 12u, m[0u], m[2u]);
|
|
209
|
-
G(2u, 7u, 8u, 13u, m[11u], m[7u], 3u, 4u, 9u, 14u, m[5u], m[3u]);
|
|
210
|
-
|
|
211
|
-
// Round 2
|
|
212
|
-
G(0u, 4u, 8u, 12u, m[11u], m[8u], 1u, 5u, 9u, 13u, m[12u], m[0u]);
|
|
213
|
-
G(2u, 6u, 10u, 14u, m[5u], m[2u], 3u, 7u, 11u, 15u, m[15u], m[13u]);
|
|
214
|
-
G(0u, 5u, 10u, 15u, m[10u], m[14u], 1u, 6u, 11u, 12u, m[3u], m[6u]);
|
|
215
|
-
G(2u, 7u, 8u, 13u, m[7u], m[1u], 3u, 4u, 9u, 14u, m[9u], m[4u]);
|
|
216
|
-
|
|
217
|
-
// Round 3
|
|
218
|
-
G(0u, 4u, 8u, 12u, m[7u], m[9u], 1u, 5u, 9u, 13u, m[3u], m[1u]);
|
|
219
|
-
G(2u, 6u, 10u, 14u, m[13u], m[12u], 3u, 7u, 11u, 15u, m[11u], m[14u]);
|
|
220
|
-
G(0u, 5u, 10u, 15u, m[2u], m[6u], 1u, 6u, 11u, 12u, m[5u], m[10u]);
|
|
221
|
-
G(2u, 7u, 8u, 13u, m[4u], m[0u], 3u, 4u, 9u, 14u, m[15u], m[8u]);
|
|
222
|
-
|
|
223
|
-
// Round 4
|
|
224
|
-
G(0u, 4u, 8u, 12u, m[9u], m[0u], 1u, 5u, 9u, 13u, m[5u], m[7u]);
|
|
225
|
-
G(2u, 6u, 10u, 14u, m[2u], m[4u], 3u, 7u, 11u, 15u, m[10u], m[15u]);
|
|
226
|
-
G(0u, 5u, 10u, 15u, m[14u], m[1u], 1u, 6u, 11u, 12u, m[11u], m[12u]);
|
|
227
|
-
G(2u, 7u, 8u, 13u, m[6u], m[8u], 3u, 4u, 9u, 14u, m[3u], m[13u]);
|
|
228
|
-
|
|
229
|
-
// Round 5
|
|
230
|
-
G(0u, 4u, 8u, 12u, m[2u], m[12u], 1u, 5u, 9u, 13u, m[6u], m[10u]);
|
|
231
|
-
G(2u, 6u, 10u, 14u, m[0u], m[11u], 3u, 7u, 11u, 15u, m[8u], m[3u]);
|
|
232
|
-
G(0u, 5u, 10u, 15u, m[4u], m[13u], 1u, 6u, 11u, 12u, m[7u], m[5u]);
|
|
233
|
-
G(2u, 7u, 8u, 13u, m[15u], m[14u], 3u, 4u, 9u, 14u, m[1u], m[9u]);
|
|
234
|
-
|
|
235
|
-
// Round 6
|
|
236
|
-
G(0u, 4u, 8u, 12u, m[12u], m[5u], 1u, 5u, 9u, 13u, m[1u], m[15u]);
|
|
237
|
-
G(2u, 6u, 10u, 14u, m[14u], m[13u], 3u, 7u, 11u, 15u, m[4u], m[10u]);
|
|
238
|
-
G(0u, 5u, 10u, 15u, m[0u], m[7u], 1u, 6u, 11u, 12u, m[6u], m[3u]);
|
|
239
|
-
G(2u, 7u, 8u, 13u, m[9u], m[2u], 3u, 4u, 9u, 14u, m[8u], m[11u]);
|
|
240
|
-
|
|
241
|
-
// Round 7
|
|
242
|
-
G(0u, 4u, 8u, 12u, m[13u], m[11u], 1u, 5u, 9u, 13u, m[7u], m[14u]);
|
|
243
|
-
G(2u, 6u, 10u, 14u, m[12u], m[1u], 3u, 7u, 11u, 15u, m[3u], m[9u]);
|
|
244
|
-
G(0u, 5u, 10u, 15u, m[5u], m[0u], 1u, 6u, 11u, 12u, m[15u], m[4u]);
|
|
245
|
-
G(2u, 7u, 8u, 13u, m[8u], m[6u], 3u, 4u, 9u, 14u, m[2u], m[10u]);
|
|
246
|
-
|
|
247
|
-
// Round 8
|
|
248
|
-
G(0u, 4u, 8u, 12u, m[6u], m[15u], 1u, 5u, 9u, 13u, m[14u], m[9u]);
|
|
249
|
-
G(2u, 6u, 10u, 14u, m[11u], m[3u], 3u, 7u, 11u, 15u, m[0u], m[8u]);
|
|
250
|
-
G(0u, 5u, 10u, 15u, m[12u], m[2u], 1u, 6u, 11u, 12u, m[13u], m[7u]);
|
|
251
|
-
G(2u, 7u, 8u, 13u, m[1u], m[4u], 3u, 4u, 9u, 14u, m[10u], m[5u]);
|
|
252
|
-
|
|
253
|
-
// Round 9
|
|
254
|
-
G(0u, 4u, 8u, 12u, m[10u], m[2u], 1u, 5u, 9u, 13u, m[8u], m[4u]);
|
|
255
|
-
G(2u, 6u, 10u, 14u, m[7u], m[6u], 3u, 7u, 11u, 15u, m[1u], m[5u]);
|
|
256
|
-
G(0u, 5u, 10u, 15u, m[15u], m[11u], 1u, 6u, 11u, 12u, m[9u], m[14u]);
|
|
257
|
-
G(2u, 7u, 8u, 13u, m[3u], m[12u], 3u, 4u, 9u, 14u, m[13u], m[0u]);
|
|
258
|
-
|
|
259
|
-
// Round 10
|
|
260
|
-
G(0u, 4u, 8u, 12u, m[0u], m[1u], 1u, 5u, 9u, 13u, m[2u], m[3u]);
|
|
261
|
-
G(2u, 6u, 10u, 14u, m[4u], m[5u], 3u, 7u, 11u, 15u, m[6u], m[7u]);
|
|
262
|
-
G(0u, 5u, 10u, 15u, m[8u], m[9u], 1u, 6u, 11u, 12u, m[10u], m[11u]);
|
|
263
|
-
G(2u, 7u, 8u, 13u, m[12u], m[13u], 3u, 4u, 9u, 14u, m[14u], m[15u]);
|
|
264
|
-
|
|
265
|
-
// Round 11
|
|
266
|
-
G(0u, 4u, 8u, 12u, m[14u], m[10u], 1u, 5u, 9u, 13u, m[4u], m[8u]);
|
|
267
|
-
G(2u, 6u, 10u, 14u, m[9u], m[15u], 3u, 7u, 11u, 15u, m[13u], m[6u]);
|
|
268
|
-
G(0u, 5u, 10u, 15u, m[1u], m[12u], 1u, 6u, 11u, 12u, m[0u], m[2u]);
|
|
269
|
-
G(2u, 7u, 8u, 13u, m[11u], m[7u], 3u, 4u, 9u, 14u, m[5u], m[3u]);
|
|
270
|
-
|
|
271
|
-
// Pixel data set from work seed values
|
|
272
|
-
// Finalize digest from high bits, low bits can be safely ignored
|
|
273
|
-
if ((BLAKE2B_INIT[0u].y ^ v[0u].y ^ v[8u].y) >= threshold && (search || uvec2(gl_FragCoord) == uvec2(0u))) {
|
|
274
|
-
nonce = uvec4(1u, m[0u].y, m[0u].x, (uint(gl_FragCoord.x) << 16u) | uint(gl_FragCoord.y));
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Valid nonce not found
|
|
278
|
-
if (nonce.x == 0u) {
|
|
279
|
-
discard;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
`;
|
|
283
|
-
|
|
284
|
-
// src/shaders/gl-vertex.ts
|
|
285
|
-
var NanoPowGlVertexShader = `#version 300 es
|
|
26
|
+
// src/lib/gl/gl-vertex.vert
|
|
27
|
+
var gl_vertex_default = `#version 300 es
|
|
286
28
|
#pragma vscode_glsllint_stage: vert
|
|
29
|
+
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
30
|
+
//! SPDX-FileContributor: Ben Green <ben@latenightsketches.com>
|
|
31
|
+
//! SPDX-License-Identifier: GPL-3.0-or-later AND MIT
|
|
287
32
|
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
288
33
|
precision highp float;
|
|
289
34
|
#else
|
|
290
35
|
precision mediump float;
|
|
291
36
|
#endif
|
|
37
|
+
layout(location=0)in vec4 position;void main(){gl_Position=position;}`;
|
|
292
38
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
void main() {
|
|
296
|
-
gl_Position = position;
|
|
297
|
-
}
|
|
298
|
-
`;
|
|
299
|
-
|
|
300
|
-
// src/classes/gl.ts
|
|
39
|
+
// src/lib/gl/index.ts
|
|
301
40
|
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
302
41
|
//! SPDX-FileContributor: Ben Green <ben@latenightsketches.com>
|
|
303
42
|
//! SPDX-License-Identifier: GPL-3.0-or-later AND MIT
|
|
304
43
|
var NanoPowGl = class _NanoPowGl {
|
|
44
|
+
static #SEND = 0xfffffff800000000n;
|
|
45
|
+
static #RECEIVE = 0xfffffe0000000000n;
|
|
305
46
|
static #busy = false;
|
|
306
47
|
static #debug = false;
|
|
307
48
|
static #raf = 0;
|
|
@@ -309,8 +50,9 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
309
50
|
static #cores = Math.max(1, Math.floor(navigator.hardwareConcurrency));
|
|
310
51
|
static #WORKLOAD = 256 * this.#cores;
|
|
311
52
|
static #canvas;
|
|
53
|
+
/** Drawing buffer size in pixels. */
|
|
312
54
|
static get size() {
|
|
313
|
-
return this.#gl?.drawingBufferWidth;
|
|
55
|
+
return (this.#gl?.drawingBufferWidth ?? 0) * (this.#gl?.drawingBufferHeight ?? 0);
|
|
314
56
|
}
|
|
315
57
|
static #gl;
|
|
316
58
|
static #drawProgram;
|
|
@@ -328,7 +70,7 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
328
70
|
static #seed = new BigUint64Array(1);
|
|
329
71
|
static #query;
|
|
330
72
|
static #pixels;
|
|
331
|
-
/**Vertex
|
|
73
|
+
/** Vertex positions for fullscreen quad. */
|
|
332
74
|
static #positions = new Float32Array([
|
|
333
75
|
-1,
|
|
334
76
|
-1,
|
|
@@ -339,7 +81,10 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
339
81
|
-1,
|
|
340
82
|
1
|
|
341
83
|
]);
|
|
342
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Constructs canvas, gets WebGL context, initializes buffers, and compiles
|
|
86
|
+
* shaders.
|
|
87
|
+
*/
|
|
343
88
|
static async init() {
|
|
344
89
|
if (this.#busy) return;
|
|
345
90
|
this.#busy = true;
|
|
@@ -360,13 +105,13 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
360
105
|
if (this.#drawProgram == null) throw new Error("Failed to create shader program");
|
|
361
106
|
this.#vertexShader = this.#gl.createShader(this.#gl.VERTEX_SHADER);
|
|
362
107
|
if (this.#vertexShader == null) throw new Error("Failed to create vertex shader");
|
|
363
|
-
this.#gl.shaderSource(this.#vertexShader,
|
|
108
|
+
this.#gl.shaderSource(this.#vertexShader, gl_vertex_default);
|
|
364
109
|
this.#gl.compileShader(this.#vertexShader);
|
|
365
110
|
if (!this.#gl.getShaderParameter(this.#vertexShader, this.#gl.COMPILE_STATUS))
|
|
366
111
|
throw new Error(this.#gl.getShaderInfoLog(this.#vertexShader) ?? `Failed to compile vertex shader`);
|
|
367
112
|
this.#drawShader = this.#gl.createShader(this.#gl.FRAGMENT_SHADER);
|
|
368
113
|
if (this.#drawShader == null) throw new Error("Failed to create fragment shader");
|
|
369
|
-
this.#gl.shaderSource(this.#drawShader,
|
|
114
|
+
this.#gl.shaderSource(this.#drawShader, gl_draw_default);
|
|
370
115
|
this.#gl.compileShader(this.#drawShader);
|
|
371
116
|
if (!this.#gl.getShaderParameter(this.#drawShader, this.#gl.COMPILE_STATUS))
|
|
372
117
|
throw new Error(this.#gl.getShaderInfoLog(this.#drawShader) ?? `Failed to compile fragment shader`);
|
|
@@ -379,7 +124,7 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
379
124
|
if (this.#downsampleProgram == null) throw new Error("Failed to create downsample program");
|
|
380
125
|
this.#downsampleShader = this.#gl.createShader(this.#gl.FRAGMENT_SHADER);
|
|
381
126
|
if (this.#downsampleShader == null) throw new Error("Failed to create downsample shader");
|
|
382
|
-
this.#gl.shaderSource(this.#downsampleShader,
|
|
127
|
+
this.#gl.shaderSource(this.#downsampleShader, gl_downsample_default);
|
|
383
128
|
this.#gl.compileShader(this.#downsampleShader);
|
|
384
129
|
if (!this.#gl.getShaderParameter(this.#downsampleShader, this.#gl.COMPILE_STATUS))
|
|
385
130
|
throw new Error(this.#gl.getShaderInfoLog(this.#downsampleShader) ?? `Failed to compile downsample shader`);
|
|
@@ -441,14 +186,18 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
441
186
|
this.#gl.uniformBlockBinding(this.#drawProgram, this.#gl.getUniformBlockIndex(this.#drawProgram, "WORK"), 1);
|
|
442
187
|
this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null);
|
|
443
188
|
this.#query = this.#gl.createQuery();
|
|
444
|
-
this.#pixels = new Uint32Array(this
|
|
445
|
-
console.log(`NanoPow WebGL initialized at ${this.#gl.drawingBufferWidth}x${this.#gl.drawingBufferHeight}. Maximum nonces checked per frame: ${this
|
|
189
|
+
this.#pixels = new Uint32Array(this.size * 4);
|
|
190
|
+
console.log(`NanoPow WebGL initialized at ${this.#gl.drawingBufferWidth}x${this.#gl.drawingBufferHeight}. Maximum nonces checked per frame: ${this.size}`);
|
|
446
191
|
} catch (err) {
|
|
447
192
|
throw new Error("WebGL initialization failed.", { cause: err });
|
|
448
193
|
} finally {
|
|
449
194
|
this.#busy = false;
|
|
450
195
|
}
|
|
451
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* On WebGL context loss, attempts to clear all program variables and then
|
|
199
|
+
* reinitialize them by calling `init()`.
|
|
200
|
+
*/
|
|
452
201
|
static reset() {
|
|
453
202
|
cancelAnimationFrame(_NanoPowGl.#raf);
|
|
454
203
|
_NanoPowGl.#gl?.deleteQuery(_NanoPowGl.#query);
|
|
@@ -579,9 +328,15 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
579
328
|
for (let i = 0; i < pixelCount; i += 4) {
|
|
580
329
|
if (this.#pixels[i] !== 0) {
|
|
581
330
|
if (this.#debug) console.log(`readResults (${performance.now() - start} ms)`);
|
|
582
|
-
if (this.#debug) console.log(`Pixel: rgba(${this.#pixels[i]}, ${this.#pixels[i + 1]}, ${this.#pixels[i + 2]}, ${this.#pixels[i + 3]
|
|
583
|
-
const
|
|
584
|
-
|
|
331
|
+
if (this.#debug) console.log(`Pixel: rgba(${this.#pixels[i]}, ${this.#pixels[i + 1]}, ${this.#pixels[i + 2]}, ${this.#pixels[i + 3]})`);
|
|
332
|
+
const result = `${this.#pixels[i].toString(16).padStart(8, "0")}${this.#pixels[i + 1].toString(16).padStart(8, "0")}`;
|
|
333
|
+
const nonce = `${this.#pixels[i + 2].toString(16).padStart(8, "0")}${this.#pixels[i + 3].toString(16).padStart(8, "0")}`;
|
|
334
|
+
if (workHex == null || workHex == nonce) {
|
|
335
|
+
return {
|
|
336
|
+
result: BigInt(`0x${result}`),
|
|
337
|
+
nonce: BigInt(`0x${nonce}`)
|
|
338
|
+
};
|
|
339
|
+
}
|
|
585
340
|
}
|
|
586
341
|
}
|
|
587
342
|
throw new Error("Query reported result but nonce value not found");
|
|
@@ -590,26 +345,39 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
590
345
|
* Finds a nonce that satisfies the Nano proof-of-work requirements.
|
|
591
346
|
*
|
|
592
347
|
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
593
|
-
* @param {NanoPowOptions} options -
|
|
348
|
+
* @param {NanoPowOptions} options - Used to configure search execution
|
|
594
349
|
*/
|
|
595
350
|
static async search(hash, options) {
|
|
351
|
+
if (options?.threshold != null) {
|
|
352
|
+
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
353
|
+
}
|
|
354
|
+
const result = await this.work_generate(hash, options);
|
|
355
|
+
return result.work;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Finds a nonce that satisfies the Nano proof-of-work requirements.
|
|
359
|
+
*
|
|
360
|
+
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
361
|
+
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
362
|
+
*/
|
|
363
|
+
static async work_generate(hash, options) {
|
|
596
364
|
if (this.#busy) {
|
|
597
365
|
console.log("NanoPowGl is busy. Retrying search...");
|
|
598
366
|
return new Promise((resolve) => {
|
|
599
367
|
setTimeout(async () => {
|
|
600
|
-
const
|
|
601
|
-
resolve(
|
|
368
|
+
const result2 = this.work_generate(hash, options);
|
|
369
|
+
resolve(result2);
|
|
602
370
|
}, 100);
|
|
603
371
|
});
|
|
604
372
|
}
|
|
605
373
|
this.#busy = true;
|
|
606
374
|
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new Error(`Invalid hash ${hash}`);
|
|
607
|
-
const threshold = typeof options?.threshold !== "
|
|
375
|
+
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
608
376
|
const effort = typeof options?.effort !== "number" || options.effort < 1 || options.effort > 32 ? this.#cores : options.effort;
|
|
609
377
|
this.#debug = !!options?.debug;
|
|
610
378
|
if (this.#debug) console.log("NanoPowGl.search()");
|
|
611
379
|
if (this.#debug) console.log("blockhash", hash);
|
|
612
|
-
if (this.#debug) console.log("search options", JSON.stringify(options));
|
|
380
|
+
if (this.#debug) console.log("search options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
613
381
|
if (this.#WORKLOAD !== 256 * effort) {
|
|
614
382
|
this.#WORKLOAD = 256 * effort;
|
|
615
383
|
this.#canvas.height = this.#WORKLOAD;
|
|
@@ -627,33 +395,39 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
627
395
|
const uint32 = hash.slice(i, i + 8);
|
|
628
396
|
this.#uboView.setUint32(i * 2, parseInt(uint32, 16));
|
|
629
397
|
}
|
|
630
|
-
this.#uboView.
|
|
631
|
-
this.#uboView.setUint32(
|
|
398
|
+
this.#uboView.setBigUint64(128, threshold, true);
|
|
399
|
+
this.#uboView.setUint32(136, 0, true);
|
|
632
400
|
if (this.#debug) console.log("UBO", this.#uboView.buffer.slice(0));
|
|
633
401
|
this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#uboBuffer);
|
|
634
402
|
this.#gl.bufferSubData(this.#gl.UNIFORM_BUFFER, 0, this.#uboView);
|
|
635
403
|
this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null);
|
|
636
404
|
let times = [];
|
|
637
405
|
let start = performance.now();
|
|
638
|
-
let
|
|
406
|
+
let result = 0n;
|
|
407
|
+
let nonce = 0n;
|
|
408
|
+
let found = false;
|
|
639
409
|
if (this.#debug) console.groupCollapsed("Seeds (click to view)");
|
|
640
|
-
while (
|
|
410
|
+
while (!found) {
|
|
641
411
|
start = performance.now();
|
|
642
412
|
const random0 = Math.floor(Math.random() * 4294967295);
|
|
643
413
|
const random1 = Math.floor(Math.random() * 4294967295);
|
|
644
414
|
this.#seed[0] = BigInt(random0) << 32n | BigInt(random1);
|
|
645
415
|
if (this.#debug) console.log("Seed", this.#seed);
|
|
646
416
|
this.#draw(this.#seed);
|
|
647
|
-
|
|
417
|
+
found = await this.#checkQueryResult();
|
|
648
418
|
times.push(performance.now() - start);
|
|
649
419
|
if (found) {
|
|
420
|
+
({ result, nonce } = this.#readResult());
|
|
650
421
|
if (this.#debug) console.groupEnd();
|
|
651
|
-
nonce = this.#readResult();
|
|
652
422
|
}
|
|
653
423
|
}
|
|
654
424
|
this.#busy = false;
|
|
655
425
|
if (this.#debug) this.#logAverages(times);
|
|
656
|
-
return
|
|
426
|
+
return {
|
|
427
|
+
hash,
|
|
428
|
+
work: nonce.toString(16).padStart(16, "0"),
|
|
429
|
+
difficulty: result.toString(16).padStart(16, "0")
|
|
430
|
+
};
|
|
657
431
|
}
|
|
658
432
|
/**
|
|
659
433
|
* Validates that a nonce satisfies Nano proof-of-work requirements.
|
|
@@ -663,23 +437,37 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
663
437
|
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
664
438
|
*/
|
|
665
439
|
static async validate(work, hash, options) {
|
|
440
|
+
if (options?.threshold != null) {
|
|
441
|
+
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
442
|
+
}
|
|
443
|
+
const result = await this.work_validate(work, hash, options);
|
|
444
|
+
return options?.threshold != null ? result.valid === "1" : result.valid_all === "1";
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Validates that a nonce satisfies Nano proof-of-work requirements.
|
|
448
|
+
*
|
|
449
|
+
* @param {string} work - Hexadecimal proof-of-work value to validate
|
|
450
|
+
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
451
|
+
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
452
|
+
*/
|
|
453
|
+
static async work_validate(work, hash, options) {
|
|
666
454
|
if (this.#busy) {
|
|
667
455
|
console.log("NanoPowGl is busy. Retrying validate...");
|
|
668
456
|
return new Promise((resolve) => {
|
|
669
457
|
setTimeout(async () => {
|
|
670
|
-
const
|
|
671
|
-
resolve(
|
|
458
|
+
const result2 = this.work_validate(work, hash, options);
|
|
459
|
+
resolve(result2);
|
|
672
460
|
}, 100);
|
|
673
461
|
});
|
|
674
462
|
}
|
|
675
463
|
this.#busy = true;
|
|
676
464
|
if (!/^[A-Fa-f0-9]{16}$/.test(work)) throw new Error(`Invalid work ${work}`);
|
|
677
465
|
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new Error(`Invalid hash ${hash}`);
|
|
678
|
-
const threshold = typeof options?.threshold !== "
|
|
466
|
+
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
679
467
|
this.#debug = !!options?.debug;
|
|
680
468
|
if (this.#debug) console.log("NanoPowGl.validate()");
|
|
681
469
|
if (this.#debug) console.log("blockhash", hash);
|
|
682
|
-
if (this.#debug) console.log("validate options", JSON.stringify(options));
|
|
470
|
+
if (this.#debug) console.log("validate options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
683
471
|
if (_NanoPowGl.#gl == null) throw new Error("WebGL 2 is required");
|
|
684
472
|
if (this.#gl == null) throw new Error("WebGL 2 is required");
|
|
685
473
|
if (this.#drawFbo == null) throw new Error("WebGL framebuffer is required");
|
|
@@ -691,34 +479,53 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
691
479
|
const uint32 = hash.slice(i, i + 8);
|
|
692
480
|
this.#uboView.setUint32(i * 2, parseInt(uint32, 16));
|
|
693
481
|
}
|
|
694
|
-
this.#uboView.
|
|
695
|
-
this.#uboView.setUint32(
|
|
482
|
+
this.#uboView.setBigUint64(128, threshold, true);
|
|
483
|
+
this.#uboView.setUint32(136, 1, true);
|
|
696
484
|
if (this.#debug) console.log("UBO", this.#uboView.buffer.slice(0));
|
|
697
485
|
this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#uboBuffer);
|
|
698
486
|
this.#gl.bufferSubData(this.#gl.UNIFORM_BUFFER, 0, this.#uboView);
|
|
699
487
|
this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null);
|
|
700
|
-
let
|
|
488
|
+
let result = 0n;
|
|
489
|
+
let nonce = 0n;
|
|
701
490
|
this.#seed[0] = BigInt(`0x${work}`);
|
|
702
491
|
if (this.#debug) console.log("Work", this.#seed);
|
|
703
492
|
this.#draw(this.#seed);
|
|
704
493
|
let found = await this.#checkQueryResult();
|
|
705
494
|
if (found) {
|
|
706
495
|
try {
|
|
707
|
-
nonce = this.#readResult(work);
|
|
496
|
+
({ result, nonce } = this.#readResult(work));
|
|
708
497
|
} catch (err) {
|
|
709
|
-
|
|
498
|
+
throw new Error("Error reading results", { cause: err });
|
|
710
499
|
}
|
|
500
|
+
} else {
|
|
501
|
+
throw new Error("Failed to find nonce on canvas");
|
|
711
502
|
}
|
|
712
503
|
this.#busy = false;
|
|
713
|
-
if (
|
|
714
|
-
|
|
504
|
+
if (this.#debug) console.log("result", result, result.toString(16).padStart(16, "0"));
|
|
505
|
+
if (this.#debug) console.log("nonce", nonce, nonce.toString(16).padStart(16, "0"));
|
|
506
|
+
const response = {
|
|
507
|
+
hash,
|
|
508
|
+
work: nonce.toString(16).padStart(16, "0"),
|
|
509
|
+
difficulty: result.toString(16).padStart(16, "0"),
|
|
510
|
+
valid_all: result >= this.#SEND ? "1" : "0",
|
|
511
|
+
valid_receive: result >= this.#RECEIVE ? "1" : "0"
|
|
512
|
+
};
|
|
513
|
+
if (options?.threshold != null) response.valid = result >= threshold ? "1" : "0";
|
|
514
|
+
return response;
|
|
715
515
|
}
|
|
716
516
|
};
|
|
717
517
|
|
|
718
|
-
// src/
|
|
518
|
+
// src/lib/gpu/compute.wgsl
|
|
519
|
+
var compute_default = `//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
520
|
+
//! SPDX-License-Identifier: GPL-3.0-or-later
|
|
521
|
+
struct UBO{blockhash:array<vec4<u32>,2>,seed:vec2<u32>,threshold:vec2<u32>};@group(0)@binding(0)var<uniform> ubo:UBO;struct WORK{found:atomic<u32>,nonce:vec2<u32>,result:vec2<u32>};@group(0)@binding(1)var<storage,read_write>work:WORK;const BLAKE2B_IV=array<vec2<u32>,8>(vec2<u32>(0xF3BCC908u,0x6A09E667u),vec2<u32>(0x84CAA73Bu,0xBB67AE85u),vec2<u32>(0xFE94F82Bu,0x3C6EF372u),vec2<u32>(0x5F1D36F1u,0xA54FF53Au),vec2<u32>(0xADE682D1u,0x510E527Fu),vec2<u32>(0x2B3E6C1Fu,0x9B05688Cu),vec2<u32>(0xFB41BD6Bu,0x1F83D9ABu),vec2<u32>(0x137E2179u,0x5BE0CD19u));const BLAKE2B_PARAM=vec2<u32>(0x01010008u,0u);const BLAKE2B_INLEN=vec2<u32>(0x00000028u,0u);const BLAKE2B_FINAL=vec2<u32>(0xFFFFFFFFu,0xFFFFFFFFu);const BLAKE2B_INIT=array<vec2<u32>,16>(BLAKE2B_IV[0u]^ BLAKE2B_PARAM,BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u],BLAKE2B_IV[5u],BLAKE2B_IV[6u],BLAKE2B_IV[7u],BLAKE2B_IV[0u],BLAKE2B_IV[1u],BLAKE2B_IV[2u],BLAKE2B_IV[3u],BLAKE2B_IV[4u]^ BLAKE2B_INLEN,BLAKE2B_IV[5u],BLAKE2B_IV[6u]^ BLAKE2B_FINAL,BLAKE2B_IV[7u]);const Z=vec2(0u);const CARRY=vec4(1u,0u,1u,0u);const ROTATE_1=vec4(1u);const ROTATE_8=vec4(8u);const ROTATE_16=vec4(16u);const ROTATE_24=vec4(24u);const ROTATE_31=vec4(31u);var<workgroup> found:bool;@compute @workgroup_size(32)fn search(@builtin(global_invocation_id)global_id:vec3<u32>,@builtin(local_invocation_id)local_id:vec3<u32>){found=(local_id.x==0u&&atomicLoad(&work.found)!=0u);workgroupBarrier();if(found){return;}main(global_id,false);}@compute @workgroup_size(1)fn validate(@builtin(global_invocation_id)global_id:vec3<u32>){main(global_id,true);}fn main(id:vec3<u32>,validate:bool){let m0:vec2<u32>=ubo.seed ^ id.xy;let m1:vec2<u32>=ubo.blockhash[0u].xy;let m2:vec2<u32>=ubo.blockhash[0u].zw;let m3:vec2<u32>=ubo.blockhash[1u].xy;let m4:vec2<u32>=ubo.blockhash[1u].zw;var v01:vec4<u32>=vec4<u32>(BLAKE2B_INIT[0u],BLAKE2B_INIT[1u]);var v23:vec4<u32>=vec4<u32>(BLAKE2B_INIT[2u],BLAKE2B_INIT[3u]);var v45:vec4<u32>=vec4<u32>(BLAKE2B_INIT[4u],BLAKE2B_INIT[5u]);var v67:vec4<u32>=vec4<u32>(BLAKE2B_INIT[6u],BLAKE2B_INIT[7u]);var v89:vec4<u32>=vec4<u32>(BLAKE2B_INIT[8u],BLAKE2B_INIT[9u]);var vAB:vec4<u32>=vec4<u32>(BLAKE2B_INIT[10u],BLAKE2B_INIT[11u]);var vCD:vec4<u32>=vec4<u32>(BLAKE2B_INIT[12u],BLAKE2B_INIT[13u]);var vEF:vec4<u32>=vec4<u32>(BLAKE2B_INIT[14u],BLAKE2B_INIT[15u]);var v56:vec4<u32>;var vFC:vec4<u32>;var v74:vec4<u32>;var vDE:vec4<u32>;var s0:vec4<u32>;var s1:vec4<u32>;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m0,m2);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;v23+=vec4(m4,Z);v23.y+=u32(v23.x<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m3);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m4);v01.w+=u32(v01.z<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m2);v01.w+=u32(v01.z<m2.x);v23+=vec4(Z,m3);v23.w+=u32(v23.z<m3.x);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(Z,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01.z+=m3.x;v01.w+=m3.y+u32(v01.z<m3.x);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,m4)+vec4(0u,u32(v23.x+vec4(m1,m4).x<v23.x),0u,u32(v23.z+vec4(m1,m4).z<v23.z));vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m3)+vec4(Z,0u,u32(v01.z+vec4(Z,m3).z<v01.z));vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m1)+vec4(Z,0u,u32(v01.z+vec4(Z,m1).z<v01.z));vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m0,Z)+vec4(0u,u32(v23.x+vec4(m0,Z).x<v23.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,Z)+vec4(0u,u32(v01.x+vec4(m0,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m1,Z)+vec4(0u,u32(v01.x+vec4(m1,Z).x<v01.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m0,Z)+vec4(0u,u32(v23.x+vec4(m0,Z).x<v23.x),Z);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m4,Z)+vec4(0u,u32(v01.x+vec4(m4,Z).x<v01.x),Z);v23+=vec4(Z,m1)+vec4(Z,0u,u32(v23.z+vec4(Z,m1).z<v23.z));vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m1)+vec4(Z,0u,u32(v01.z+vec4(Z,m1).z<v01.z));v23+=vec4(Z,m4)+vec4(Z,0u,u32(v23.z+vec4(Z,m4).z<v23.z));vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,Z)+vec4(0u,u32(v01.x+vec4(m0,Z).x<v01.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m3)+vec4(Z,0u,u32(v01.z+vec4(Z,m3).z<v01.z));s1=v23+vec4(m2,Z);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s1=v23+vec4(Z,m3);v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,Z)+vec4(0u,u32(v23.x+vec4(m1,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m2)+vec4(Z,0u,u32(v23.z+vec4(Z,m2).z<v23.z));vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m0,m4)+vec4(0u,u32(v01.x+vec4(m0,m4).x<v01.x),0u,u32(v01.z+vec4(m0,m4).z<v01.z));vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m0);v23.w+=u32(v23.z<m0.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m3,Z)+vec4(0u,u32(v23.x+vec4(m3,Z).x<v23.x),Z);vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m1,Z)+vec4(0u,u32(v23.x+vec4(m1,Z).x<v23.x),Z);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(m2,Z)+vec4(0u,u32(v01.x+vec4(m2,Z).x<v01.x),Z);v23+=vec4(m4,Z)+vec4(0u,u32(v23.x+vec4(m4,Z).x<v23.x),Z);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m1);v23.w+=u32(v23.z<m1.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m2,m4);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(m3,Z);v23.y+=u32(v23.x<m3.x);vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m0);v23.w+=u32(v23.z<m0.x);vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m0,m2);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;v23+=vec4(m4,Z);v23.y+=u32(v23.x<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m3);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vFC ^=v01;vFC=(vFC>>ROTATE_16)|(vFC<<ROTATE_16).yxwz;vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_31).yxwz|(v56<<ROTATE_1);v74 ^=v89;v74=(v74>>ROTATE_31).yxwz|(v74<<ROTATE_1);v45=vec4(v74.zw,v56.xy);v67=vec4(v56.zw,v74.xy);vCD=vec4(vFC.zw,vDE.xy);vEF=vec4(vDE.zw,vFC.xy);s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v01+=vec4(Z,m4);v01.w+=u32(v01.z<m4.x);vCD=(vCD ^ v01).yxwz;vEF=(vEF ^ v23).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_24)|(v45<<ROTATE_8).yxwz;v67 ^=vAB;v67=(v67>>ROTATE_24)|(v67<<ROTATE_8).yxwz;s0=v01+v45;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v67;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;vCD ^=v01;vCD=(vCD>>ROTATE_16)|(vCD<<ROTATE_16).yxwz;vEF ^=v23;vEF=(vEF>>ROTATE_16)|(vEF<<ROTATE_16).yxwz;s0=v89+vCD;v89=s0+(vec4<u32>(s0<v89)&CARRY).yxwz;s1=vAB+vEF;vAB=s1+(vec4<u32>(s1<vAB)&CARRY).yxwz;v45 ^=v89;v45=(v45>>ROTATE_31).yxwz|(v45<<ROTATE_1);v67 ^=vAB;v67=(v67>>ROTATE_31).yxwz|(v67<<ROTATE_1);v56=vec4(v45.zw,v67.xy);v74=vec4(v67.zw,v45.xy);vFC=vec4(vEF.zw,vCD.xy);vDE=vec4(vCD.zw,vEF.xy);s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;s0=v01+vec4(m1,m0);v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;vFC=(vFC ^ v01).yxwz;vDE=(vDE ^ v23).yxwz;s0=vAB+vFC;vAB=s0+(vec4<u32>(s0<vAB)&CARRY).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;v56 ^=vAB;v56=(v56>>ROTATE_24)|(v56<<ROTATE_8).yxwz;v74 ^=v89;v74=(v74>>ROTATE_24)|(v74<<ROTATE_8).yxwz;s0=v01+v56;v01=s0+(vec4<u32>(s0<v01)&CARRY).yxwz;s1=v23+v74;v23=s1+(vec4<u32>(s1<v23)&CARRY).yxwz;v23+=vec4(Z,m3);v23.w+=u32(v23.z<m3.x);vDE ^=v23;vDE=(vDE>>ROTATE_16)|(vDE<<ROTATE_16).yxwz;s1=v89+vDE;v89=s1+(vec4<u32>(s1<v89)&CARRY).yxwz;var result=BLAKE2B_INIT[0u]^ v01.xy ^ v89.xy;if(validate||((result.y>ubo.threshold.y||(result.y==ubo.threshold.y&&result.y>=ubo.threshold.y))&&atomicLoad(&work.found)==0u)){atomicStore(&work.found,1u);work.nonce=m0;work.result=result;}return;}`;
|
|
522
|
+
|
|
523
|
+
// src/lib/gpu/index.ts
|
|
719
524
|
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
720
525
|
//! SPDX-License-Identifier: GPL-3.0-or-later
|
|
721
526
|
var NanoPowGpu = class _NanoPowGpu {
|
|
527
|
+
static #SEND = 0xfffffff800000000n;
|
|
528
|
+
static #RECEIVE = 0xfffffe0000000000n;
|
|
722
529
|
// Initialize WebGPU
|
|
723
530
|
static #busy = false;
|
|
724
531
|
static #debug = false;
|
|
@@ -849,7 +656,7 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
849
656
|
this.#uboView.setBigUint64(i / 2, BigInt(`0x${u64}`));
|
|
850
657
|
}
|
|
851
658
|
this.#uboView.setBigUint64(32, seed, true);
|
|
852
|
-
this.#uboView.
|
|
659
|
+
this.#uboView.setBigUint64(40, threshold, true);
|
|
853
660
|
if (this.#debug) console.log("UBO", this.#uboView);
|
|
854
661
|
this.#device.queue.writeBuffer(this.#uboBuffer, 0, this.#uboView);
|
|
855
662
|
this.#device.queue.writeBuffer(this.#gpuBuffer, 0, this.#bufferReset);
|
|
@@ -900,23 +707,36 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
900
707
|
* @param {NanoPowOptions} options - Used to configure search execution
|
|
901
708
|
*/
|
|
902
709
|
static async search(hash, options) {
|
|
710
|
+
if (options?.threshold != null) {
|
|
711
|
+
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
712
|
+
}
|
|
713
|
+
const result = await this.work_generate(hash, options);
|
|
714
|
+
return result.work;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Finds a nonce that satisfies the Nano proof-of-work requirements.
|
|
718
|
+
*
|
|
719
|
+
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
720
|
+
* @param {NanoPowOptions} options - Used to configure search execution
|
|
721
|
+
*/
|
|
722
|
+
static async work_generate(hash, options) {
|
|
903
723
|
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new TypeError(`Invalid hash ${hash}`);
|
|
904
724
|
if (this.#busy) {
|
|
905
725
|
console.log("NanoPowGpu is busy. Retrying search...");
|
|
906
726
|
return new Promise((resolve) => {
|
|
907
727
|
setTimeout(async () => {
|
|
908
|
-
const
|
|
909
|
-
resolve(
|
|
728
|
+
const result2 = this.work_generate(hash, options);
|
|
729
|
+
resolve(result2);
|
|
910
730
|
}, 100);
|
|
911
731
|
});
|
|
912
732
|
}
|
|
913
733
|
this.#busy = true;
|
|
914
|
-
const threshold = typeof options?.threshold !== "
|
|
734
|
+
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
915
735
|
const effort = typeof options?.effort !== "number" || options.effort < 1 || options.effort > 32 ? 2048 : options.effort * 256;
|
|
916
736
|
this.#debug = !!options?.debug;
|
|
917
737
|
if (this.#debug) console.log("NanoPowGpu.search()");
|
|
918
738
|
if (this.#debug) console.log("blockhash", hash);
|
|
919
|
-
if (this.#debug) console.log("search options", JSON.stringify(options));
|
|
739
|
+
if (this.#debug) console.log("search options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
920
740
|
let loads = 0;
|
|
921
741
|
while (this.#device == null && loads < 20) {
|
|
922
742
|
await new Promise((resolve) => {
|
|
@@ -930,6 +750,7 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
930
750
|
let times = [];
|
|
931
751
|
let start = performance.now();
|
|
932
752
|
let nonce = 0n;
|
|
753
|
+
let result = 0n;
|
|
933
754
|
do {
|
|
934
755
|
start = performance.now();
|
|
935
756
|
const random0 = Math.floor(Math.random() * 4294967295);
|
|
@@ -939,13 +760,18 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
939
760
|
const data = await this.#dispatch(this.#searchPipeline, seed, hash, threshold, effort);
|
|
940
761
|
const found = !!data.getUint32(0);
|
|
941
762
|
nonce = data.getBigUint64(8, true);
|
|
942
|
-
|
|
763
|
+
result = data.getBigUint64(16, true);
|
|
943
764
|
this.#busy = !found;
|
|
944
765
|
times.push(performance.now() - start);
|
|
945
766
|
} while (this.#busy);
|
|
946
767
|
if (this.#debug) this.#logAverages(times);
|
|
947
768
|
if (this.#debug) console.log("nonce", nonce, nonce.toString(16).padStart(16, "0"));
|
|
948
|
-
|
|
769
|
+
if (this.#debug) console.log("result", result, result.toString(16).padStart(16, "0"));
|
|
770
|
+
return {
|
|
771
|
+
hash,
|
|
772
|
+
work: nonce.toString(16).padStart(16, "0"),
|
|
773
|
+
difficulty: result.toString(16).padStart(16, "0")
|
|
774
|
+
};
|
|
949
775
|
}
|
|
950
776
|
/**
|
|
951
777
|
* Validates that a nonce satisfies Nano proof-of-work requirements.
|
|
@@ -955,23 +781,37 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
955
781
|
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
956
782
|
*/
|
|
957
783
|
static async validate(work, hash, options) {
|
|
784
|
+
if (options?.threshold != null) {
|
|
785
|
+
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
786
|
+
}
|
|
787
|
+
const result = await this.work_validate(work, hash, options);
|
|
788
|
+
return options?.threshold != null ? result.valid === "1" : result.valid_all === "1";
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Validates that a nonce satisfies Nano proof-of-work requirements.
|
|
792
|
+
*
|
|
793
|
+
* @param {string} work - Hexadecimal proof-of-work value to validate
|
|
794
|
+
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
795
|
+
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
796
|
+
*/
|
|
797
|
+
static async work_validate(work, hash, options) {
|
|
958
798
|
if (!/^[A-Fa-f0-9]{16}$/.test(work)) throw new TypeError(`Invalid work ${work}`);
|
|
959
799
|
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new TypeError(`Invalid hash ${hash}`);
|
|
960
800
|
if (this.#busy) {
|
|
961
801
|
console.log("NanoPowGpu is busy. Retrying validate...");
|
|
962
802
|
return new Promise((resolve) => {
|
|
963
803
|
setTimeout(async () => {
|
|
964
|
-
const
|
|
965
|
-
resolve(
|
|
804
|
+
const result2 = this.work_validate(work, hash, options);
|
|
805
|
+
resolve(result2);
|
|
966
806
|
}, 100);
|
|
967
807
|
});
|
|
968
808
|
}
|
|
969
809
|
this.#busy = true;
|
|
970
|
-
const threshold = typeof options?.threshold !== "
|
|
810
|
+
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
971
811
|
this.#debug = !!options?.debug;
|
|
972
812
|
if (this.#debug) console.log("NanoPowGpu.validate()");
|
|
973
813
|
if (this.#debug) console.log("blockhash", hash);
|
|
974
|
-
if (this.#debug) console.log("validate options", JSON.stringify(options));
|
|
814
|
+
if (this.#debug) console.log("validate options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
975
815
|
let loads = 0;
|
|
976
816
|
while (this.#device == null && loads < 20) {
|
|
977
817
|
await new Promise((resolve) => {
|
|
@@ -982,20 +822,29 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
982
822
|
this.#busy = false;
|
|
983
823
|
throw new Error(`WebGPU device failed to load.`);
|
|
984
824
|
}
|
|
825
|
+
let result = 0n;
|
|
826
|
+
let nonce = 0n;
|
|
985
827
|
const seed = BigInt(`0x${work}`);
|
|
986
828
|
if (this.#debug) console.log("work", work);
|
|
987
829
|
const data = await this.#dispatch(this.#validatePipeline, seed, hash, threshold, 1);
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
if (this.#debug) console.log("result", data.getBigUint64(16).toString(16).padStart(16, "0"));
|
|
830
|
+
nonce = data.getBigUint64(8, true);
|
|
831
|
+
result = data.getBigUint64(16, true);
|
|
991
832
|
this.#busy = false;
|
|
992
833
|
if (this.#debug) console.log("nonce", nonce, nonce.toString(16).padStart(16, "0"));
|
|
993
|
-
if (
|
|
994
|
-
|
|
834
|
+
if (this.#debug) console.log("result", result, result.toString(16).padStart(16, "0"));
|
|
835
|
+
const response = {
|
|
836
|
+
hash,
|
|
837
|
+
work: nonce.toString(16).padStart(16, "0"),
|
|
838
|
+
difficulty: result.toString(16).padStart(16, "0"),
|
|
839
|
+
valid_all: result >= this.#SEND ? "1" : "0",
|
|
840
|
+
valid_receive: result >= this.#RECEIVE ? "1" : "0"
|
|
841
|
+
};
|
|
842
|
+
if (options?.threshold != null) response.valid = result >= threshold ? "1" : "0";
|
|
843
|
+
return response;
|
|
995
844
|
}
|
|
996
845
|
};
|
|
997
846
|
|
|
998
|
-
// src/
|
|
847
|
+
// src/lib/index.ts
|
|
999
848
|
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
1000
849
|
//! SPDX-License-Identifier: GPL-3.0-or-later
|
|
1001
850
|
var isGlSupported;
|