UNPKG

js-randomness-predictor

Version:

Predict Math.random output in Node, Deno, Bun, Chrome, Firefox, and Safari

2 lines (1 loc) 9.23 kB
import*as m from"z3-solver-jsrp";class w extends Error{constructor(t){t=t===void 0?"Cannot solve state. Unable to make accurate predictions.":t,super(t),this.name="UnsatError",Object.setPrototypeOf(this,new.target.prototype)}}class g extends Error{constructor(t){super(t),this.name="InsufficientSequenceLengthError",Object.setPrototypeOf(this,new.target.prototype)}}class y extends Error{constructor(t){super(t),this.name="UnexpectedRuntimeError",Object.setPrototypeOf(this,new.target.prototype)}}function u(i){return i&0xffffffffffffffffn}class a{constructor(){}static symbolic(t){let e=t[0];e=e.xor(e.shl(23)),e=e.xor(e.lshr(17)),e=e.xor(t[1]),e=e.xor(t[1].lshr(26)),t[0]=t[1],t[1]=e}static symbolicArithmeticShiftRight(t){let e=t[0];e=e.xor(e.shl(23)),e=e.xor(e.shr(17)),e=e.xor(t[1]),e=e.xor(t[1].shr(26)),t[0]=t[1],t[1]=e}static concreteBackwards(t){let e=t[1]^t[0]>>26n^t[0];e=u(e^e>>17n^e>>34n^e>>51n),e=u(e^e<<23n^e<<46n),t[1]=t[0],t[0]=e}static concrete(t){let e=t[0];e^=u(e<<23n),e^=u(e>>17n),e^=t[1],e^=u(t[1]>>26n),t[0]=t[1],t[1]=e}static concreteArithmeticShiftRight(t){let e=u(t[0]);e^=u(e<<23n),e^=this.#s(e,17n),e^=t[1],e^=this.#s(t[1],26n),t[0]=t[1],t[1]=u(e)}static#s(t,e){const s=u(t>>e);if((t&1n<<63n)===0n)return s;const o=(1n<<e)-1n<<64n-e;return s|o}}class p{sequence;#s=Math.pow(2,53);#t=[0n,0n];constructor(t){this.sequence=t}async predictNext(){this.#t[0]===0n&&this.#t[1]===0n&&await this.#e();const t=this.#i(this.#t[0]);return a.concreteBackwards(this.#t),t}async#e(){try{const{Context:t}=await m.init(),e=t("main"),s=new e.Solver,n=e.BitVec.const("ss0",64),o=e.BitVec.const("ss1",64),r=[n,o],h=[...this.sequence].reverse();for(const f of h){a.symbolic(r);const l=this.#n(f);s.add(r[0].lshr(11).eq(e.BitVec.val(l,64)))}if(await s.check()!=="sat")throw new w;const c=s.model();this.#t=[c.get(n).value(),c.get(o).value()]}catch(t){return Promise.reject(t)}}#n(t){const e=Math.floor(t*this.#s);return BigInt(e)}#i(t){return Number(t>>11n)/this.#s}}class S{sequence;#s=0x1fffffffffffffn;#t=Math.pow(2,53);#e=[0n,0n];constructor(t){this.sequence=t}async predictNext(){return this.#e[0]===0n&&this.#e[1]===0n&&await this.#n(),a.concrete(this.#e),this.#r(u(this.#e[0]+this.#e[1]))}async#n(){try{const{Context:t}=await m.init(),e=t("main"),s=new e.Solver,n=e.BitVec.const("ss0",64),o=e.BitVec.const("ss1",64),r=[n,o];for(const f of this.sequence){a.symbolic(r);const l=this.#i(f),v=r[0].add(r[1]).and(e.BitVec.val(this.#s,64));s.add(v.eq(e.BitVec.val(l,64)))}if(await s.check()!=="sat")throw new w;const h=s.model(),c=[h.get(n).value(),h.get(o).value()];for(const f of this.sequence)a.concrete(c);this.#e=c}catch(t){return Promise.reject(t)}}#i(t){return BigInt(Math.floor(t*this.#t))}#r(t){return Number(t&this.#s)/this.#t}}class b{constructor(){}static isDeno(){return typeof globalThis.Deno<"u"&&typeof Deno.version<"u"&&typeof Deno.version.deno=="string"}static isBun(){return typeof globalThis.Bun<"u"&&typeof Bun.version<"u"&&typeof process.versions.bun=="string"}static isNode(){return!this.isDeno()&&!this.isBun()&&typeof process.versions.node<"u"&&typeof process.versions.node=="string"}static isFirefox(){return typeof window<"u"&&navigator.userAgent.indexOf("Firefox")>-1}static isChrome(){return typeof window!==void 0&&navigator.userAgent.indexOf("Chrome")>-1}static isSafari(){return typeof window!==void 0&&navigator.userAgent.indexOf("Safari")>-1}static type(){if(this.isNode())return"node";if(this.isDeno())return"deno";if(this.isBun())return"bun";if(this.isChrome())return"chrome";if(this.isSafari())return"safari";if(this.isFirefox())return"firefox";throw new y}}class B{sequence;#s=64;#t=4;#e=0x000fffffffffffffn;#n=0x3ff0000000000000n;#i=Math.pow(2,53);#r=this.#h();#c;#o=[0n,0n];constructor(t){if(t&&t.length>=this.#s)throw new Error(`sequence.length must be less than '${this.#s}', got '${t.length}'`);if(!t){if(!b.isNode())throw new y("Expected NodeJS runtime! Unable to auto-generate sequence, please provide one.");t=Array.from({length:this.#t},Math.random)}this.sequence=t,this.#c=this.#a()}async predictNext(){this.#o[0]===0n&&this.#o[1]===0n&&await this.#f();const t=this.#c.toDouble(this.#o);return a.concreteBackwards(this.#o),t}setNodeVersion(t){this.#r=t,this.#c=this.#a()}#h(){const[t,e,s]=process.versions.node.split(".").map(Number);return{major:t,minor:e,patch:s}}#a(){const{major:t}=this.#r;return t<=11?{recoverMantissa:e=>{const s=Buffer.alloc(8);return s.writeDoubleLE(e+1,0),s.readBigUInt64LE(0)&this.#e},toDouble:e=>{const s=e[0]+e[1],n=Buffer.alloc(8);return n.writeBigUInt64LE(s&this.#e|this.#n,0),n.readDoubleLE(0)-1},constrainMantissa:(e,s,n,o)=>{const r=s[0].add(s[1]).and(o.BitVec.val(this.#e,64));n.add(r.eq(o.BitVec.val(e,64)))}}:t<=23?{recoverMantissa:e=>{const s=Buffer.alloc(8);return s.writeDoubleLE(e+1,0),s.readBigUInt64LE(0)&this.#e},toDouble:e=>{const s=Buffer.alloc(8);return s.writeBigUInt64LE(e[0]>>12n|this.#n,0),s.readDoubleLE(0)-1},constrainMantissa:(e,s,n,o)=>{n.add(s[0].lshr(12).eq(o.BitVec.val(e,64)))}}:{recoverMantissa:e=>{const s=Math.floor(e*this.#i);return BigInt(s)},toDouble:e=>Number(e[0]>>11n)/this.#i,constrainMantissa:(e,s,n,o)=>{n.add(s[0].lshr(11).eq(o.BitVec.val(e,64)))}}}async#f(){try{const{Context:t}=await m.init(),e=t("main"),s=new e.Solver,n=e.BitVec.const("ss0",64),o=e.BitVec.const("ss1",64),r=[n,o],h=[...this.sequence].reverse();for(const f of h){a.symbolic(r);const l=this.#c.recoverMantissa(f);this.#c.constrainMantissa(l,r,s,e)}if(await s.check()!=="sat")throw new w;const c=s.model();this.#o=[c.get(n).value(),c.get(o).value()]}catch(t){return Promise.reject(t)}}}class x{sequence;#s=6;#t=[0n,0n];#e;#n;#i=0x1fffffffffffffn;#r=Math.pow(2,53);constructor(t){if(t.length<this.#s)throw new g(`sequence length must be >= 6 : got ${t.length}`);this.#e=e=>a.symbolicArithmeticShiftRight(e),this.#n=e=>a.concreteArithmeticShiftRight(e),this.sequence=t}async predictNext(){return this.#t[0]===0n&&this.#t[1]===0n&&await this.#c(()=>this.#o(),()=>(this.#e=t=>a.symbolic(t),this.#n=t=>a.concrete(t),this.#o())),this.#n(this.#t),this.#a(u(this.#t[0]+this.#t[1]))}async#c(t,e){try{return await t()}catch{return await e()}}async#o(){try{const{Context:t}=await m.init(),e=t("main"),s=new e.Solver,n=e.BitVec.const("ss0",64),o=e.BitVec.const("ss1",64),r=[n,o];for(const f of this.sequence){this.#e(r);const l=this.#h(f),v=r[0].add(r[1]).and(e.BitVec.val(this.#i,64));s.add(v.eq(e.BitVec.val(l,64)))}if(await s.check()!=="sat")throw new w;const h=s.model(),c=[h.get(n).value(),h.get(o).value()];for(const f of this.sequence)this.#n(c);this.#t=c}catch(t){return Promise.reject(t)}}#h(t){return BigInt(Math.floor(t*this.#r))}#a(t){return Number(t&this.#i)/this.#r}}function I(i=1){const t=[];for(let e=0;e<i;e++)t.push(Math.random());return t}class E{sequence;#s=6;#t=[0n,0n];#e=t=>a.symbolic(t);#n=t=>a.concrete(t);#i=0x1fffffffffffffn;#r=Math.pow(2,53);constructor(t){if(t&&t.length<this.#s)throw new g(`sequence length must be >= 6 : got ${t.length}`);if(!t){if(!b.isBun())throw new y("Expected Bun runtime! Unable to auto-generate sequence, please provide one.");t=I(this.#s)}this.sequence=t}async predictNext(){return this.#t[0]===0n&&this.#t[1]===0n&&await this.#c(()=>this.#o(),()=>(this.#e=t=>a.symbolicArithmeticShiftRight(t),this.#n=t=>a.concreteArithmeticShiftRight(t),this.#o())),this.#n(this.#t),this.#a(u(this.#t[0]+this.#t[1]))}async#c(t,e){try{return await t()}catch{return await e()}}async#o(){try{const{Context:t}=await m.init(),e=t("main"),s=new e.Solver,n=e.BitVec.const("ss0",64),o=e.BitVec.const("ss1",64),r=[n,o];for(const f of this.sequence){this.#e(r);const l=this.#h(f),v=r[0].add(r[1]).and(e.BitVec.val(this.#i,64));s.add(v.eq(e.BitVec.val(l,64)))}if(await s.check()!=="sat")throw new w;const h=s.model(),c=[h.get(n).value(),h.get(o).value()];for(const f of this.sequence)this.#n(c);this.#t=c}catch(t){return Promise.reject(t)}}#h(t){return BigInt(Math.floor(t*this.#r))}#a(t){return Number(t&this.#i)/this.#r}}class _{sequence;#s=Math.pow(2,53);#t=[0n,0n];constructor(t){if(!t){if(!b.isDeno())throw new y("Expected Deno runtime! Unable to auto-generate sequence, please provide one.");t=Array.from({length:4},Math.random)}this.sequence=t}async predictNext(){this.#t[0]===0n&&this.#t[1]===0n&&await this.#e();const t=this.#i(this.#t[0]);return a.concreteBackwards(this.#t),t}async#e(){try{const{Context:t}=await m.init(),e=t("main"),s=new e.Solver,n=e.BitVec.const("ss0",64),o=e.BitVec.const("ss1",64),r=[n,o],h=[...this.sequence].reverse();for(const f of h){a.symbolic(r);const l=this.#n(f);s.add(r[0].lshr(11).eq(e.BitVec.val(l,64)))}if(await s.check()!=="sat")throw new w;const c=s.model();this.#t=[c.get(n).value(),c.get(o).value()]}catch(t){return Promise.reject(t)}}#n(t){const e=Math.floor(t*this.#s);return BigInt(e)}#i(t){return Number(t>>11n)/this.#s}}const d={node:i=>new B(i),firefox:i=>new S(i),chrome:i=>new p(i),safari:i=>new x(i),bun:i=>new E(i),deno:i=>new _(i)},M=d.node,N=d.firefox,A=d.chrome,T=d.safari,q=d.bun,V=d.deno;export{E as BunRandomnessPredictor,p as ChromeRandomnessPredictor,_ as DenoRandomnessPredictor,S as FirefoxRandomnessPredictor,B as NodeRandomnessPredictor,x as SafariRandomnessPredictor,q as bun,A as chrome,d as default,V as deno,N as firefox,M as node,T as safari};