nano-pow 2.0.0 → 3.0.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.
@@ -1,801 +0,0 @@
1
- // src/shaders/compute.wgsl
2
- var compute_default = "struct UBO{blockhash:array<vec4<u32>,2>,random:vec2<u32>,threshold:u32};@group(0)@binding(0)var<uniform> ubo:UBO;struct WORK{nonce:vec2<u32>,found:atomic<u32>};@group(0)@binding(1)var<storage,read_write>work:WORK;const BLAKE2B_IV32_1:u32=0x6A09E667u;const ROTATE_1=vec2(1u,1u);const ROTATE_8=vec2(8u,8u);const ROTATE_16=vec2(16u,16u);const ROTATE_24=vec2(24u,24u);const ROTATE_31=vec2(31u,31u);@compute @workgroup_size(8,8)fn search(@builtin(global_invocation_id)global_id:vec3<u32>){if(atomicLoad(&work.found)!=0u){return;}main(global_id);}@compute @workgroup_size(1)fn validate(@builtin(global_invocation_id)global_id:vec3<u32>){if(atomicLoad(&work.found)!=0u){return;}main(global_id);}fn main(id:vec3<u32>){let threshold:u32=ubo.threshold;let m0:vec2<u32>=ubo.random ^ 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 v0:vec2<u32>=vec2(0xF2BDC900u,0x6A09E667u);var v1:vec2<u32>=vec2(0x84CAA73Bu,0xBB67AE85u);var v2:vec2<u32>=vec2(0xFE94F82Bu,0x3C6EF372u);var v3:vec2<u32>=vec2(0x5F1D36F1u,0xA54FF53Au);var v4:vec2<u32>=vec2(0xADE682D1u,0x510E527Fu);var v5:vec2<u32>=vec2(0x2B3E6C1Fu,0x9B05688Cu);var v6:vec2<u32>=vec2(0xFB41BD6Bu,0x1F83D9ABu);var v7:vec2<u32>=vec2(0x137E2179u,0x5BE0CD19u);var v8:vec2<u32>=vec2(0xF3BCC908u,0x6A09E667u);var v9:vec2<u32>=vec2(0x84CAA73Bu,0xBB67AE85u);var v10:vec2<u32>=vec2(0xFE94F82Bu,0x3C6EF372u);var v11:vec2<u32>=vec2(0x5F1D36F1u,0xA54FF53Au);var v12:vec2<u32>=vec2(0xADE682F9u,0x510E527Fu);var v13:vec2<u32>=vec2(0x2B3E6C1Fu,0x9B05688Cu);var v14:vec2<u32>=vec2(0x04BE4294u,0xE07C2654u);var v15:vec2<u32>=vec2(0x137E2179u,0x5BE0CD19u);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v0=v0+m0+vec2(0u,u32(v0.x+m0.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v0=v0+m1+vec2(0u,u32(v0.x+m1.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m2+vec2(0u,u32(v1.x+m2.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m3+vec2(0u,u32(v1.x+m3.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m4+vec2(0u,u32(v2.x+m4.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m4+vec2(0u,u32(v1.x+m4.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m1+vec2(0u,u32(v0.x+m1.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v1=v1+m0+vec2(0u,u32(v1.x+m0.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v1=v1+m2+vec2(0u,u32(v1.x+m2.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v3=v3+m3+vec2(0u,u32(v3.x+m3.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m0+vec2(0u,u32(v1.x+m0.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m2+vec2(0u,u32(v2.x+m2.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v1=v1+m3+vec2(0u,u32(v1.x+m3.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v2=v2+m1+vec2(0u,u32(v2.x+m1.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v3=v3+m4+vec2(0u,u32(v3.x+m4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m3+vec2(0u,u32(v1.x+m3.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m1+vec2(0u,u32(v1.x+m1.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m2+vec2(0u,u32(v0.x+m2.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v2=v2+m4+vec2(0u,u32(v2.x+m4.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v2=v2+m0+vec2(0u,u32(v2.x+m0.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v0=v0+m0+vec2(0u,u32(v0.x+m0.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m2+vec2(0u,u32(v2.x+m2.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m4+vec2(0u,u32(v2.x+m4.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m1+vec2(0u,u32(v0.x+m1.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v3=v3+m3+vec2(0u,u32(v3.x+m3.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v0=v0+m2+vec2(0u,u32(v0.x+m2.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m0+vec2(0u,u32(v2.x+m0.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v3=v3+m3+vec2(0u,u32(v3.x+m3.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m4+vec2(0u,u32(v0.x+m4.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v3=v3+m1+vec2(0u,u32(v3.x+m1.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m1+vec2(0u,u32(v1.x+m1.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v3=v3+m4+vec2(0u,u32(v3.x+m4.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m0+vec2(0u,u32(v0.x+m0.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v1=v1+m3+vec2(0u,u32(v1.x+m3.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v2=v2+m2+vec2(0u,u32(v2.x+m2.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m1+vec2(0u,u32(v2.x+m1.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v3=v3+m3+vec2(0u,u32(v3.x+m3.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m0+vec2(0u,u32(v0.x+m0.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v1=v1+m4+vec2(0u,u32(v1.x+m4.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v3=v3+m2+vec2(0u,u32(v3.x+m2.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m3+vec2(0u,u32(v2.x+m3.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v3=v3+m0+vec2(0u,u32(v3.x+m0.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m2+vec2(0u,u32(v0.x+m2.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v2=v2+m1+vec2(0u,u32(v2.x+m1.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v2=v2+m4+vec2(0u,u32(v2.x+m4.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v0=v0+m2+vec2(0u,u32(v0.x+m2.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m4+vec2(0u,u32(v1.x+m4.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v3=v3+m1+vec2(0u,u32(v3.x+m1.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v2=v2+m3+vec2(0u,u32(v2.x+m3.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v3=v3+m0+vec2(0u,u32(v3.x+m0.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v0=v0+m0+vec2(0u,u32(v0.x+m0.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v0=v0+m1+vec2(0u,u32(v0.x+m1.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy<<ROTATE_1)|((v4 ^ v8).yx>>ROTATE_31);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m2+vec2(0u,u32(v1.x+m2.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m3+vec2(0u,u32(v1.x+m3.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v2=v2+m4+vec2(0u,u32(v2.x+m4.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy<<ROTATE_1)|((v6 ^ v10).yx>>ROTATE_31);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v15=((v15 ^ v0).xy>>ROTATE_16)|((v15 ^ v0).yx<<ROTATE_16);v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy<<ROTATE_1)|((v5 ^ v10).yx>>ROTATE_31);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=v12.yx ^ v1.yx;v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy>>ROTATE_24)|((v6 ^ v11).yx<<ROTATE_8);v1=v1+v6+vec2(0u,u32(v1.x+v6.x<v1.x));v12=((v12 ^ v1).xy>>ROTATE_16)|((v12 ^ v1).yx<<ROTATE_16);v11=v11+v12+vec2(0u,u32(v11.x+v12.x<v11.x));v6=((v6 ^ v11).xy<<ROTATE_1)|((v6 ^ v11).yx>>ROTATE_31);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy<<ROTATE_1)|((v7 ^ v8).yx>>ROTATE_31);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=v14.yx ^ v3.yx;v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy>>ROTATE_24)|((v4 ^ v9).yx<<ROTATE_8);v3=v3+v4+vec2(0u,u32(v3.x+v4.x<v3.x));v14=((v14 ^ v3).xy>>ROTATE_16)|((v14 ^ v3).yx<<ROTATE_16);v9=v9+v14+vec2(0u,u32(v9.x+v14.x<v9.x));v4=((v4 ^ v9).xy<<ROTATE_1)|((v4 ^ v9).yx>>ROTATE_31);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=v12.yx ^ v0.yx;v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v4=((v4 ^ v8).xy>>ROTATE_24)|((v4 ^ v8).yx<<ROTATE_8);v0=v0+v4+vec2(0u,u32(v0.x+v4.x<v0.x));v12=((v12 ^ v0).xy>>ROTATE_16)|((v12 ^ v0).yx<<ROTATE_16);v8=v8+v12+vec2(0u,u32(v8.x+v12.x<v8.x));v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v1=v1+m4+vec2(0u,u32(v1.x+m4.x<v1.x));v13=v13.yx ^ v1.yx;v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy>>ROTATE_24)|((v5 ^ v9).yx<<ROTATE_8);v1=v1+v5+vec2(0u,u32(v1.x+v5.x<v1.x));v13=((v13 ^ v1).xy>>ROTATE_16)|((v13 ^ v1).yx<<ROTATE_16);v9=v9+v13+vec2(0u,u32(v9.x+v13.x<v9.x));v5=((v5 ^ v9).xy<<ROTATE_1)|((v5 ^ v9).yx>>ROTATE_31);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=v14.yx ^ v2.yx;v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v6=((v6 ^ v10).xy>>ROTATE_24)|((v6 ^ v10).yx<<ROTATE_8);v2=v2+v6+vec2(0u,u32(v2.x+v6.x<v2.x));v14=((v14 ^ v2).xy>>ROTATE_16)|((v14 ^ v2).yx<<ROTATE_16);v10=v10+v14+vec2(0u,u32(v10.x+v14.x<v10.x));v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=v15.yx ^ v3.yx;v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy>>ROTATE_24)|((v7 ^ v11).yx<<ROTATE_8);v3=v3+v7+vec2(0u,u32(v3.x+v7.x<v3.x));v15=((v15 ^ v3).xy>>ROTATE_16)|((v15 ^ v3).yx<<ROTATE_16);v11=v11+v15+vec2(0u,u32(v11.x+v15.x<v11.x));v7=((v7 ^ v11).xy<<ROTATE_1)|((v7 ^ v11).yx>>ROTATE_31);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v0=v0+m1+vec2(0u,u32(v0.x+m1.x<v0.x));v15=v15.yx ^ v0.yx;v10=v10+v15+vec2(0u,u32(v10.x+v15.x<v10.x));v5=((v5 ^ v10).xy>>ROTATE_24)|((v5 ^ v10).yx<<ROTATE_8);v0=v0+v5+vec2(0u,u32(v0.x+v5.x<v0.x));v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=v13.yx ^ v2.yx;v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));v7=((v7 ^ v8).xy>>ROTATE_24)|((v7 ^ v8).yx<<ROTATE_8);v2=v2+v7+vec2(0u,u32(v2.x+v7.x<v2.x));v13=((v13 ^ v2).xy>>ROTATE_16)|((v13 ^ v2).yx<<ROTATE_16);v8=v8+v13+vec2(0u,u32(v8.x+v13.x<v8.x));if((BLAKE2B_IV32_1 ^ v0.y ^ v8.y)>threshold&&atomicLoad(&work.found)==0u){atomicStore(&work.found,1u);work.nonce=m0;}return;}";
3
-
4
- // src/shaders/gl-fragment.ts
5
- var NanoPowGlFragmentShader = `#version 300 es
6
- #pragma vscode_glsllint_stage: frag
7
- precision highp float;
8
- precision highp int;
9
-
10
- in vec2 uv_pos;
11
- out vec4 fragColor;
12
-
13
- // blockhash - array of precalculated block hash components
14
- // threshold - 0xfffffff8 for send/change blocks, 0xfffffe00 for all else
15
- // workload - Defines canvas size
16
- layout(std140) uniform UBO {
17
- uint blockhash[8];
18
- uint threshold;
19
- float workload;
20
- };
21
-
22
- // Random work values
23
- // First 2 bytes will be overwritten by texture pixel position
24
- // Second 2 bytes will be modified if the canvas size is greater than 256x256
25
- // Last 4 bytes remain as generated externally
26
- layout(std140) uniform WORK {
27
- uvec4 work[2];
28
- };
29
-
30
- // Defined separately from uint v[32] below as the original value is required
31
- // to calculate the second uint32 of the digest for threshold comparison
32
- const uint BLAKE2B_IV32_1 = 0x6A09E667u;
33
-
34
- // Both buffers represent 16 uint64s as 32 uint32s
35
- // because that's what GLSL offers, just like Javascript
36
-
37
- // Compression buffer, intialized to 2 instances of the initialization vector
38
- // The following values have been modified from the BLAKE2B_IV:
39
- // OUTLEN is constant 8 bytes
40
- // v[0] ^= 0x01010000u ^ uint(OUTLEN);
41
- // INLEN is constant 40 bytes: work value (8) + block hash (32)
42
- // v[24] ^= uint(INLEN);
43
- // It's always the "last" compression at this INLEN
44
- // v[28] = ~v[28];
45
- // v[29] = ~v[29];
46
- uint v[32] = uint[32](
47
- 0xF2BDC900u, 0x6A09E667u, 0x84CAA73Bu, 0xBB67AE85u,
48
- 0xFE94F82Bu, 0x3C6EF372u, 0x5F1D36F1u, 0xA54FF53Au,
49
- 0xADE682D1u, 0x510E527Fu, 0x2B3E6C1Fu, 0x9B05688Cu,
50
- 0xFB41BD6Bu, 0x1F83D9ABu, 0x137E2179u, 0x5BE0CD19u,
51
- 0xF3BCC908u, 0x6A09E667u, 0x84CAA73Bu, 0xBB67AE85u,
52
- 0xFE94F82Bu, 0x3C6EF372u, 0x5F1D36F1u, 0xA54FF53Au,
53
- 0xADE682F9u, 0x510E527Fu, 0x2B3E6C1Fu, 0x9B05688Cu,
54
- 0x04BE4294u, 0xE07C2654u, 0x137E2179u, 0x5BE0CD19u
55
- );
56
- // Input data buffer
57
- uint m[32];
58
-
59
- // These are offsets into the input data buffer for each mixing step.
60
- // They are multiplied by 2 from the original SIGMA values in
61
- // the C reference implementation, which refered to uint64s.
62
- const uint SIGMA82[192] = uint[192](
63
- 0u,2u,4u,6u,8u,10u,12u,14u,16u,18u,20u,22u,24u,26u,28u,30u,
64
- 28u,20u,8u,16u,18u,30u,26u,12u,2u,24u,0u,4u,22u,14u,10u,6u,
65
- 22u,16u,24u,0u,10u,4u,30u,26u,20u,28u,6u,12u,14u,2u,18u,8u,
66
- 14u,18u,6u,2u,26u,24u,22u,28u,4u,12u,10u,20u,8u,0u,30u,16u,
67
- 18u,0u,10u,14u,4u,8u,20u,30u,28u,2u,22u,24u,12u,16u,6u,26u,
68
- 4u,24u,12u,20u,0u,22u,16u,6u,8u,26u,14u,10u,30u,28u,2u,18u,
69
- 24u,10u,2u,30u,28u,26u,8u,20u,0u,14u,12u,6u,18u,4u,16u,22u,
70
- 26u,22u,14u,28u,24u,2u,6u,18u,10u,0u,30u,8u,16u,12u,4u,20u,
71
- 12u,30u,28u,18u,22u,6u,0u,16u,24u,4u,26u,14u,2u,8u,20u,10u,
72
- 20u,4u,16u,8u,14u,12u,2u,10u,30u,22u,18u,28u,6u,24u,26u,0u,
73
- 0u,2u,4u,6u,8u,10u,12u,14u,16u,18u,20u,22u,24u,26u,28u,30u,
74
- 28u,20u,8u,16u,18u,30u,26u,12u,2u,24u,0u,4u,22u,14u,10u,6u
75
- );
76
-
77
- // G mixing function
78
- void G (uint ix, uint iy, uint a, uint b, uint c, uint d) {
79
- bool carry;
80
- uint o0;
81
- uint o1;
82
- uint xor0;
83
- uint xor1;
84
-
85
- // a = a + b;
86
- o0 = v[a] + v[b];
87
- o1 = v[a+1u] + v[b+1u];
88
- carry = o0 < v[a];
89
- o1 = o1 + uint(mix(0.0, 1.0, float(carry)));
90
- v[a] = o0;
91
- v[a+1u] = o1;
92
-
93
- // a = a + m[sigma[r][2*i+0]];
94
- o0 = v[a] + m[ix];
95
- o1 = v[a+1u] + m[ix+1u];
96
- carry = o0 < v[a];
97
- o1 = o1 + uint(mix(0.0, 1.0, float(carry)));
98
- v[a] = o0;
99
- v[a+1u] = o1;
100
-
101
- // d = rotr64(d ^ a, 32);
102
- xor0 = v[d] ^ v[a];
103
- xor1 = v[d+1u] ^ v[a+1u];
104
- v[d] = xor1;
105
- v[d+1u] = xor0;
106
-
107
- // c = c + d;
108
- o0 = v[c] + v[d];
109
- o1 = v[c+1u] + v[d+1u];
110
- carry = o0 < v[c];
111
- o1 = o1 + uint(mix(0.0, 1.0, float(carry)));
112
- v[c] = o0;
113
- v[c+1u] = o1;
114
-
115
- // b = rotr64(b ^ c, 24);
116
- xor0 = v[b] ^ v[c];
117
- xor1 = v[b+1u] ^ v[c+1u];
118
- v[b] = (xor0 >> 24u) ^ (xor1 << 8u);
119
- v[b+1u] = (xor1 >> 24u) ^ (xor0 << 8u);
120
-
121
- // a = a + b;
122
- o0 = v[a] + v[b];
123
- o1 = v[a+1u] + v[b+1u];
124
- carry = o0 < v[a];
125
- o1 = o1 + uint(mix(0.0, 1.0, float(carry)));
126
- v[a] = o0;
127
- v[a+1u] = o1;
128
-
129
- // a = a + m[sigma[r][2*i+1]];
130
- o0 = v[a] + m[iy];
131
- o1 = v[a+1u] + m[iy+1u];
132
- carry = o0 < v[a];
133
- o1 = o1 + uint(mix(0.0, 1.0, float(carry)));
134
- v[a] = o0;
135
- v[a+1u] = o1;
136
-
137
- // d = rotr64(d ^ a, 16)
138
- xor0 = v[d] ^ v[a];
139
- xor1 = v[d+1u] ^ v[a+1u];
140
- v[d] = (xor0 >> 16u) ^ (xor1 << 16u);
141
- v[d+1u] = (xor1 >> 16u) ^ (xor0 << 16u);
142
-
143
- // c = c + d;
144
- o0 = v[c] + v[d];
145
- o1 = v[c+1u] + v[d+1u];
146
- carry = o0 < v[c];
147
- o1 = o1 + uint(mix(0.0, 1.0, float(carry)));
148
- v[c] = o0;
149
- v[c+1u] = o1;
150
-
151
- // b = rotr64(b ^ c, 63)
152
- xor0 = v[b] ^ v[c];
153
- xor1 = v[b+1u] ^ v[c+1u];
154
- v[b] = (xor1 >> 31u) ^ (xor0 << 1u);
155
- v[b+1u] = (xor0 >> 31u) ^ (xor1 << 1u);
156
- }
157
-
158
- void main() {
159
- int i;
160
- uvec4 u_work0 = work[0u];
161
- uvec4 u_work1 = work[1u];
162
- uint uv_x = uint(uv_pos.x * workload);
163
- uint uv_y = uint(uv_pos.y * workload);
164
- uint x_pos = uv_x % 256u;
165
- uint y_pos = uv_y % 256u;
166
- uint x_index = (uv_x - x_pos) / 256u;
167
- uint y_index = (uv_y - y_pos) / 256u;
168
-
169
- // First 2 work bytes are the x,y pos within the 256x256 area, the next
170
- // two bytes are modified from the random generated value, XOR'd with
171
- // the x,y area index of where this pixel is located
172
- m[0u] = (x_pos ^ (y_pos << 8u) ^ ((u_work0.b ^ x_index) << 16u) ^ ((u_work0.a ^ y_index) << 24u));
173
-
174
- // Remaining bytes are un-modified from the random generated value
175
- m[1u] = (u_work1.r ^ (u_work1.g << 8u) ^ (u_work1.b << 16u) ^ (u_work1.a << 24u));
176
-
177
- // Block hash
178
- for (uint i = 0u; i < 8u; i = i + 1u) {
179
- m[i+2u] = blockhash[i];
180
- }
181
-
182
- // twelve rounds of mixing
183
- for(uint i = 0u; i < 12u; i = i + 1u) {
184
- G(SIGMA82[i * 16u + 0u], SIGMA82[i * 16u + 1u], 0u, 8u, 16u, 24u);
185
- G(SIGMA82[i * 16u + 2u], SIGMA82[i * 16u + 3u], 2u, 10u, 18u, 26u);
186
- G(SIGMA82[i * 16u + 4u], SIGMA82[i * 16u + 5u], 4u, 12u, 20u, 28u);
187
- G(SIGMA82[i * 16u + 6u], SIGMA82[i * 16u + 7u], 6u, 14u, 22u, 30u);
188
- G(SIGMA82[i * 16u + 8u], SIGMA82[i * 16u + 9u], 0u, 10u, 20u, 30u);
189
- G(SIGMA82[i * 16u + 10u], SIGMA82[i * 16u + 11u], 2u, 12u, 22u, 24u);
190
- G(SIGMA82[i * 16u + 12u], SIGMA82[i * 16u + 13u], 4u, 14u, 16u, 26u);
191
- G(SIGMA82[i * 16u + 14u], SIGMA82[i * 16u + 15u], 6u, 8u, 18u, 28u);
192
- }
193
-
194
- // Pixel data is multipled by threshold test result (0 or 1)
195
- // First 4 bytes insignificant, only calculate digest of second 4 bytes
196
- if ((BLAKE2B_IV32_1 ^ v[1u] ^ v[17u]) > threshold) {
197
- fragColor = vec4(
198
- float(x_index + 1u)/255.0, // +1 to distinguish from 0 (unsuccessful) pixels
199
- float(y_index + 1u)/255.0, // Same as previous
200
- float(x_pos)/255.0, // Return the 2 custom bytes used in work value
201
- float(y_pos)/255.0 // Second custom byte
202
- );
203
- } else {
204
- discard;
205
- }
206
- }
207
- `;
208
-
209
- // src/shaders/gl-vertex.ts
210
- var NanoPowGlVertexShader = `#version 300 es
211
- #pragma vscode_glsllint_stage: vert
212
- precision highp float;
213
- layout (location=0) in vec4 position;
214
- layout (location=1) in vec2 uv;
215
-
216
- out vec2 uv_pos;
217
-
218
- void main() {
219
- uv_pos = uv;
220
- gl_Position = position;
221
- }
222
- `;
223
-
224
- // src/classes/gl.ts
225
- var NanoPowGl = class _NanoPowGl {
226
- static #busy = false;
227
- /** Used to set canvas size. Must be a multiple of 256. */
228
- static #WORKLOAD = 256 * Math.max(1, Math.floor(navigator.hardwareConcurrency));
229
- static #hexify(arr) {
230
- let out = "";
231
- for (let i = arr.length - 1; i >= 0; i--) {
232
- out += arr[i].toString(16).padStart(2, "0");
233
- }
234
- return out;
235
- }
236
- static #gl;
237
- static #program;
238
- static #vertexShader;
239
- static #fragmentShader;
240
- static #positionBuffer;
241
- static #uvBuffer;
242
- static #uboBuffer;
243
- static #workBuffer;
244
- static #query;
245
- static #pixels;
246
- /**Vertex Positions, 2 triangles */
247
- static #positions = new Float32Array([
248
- -1,
249
- -1,
250
- 0,
251
- -1,
252
- 1,
253
- 0,
254
- 1,
255
- 1,
256
- 0,
257
- 1,
258
- -1,
259
- 0,
260
- 1,
261
- 1,
262
- 0,
263
- -1,
264
- -1,
265
- 0
266
- ]);
267
- /** Texture Positions */
268
- static #uvPosArray = new Float32Array([
269
- 1,
270
- 1,
271
- 1,
272
- 0,
273
- 0,
274
- 0,
275
- 0,
276
- 1,
277
- 0,
278
- 0,
279
- 1,
280
- 1
281
- ]);
282
- /** Compile */
283
- static async init() {
284
- if (this.#busy) return;
285
- this.#busy = true;
286
- try {
287
- this.#gl = new OffscreenCanvas(this.#WORKLOAD, this.#WORKLOAD).getContext("webgl2");
288
- if (this.#gl == null) throw new Error("WebGL 2 is required");
289
- this.#gl.clearColor(0, 0, 0, 1);
290
- this.#program = this.#gl.createProgram();
291
- if (this.#program == null) throw new Error("Failed to create shader program");
292
- this.#vertexShader = this.#gl.createShader(this.#gl.VERTEX_SHADER);
293
- if (this.#vertexShader == null) throw new Error("Failed to create vertex shader");
294
- this.#gl.shaderSource(this.#vertexShader, NanoPowGlVertexShader);
295
- this.#gl.compileShader(this.#vertexShader);
296
- if (!this.#gl.getShaderParameter(this.#vertexShader, this.#gl.COMPILE_STATUS))
297
- throw new Error(this.#gl.getShaderInfoLog(this.#vertexShader) ?? `Failed to compile vertex shader`);
298
- this.#fragmentShader = this.#gl.createShader(this.#gl.FRAGMENT_SHADER);
299
- if (this.#fragmentShader == null) throw new Error("Failed to create fragment shader");
300
- this.#gl.shaderSource(this.#fragmentShader, NanoPowGlFragmentShader);
301
- this.#gl.compileShader(this.#fragmentShader);
302
- if (!this.#gl.getShaderParameter(this.#fragmentShader, this.#gl.COMPILE_STATUS))
303
- throw new Error(this.#gl.getShaderInfoLog(this.#fragmentShader) ?? `Failed to compile fragment shader`);
304
- this.#gl.attachShader(this.#program, this.#vertexShader);
305
- this.#gl.attachShader(this.#program, this.#fragmentShader);
306
- this.#gl.linkProgram(this.#program);
307
- if (!this.#gl.getProgramParameter(this.#program, this.#gl.LINK_STATUS))
308
- throw new Error(this.#gl.getProgramInfoLog(this.#program) ?? `Failed to link program`);
309
- this.#gl.useProgram(this.#program);
310
- const triangleArray = this.#gl.createVertexArray();
311
- this.#gl.bindVertexArray(triangleArray);
312
- this.#positionBuffer = this.#gl.createBuffer();
313
- this.#gl.bindBuffer(this.#gl.ARRAY_BUFFER, this.#positionBuffer);
314
- this.#gl.bufferData(this.#gl.ARRAY_BUFFER, this.#positions, this.#gl.STATIC_DRAW);
315
- this.#gl.vertexAttribPointer(0, 3, this.#gl.FLOAT, false, 0, 0);
316
- this.#gl.enableVertexAttribArray(0);
317
- this.#uvBuffer = this.#gl.createBuffer();
318
- this.#gl.bindBuffer(this.#gl.ARRAY_BUFFER, this.#uvBuffer);
319
- this.#gl.bufferData(this.#gl.ARRAY_BUFFER, this.#uvPosArray, this.#gl.STATIC_DRAW);
320
- this.#gl.vertexAttribPointer(1, 2, this.#gl.FLOAT, false, 0, 0);
321
- this.#gl.enableVertexAttribArray(1);
322
- this.#uboBuffer = this.#gl.createBuffer();
323
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#uboBuffer);
324
- this.#gl.bufferData(this.#gl.UNIFORM_BUFFER, 144, this.#gl.DYNAMIC_DRAW);
325
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null);
326
- this.#gl.bindBufferBase(this.#gl.UNIFORM_BUFFER, 0, this.#uboBuffer);
327
- this.#gl.uniformBlockBinding(this.#program, this.#gl.getUniformBlockIndex(this.#program, "UBO"), 0);
328
- this.#workBuffer = this.#gl.createBuffer();
329
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#workBuffer);
330
- this.#gl.bufferData(this.#gl.UNIFORM_BUFFER, 32, this.#gl.STREAM_DRAW);
331
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null);
332
- this.#gl.bindBufferBase(this.#gl.UNIFORM_BUFFER, 1, this.#workBuffer);
333
- this.#gl.uniformBlockBinding(this.#program, this.#gl.getUniformBlockIndex(this.#program, "WORK"), 1);
334
- this.#pixels = new Uint8Array(this.#gl.drawingBufferWidth * this.#gl.drawingBufferHeight * 4);
335
- this.#query = this.#gl.createQuery();
336
- } catch (err) {
337
- throw new Error(`WebGL initialization failed. ${err}`);
338
- } finally {
339
- this.#busy = false;
340
- }
341
- }
342
- static reset() {
343
- _NanoPowGl.#query = null;
344
- _NanoPowGl.#workBuffer = null;
345
- _NanoPowGl.#uboBuffer = null;
346
- _NanoPowGl.#uvBuffer = null;
347
- _NanoPowGl.#positionBuffer = null;
348
- _NanoPowGl.#fragmentShader = null;
349
- _NanoPowGl.#vertexShader = null;
350
- _NanoPowGl.#program = null;
351
- _NanoPowGl.#gl = null;
352
- _NanoPowGl.#busy = false;
353
- _NanoPowGl.init();
354
- }
355
- static #logAverages(times) {
356
- let count = times.length, sum = 0, reciprocals = 0, logarithms = 0, truncated = 0, min = 65535, max = 0, rate = 0;
357
- times.sort();
358
- for (let i = 0; i < count; i++) {
359
- sum += times[i];
360
- reciprocals += 1 / times[i];
361
- logarithms += Math.log(times[i]);
362
- min = Math.min(min, times[i]);
363
- max = Math.max(max, times[i]);
364
- if (count < 3 || i > count * 0.1 && i < count * 0.9) truncated += times[i];
365
- }
366
- const averages = {
367
- "Count (frames)": count,
368
- "Total (ms)": sum,
369
- "Rate (f/s)": 1e3 * count * 0.8 / (truncated || sum),
370
- "Minimum (ms)": min,
371
- "Maximum (ms)": max,
372
- "Arithmetic Mean (ms)": sum / count,
373
- "Truncated Mean (ms)": truncated / count,
374
- "Harmonic Mean (ms)": count / reciprocals,
375
- "Geometric Mean (ms)": Math.exp(logarithms / count)
376
- };
377
- console.table(averages);
378
- }
379
- static #draw(work) {
380
- if (this.#gl == null || this.#query == null) throw new Error("WebGL 2 is required to draw and query pixels");
381
- if (this.#workBuffer == null) throw new Error("Work buffer is required to draw");
382
- this.#gl.clear(this.#gl.COLOR_BUFFER_BIT);
383
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, this.#workBuffer);
384
- this.#gl.bufferSubData(this.#gl.UNIFORM_BUFFER, 0, Uint32Array.from(work));
385
- this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null);
386
- this.#gl.beginQuery(this.#gl.ANY_SAMPLES_PASSED_CONSERVATIVE, this.#query);
387
- this.#gl.drawArrays(this.#gl.TRIANGLES, 0, 6);
388
- this.#gl.endQuery(this.#gl.ANY_SAMPLES_PASSED_CONSERVATIVE);
389
- }
390
- static async #checkQueryResult() {
391
- return new Promise((resolve, reject) => {
392
- try {
393
- if (this.#gl == null || this.#query == null) throw new Error("WebGL 2 is required to check query results");
394
- if (this.#gl.getQueryParameter(this.#query, this.#gl.QUERY_RESULT_AVAILABLE)) {
395
- resolve(!!this.#gl.getQueryParameter(this.#query, this.#gl.QUERY_RESULT));
396
- } else {
397
- requestAnimationFrame(async () => {
398
- const result = await _NanoPowGl.#checkQueryResult();
399
- resolve(result);
400
- });
401
- }
402
- } catch (err) {
403
- reject(err);
404
- }
405
- });
406
- }
407
- /**
408
- * Reads pixels into the work buffer, checks every 4th pixel for the 'found'
409
- * byte, converts the subsequent 3 pixels with the nonce byte values to a hex
410
- * string, and returns the result.
411
- *
412
- * @param workBytes - Buffer with the original random nonce value
413
- * @param workHex - Original nonce if provided for a validation call
414
- * @returns Nonce as an 8-byte (16-char) hexadecimal string
415
- */
416
- static #readResult(workBytes, workHex) {
417
- if (this.#gl == null) throw new Error("WebGL 2 is required to read pixels");
418
- this.#gl.readPixels(0, 0, this.#gl.drawingBufferWidth, this.#gl.drawingBufferHeight, this.#gl.RGBA, this.#gl.UNSIGNED_BYTE, this.#pixels);
419
- for (let i = 0; i < this.#pixels.length; i += 4) {
420
- if (this.#pixels[i] !== 0) {
421
- const hex = this.#hexify(workBytes.subarray(4, 8)) + this.#hexify([
422
- this.#pixels[i + 2],
423
- this.#pixels[i + 3],
424
- workBytes[2] ^ this.#pixels[i] - 1,
425
- workBytes[3] ^ this.#pixels[i + 1] - 1
426
- ]);
427
- if (workHex == null || workHex == hex) return hex;
428
- }
429
- }
430
- throw new Error("Query reported result but nonce value not found");
431
- }
432
- /**
433
- * Finds a nonce that satisfies the Nano proof-of-work requirements.
434
- *
435
- * @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
436
- * @param {number} [threshold=0xfffffff8] - Difficulty of proof-of-work calculation
437
- */
438
- static async search(hash, options) {
439
- if (this.#busy) {
440
- return new Promise((resolve) => {
441
- setTimeout(async () => {
442
- const result = this.search(hash, options);
443
- resolve(result);
444
- }, 100);
445
- });
446
- }
447
- this.#busy = true;
448
- if (_NanoPowGl.#gl == null) throw new Error("WebGL 2 is required");
449
- if (this.#gl == null) throw new Error("WebGL 2 is required");
450
- if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new Error(`Invalid hash ${hash}`);
451
- const threshold = typeof options?.threshold !== "number" || options.threshold < 0 || options.threshold > 4294967295 ? 4294967288 : options.threshold;
452
- const effort = typeof options?.effort !== "number" || options.effort < 1 || options.effort > 16 ? 8 : options.effort;
453
- const debug = !!options?.debug;
454
- if (this.#WORKLOAD !== 256 * effort) {
455
- this.#WORKLOAD = 256 * effort;
456
- this.reset();
457
- }
458
- const uboView = new DataView(new ArrayBuffer(144));
459
- for (let i = 0; i < 64; i += 8) {
460
- const uint32 = hash.slice(i, i + 8);
461
- uboView.setUint32(i * 2, parseInt(uint32, 16));
462
- }
463
- uboView.setUint32(128, threshold, true);
464
- uboView.setFloat32(132, 256 * effort, true);
465
- _NanoPowGl.#gl.bindBuffer(_NanoPowGl.#gl.UNIFORM_BUFFER, _NanoPowGl.#uboBuffer);
466
- _NanoPowGl.#gl.bufferSubData(_NanoPowGl.#gl.UNIFORM_BUFFER, 0, uboView);
467
- _NanoPowGl.#gl.bindBuffer(_NanoPowGl.#gl.UNIFORM_BUFFER, null);
468
- let times = [];
469
- let start = performance.now();
470
- let nonce = null;
471
- const seed = new Uint8Array(8);
472
- while (nonce == null) {
473
- start = performance.now();
474
- crypto.getRandomValues(seed);
475
- this.#draw(seed);
476
- const found = await this.#checkQueryResult();
477
- times.push(performance.now() - start);
478
- if (found) {
479
- nonce = this.#readResult(seed);
480
- }
481
- }
482
- this.#busy = false;
483
- if (debug) this.#logAverages(times);
484
- return nonce;
485
- }
486
- /**
487
- * Validates that a nonce satisfies Nano proof-of-work requirements.
488
- *
489
- * @param {string} work - Hexadecimal proof-of-work value to validate
490
- * @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
491
- * @param {number} [threshold=0xfffffff8] - Difficulty of proof-of-work calculation
492
- */
493
- static async validate(work, hash, options) {
494
- if (this.#busy) {
495
- return new Promise((resolve) => {
496
- setTimeout(async () => {
497
- const result = this.validate(work, hash, options);
498
- resolve(result);
499
- }, 100);
500
- });
501
- }
502
- this.#busy = true;
503
- if (_NanoPowGl.#gl == null) throw new Error("WebGL 2 is required");
504
- if (this.#gl == null) throw new Error("WebGL 2 is required");
505
- if (!/^[A-Fa-f0-9]{16}$/.test(work)) throw new Error(`Invalid work ${work}`);
506
- if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new Error(`Invalid hash ${hash}`);
507
- const threshold = typeof options?.threshold !== "number" || options.threshold < 0 || options.threshold > 4294967295 ? 4294967288 : options.threshold;
508
- const debug = !!options?.debug;
509
- const uboView = new DataView(new ArrayBuffer(144));
510
- for (let i = 0; i < 64; i += 8) {
511
- const uint32 = hash.slice(i, i + 8);
512
- uboView.setUint32(i * 2, parseInt(uint32, 16));
513
- }
514
- uboView.setUint32(128, threshold, true);
515
- uboView.setFloat32(132, _NanoPowGl.#WORKLOAD - 1, true);
516
- _NanoPowGl.#gl.bindBuffer(_NanoPowGl.#gl.UNIFORM_BUFFER, _NanoPowGl.#uboBuffer);
517
- _NanoPowGl.#gl.bufferSubData(_NanoPowGl.#gl.UNIFORM_BUFFER, 0, uboView);
518
- _NanoPowGl.#gl.bindBuffer(_NanoPowGl.#gl.UNIFORM_BUFFER, null);
519
- let nonce = null;
520
- const data = new DataView(new ArrayBuffer(8));
521
- data.setBigUint64(0, BigInt(`0x${work}`), true);
522
- const seed = new Uint8Array(data.buffer);
523
- this.#draw(seed);
524
- let found = await this.#checkQueryResult();
525
- if (found) {
526
- try {
527
- nonce = this.#readResult(seed, work);
528
- } catch (err) {
529
- found = false;
530
- }
531
- }
532
- this.#busy = false;
533
- if (found && nonce !== work) throw new Error(`Nonce found but does not match work`);
534
- return found;
535
- }
536
- };
537
-
538
- // src/classes/gpu.ts
539
- var NanoPowGpu = class _NanoPowGpu {
540
- // Initialize WebGPU
541
- static #busy = false;
542
- static #device = null;
543
- static #uboBuffer;
544
- static #gpuBuffer;
545
- static #cpuBuffer;
546
- static #bindGroupLayout;
547
- static #searchPipeline;
548
- static #validatePipeline;
549
- // Initialize WebGPU
550
- static async init() {
551
- if (this.#busy) return;
552
- this.#busy = true;
553
- try {
554
- if (navigator.gpu == null) throw new Error("WebGPU is not supported in this browser.");
555
- const adapter = await navigator.gpu.requestAdapter();
556
- if (adapter == null) throw new Error("WebGPU adapter refused by browser.");
557
- const device = await adapter.requestDevice();
558
- if (!(device instanceof GPUDevice)) throw new Error("WebGPU device failed to load.");
559
- device.lost.then(this.reset);
560
- this.#device = device;
561
- this.setup();
562
- } catch (err) {
563
- throw new Error(`WebGPU initialization failed. ${err}`);
564
- } finally {
565
- this.#busy = false;
566
- }
567
- }
568
- static setup() {
569
- if (this.#device == null) throw new Error(`WebGPU device failed to load.`);
570
- this.#uboBuffer = this.#device.createBuffer({
571
- size: 48,
572
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
573
- });
574
- this.#gpuBuffer = this.#device.createBuffer({
575
- size: 16,
576
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
577
- });
578
- this.#cpuBuffer = this.#device.createBuffer({
579
- size: 16,
580
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
581
- });
582
- this.#bindGroupLayout = this.#device.createBindGroupLayout({
583
- entries: [
584
- {
585
- binding: 0,
586
- visibility: GPUShaderStage.COMPUTE,
587
- buffer: { type: "uniform" }
588
- },
589
- {
590
- binding: 1,
591
- visibility: GPUShaderStage.COMPUTE,
592
- buffer: { type: "storage" }
593
- }
594
- ]
595
- });
596
- const shaderModule = this.#device.createShaderModule({
597
- code: compute_default
598
- });
599
- this.#searchPipeline = this.#device.createComputePipeline({
600
- layout: this.#device.createPipelineLayout({
601
- bindGroupLayouts: [this.#bindGroupLayout]
602
- }),
603
- compute: {
604
- entryPoint: "search",
605
- module: shaderModule
606
- }
607
- });
608
- this.#validatePipeline = this.#device.createComputePipeline({
609
- layout: this.#device.createPipelineLayout({
610
- bindGroupLayouts: [this.#bindGroupLayout]
611
- }),
612
- compute: {
613
- entryPoint: "validate",
614
- module: shaderModule
615
- }
616
- });
617
- }
618
- static reset() {
619
- console.warn(`GPU device lost. Reinitializing...`);
620
- _NanoPowGpu.#cpuBuffer?.destroy();
621
- _NanoPowGpu.#gpuBuffer?.destroy();
622
- _NanoPowGpu.#uboBuffer?.destroy();
623
- _NanoPowGpu.#busy = false;
624
- _NanoPowGpu.init();
625
- }
626
- static #logAverages(times) {
627
- let count = times.length, sum = 0, reciprocals = 0, logarithms = 0, truncated = 0, min = 65535, max = 0, rate = 0;
628
- times.sort();
629
- for (let i = 0; i < count; i++) {
630
- sum += times[i];
631
- reciprocals += 1 / times[i];
632
- logarithms += Math.log(times[i]);
633
- min = Math.min(min, times[i]);
634
- max = Math.max(max, times[i]);
635
- if (count < 3 || i > count * 0.1 && i < count * 0.9) truncated += times[i];
636
- }
637
- const averages = {
638
- "Count (dispatches)": count,
639
- "Total (ms)": sum,
640
- "Rate (d/s)": 1e3 * count * 0.8 / (truncated || sum),
641
- "Minimum (ms)": min,
642
- "Maximum (ms)": max,
643
- "Arithmetic Mean (ms)": sum / count,
644
- "Truncated Mean (ms)": truncated / count,
645
- "Harmonic Mean (ms)": count / reciprocals,
646
- "Geometric Mean (ms)": Math.exp(logarithms / count)
647
- };
648
- console.table(averages);
649
- }
650
- static async #dispatch(pipeline, seed, hash, threshold, passes) {
651
- if (this.#device == null) throw new Error(`WebGPU device failed to load.`);
652
- const uboView = new DataView(new ArrayBuffer(48));
653
- for (let i = 0; i < 64; i += 8) {
654
- const uint32 = hash.slice(i, i + 8);
655
- uboView.setUint32(i / 2, parseInt(uint32, 16));
656
- }
657
- uboView.setBigUint64(32, seed, true);
658
- uboView.setUint32(40, threshold, true);
659
- this.#device.queue.writeBuffer(this.#uboBuffer, 0, uboView);
660
- this.#device.queue.writeBuffer(this.#gpuBuffer, 0, new Uint32Array([0, 0, 0]));
661
- const bindGroup = this.#device.createBindGroup({
662
- layout: this.#bindGroupLayout,
663
- entries: [
664
- {
665
- binding: 0,
666
- resource: {
667
- buffer: this.#uboBuffer
668
- }
669
- },
670
- {
671
- binding: 1,
672
- resource: {
673
- buffer: this.#gpuBuffer
674
- }
675
- }
676
- ]
677
- });
678
- const commandEncoder = this.#device.createCommandEncoder();
679
- const passEncoder = commandEncoder.beginComputePass();
680
- passEncoder.setPipeline(pipeline);
681
- passEncoder.setBindGroup(0, bindGroup);
682
- passEncoder.dispatchWorkgroups(passes, passes);
683
- passEncoder.end();
684
- commandEncoder.copyBufferToBuffer(this.#gpuBuffer, 0, this.#cpuBuffer, 0, 12);
685
- this.#device.queue.submit([commandEncoder.finish()]);
686
- let data = null;
687
- try {
688
- await this.#cpuBuffer.mapAsync(GPUMapMode.READ);
689
- await this.#device.queue.onSubmittedWorkDone();
690
- data = new DataView(this.#cpuBuffer.getMappedRange().slice(0));
691
- this.#cpuBuffer.unmap();
692
- } catch (err) {
693
- console.warn(`Error getting data from GPU. ${err}`);
694
- return this.#dispatch(pipeline, seed, hash, threshold, passes);
695
- }
696
- if (data == null) throw new Error(`Failed to get data from buffer.`);
697
- return data;
698
- }
699
- /**
700
- * Finds a nonce that satisfies the Nano proof-of-work requirements.
701
- *
702
- * @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
703
- * @param {NanoPowOptions} options - Used to configure search execution
704
- */
705
- static async search(hash, options) {
706
- if (this.#busy) {
707
- return new Promise((resolve) => {
708
- setTimeout(async () => {
709
- const result = this.search(hash, options);
710
- resolve(result);
711
- }, 100);
712
- });
713
- }
714
- this.#busy = true;
715
- if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new TypeError(`Invalid hash ${hash}`);
716
- const threshold = typeof options?.threshold !== "number" || options.threshold < 0 || options.threshold > 4294967295 ? 4294967288 : options.threshold;
717
- const effort = typeof options?.effort !== "number" || options.effort < 1 || options.effort > 32 ? 2048 : options.effort * 256;
718
- const debug = !!options?.debug;
719
- let loads = 0;
720
- while (this.#device == null && loads < 20) {
721
- await new Promise((resolve) => {
722
- setTimeout(resolve, 500);
723
- });
724
- }
725
- if (this.#device == null) throw new Error(`WebGPU device failed to load.`);
726
- let times = [];
727
- let start = performance.now();
728
- let nonce = 0n;
729
- do {
730
- start = performance.now();
731
- const random = Math.floor(Math.random() * 4294967295);
732
- const seed = BigInt(random) << 32n | BigInt(random);
733
- const data = await this.#dispatch(this.#searchPipeline, seed, hash, threshold, effort);
734
- nonce = data.getBigUint64(0, true);
735
- this.#busy = !data.getUint32(8);
736
- times.push(performance.now() - start);
737
- } while (this.#busy);
738
- if (debug) this.#logAverages(times);
739
- return nonce.toString(16).padStart(16, "0");
740
- }
741
- /**
742
- * Validates that a nonce satisfies Nano proof-of-work requirements.
743
- *
744
- * @param {string} work - Hexadecimal proof-of-work value to validate
745
- * @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
746
- * @param {NanoPowOptions} options - Options used to configure search execution
747
- */
748
- static async validate(work, hash, options) {
749
- if (this.#busy) {
750
- return new Promise((resolve) => {
751
- setTimeout(async () => {
752
- const result = this.validate(work, hash, options);
753
- resolve(result);
754
- }, 100);
755
- });
756
- }
757
- this.#busy = true;
758
- if (!/^[A-Fa-f0-9]{16}$/.test(work)) throw new TypeError(`Invalid work ${work}`);
759
- if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new TypeError(`Invalid hash ${hash}`);
760
- const debug = !!options?.debug;
761
- const threshold = typeof options?.threshold !== "number" || options.threshold < 0 || options.threshold > 4294967295 ? 4294967288 : options.threshold;
762
- let loads = 0;
763
- while (this.#device == null && loads < 20) {
764
- await new Promise((resolve) => {
765
- setTimeout(resolve, 500);
766
- });
767
- }
768
- if (this.#device == null) throw new Error(`WebGPU device failed to load.`);
769
- const seed = BigInt(`0x${work}`);
770
- const data = await this.#dispatch(this.#validatePipeline, seed, hash, threshold, 1);
771
- const nonce = data.getBigUint64(0, true).toString(16).padStart(16, "0");
772
- const found = !!data.getUint32(8);
773
- this.#busy = false;
774
- if (found && work !== nonce) throw new Error(`Nonce (${nonce}) found but does not match work (${work})`);
775
- return found;
776
- }
777
- };
778
-
779
- // src/classes/index.ts
780
- var isGlSupported;
781
- var isGpuSupported = false;
782
- try {
783
- await NanoPowGpu.init();
784
- isGpuSupported = true;
785
- } catch (err) {
786
- console.warn(`WebGPU is not supported in this environment.`);
787
- isGpuSupported = false;
788
- }
789
- try {
790
- await NanoPowGl.init();
791
- isGlSupported = true;
792
- } catch (err) {
793
- console.warn(`WebGL is not supported in this environment.`);
794
- isGlSupported = false;
795
- }
796
- var NanoPow = isGpuSupported ? NanoPowGpu : isGlSupported ? NanoPowGl : null;
797
-
798
- // src/global.ts
799
- globalThis.NanoPow ??= NanoPow;
800
- globalThis.NanoPowGl ??= NanoPowGl;
801
- globalThis.NanoPowGpu ??= NanoPowGpu;