If you look at the chatgpt conversation which is linked at the bottom of the article (it will take a minute to load because it is very long), you will see that my initial approach was using matrices over GF(2). I am in the process of writing a blog about how I thought I could solve this quickly using ChatGPT, but unfortunately it took me down a bunch of rabbit holes that didn't work. Ultimately the ideas that did work were my own, but I still think using ChatGPT is useful if you know how to use it right (keep it on a tight leash, more details coming soon).
Back to the matrices... I thought I have an idea using matrices that would solve it really fast. It didn't work. There were dependencies in the matrix that I did not expect that made the idea fail. You can see all the details in the chat log.
With your recommendation, it is not clear to me that you are dealing with the problem that there is an integer addition of the state values to get the outputs. This integer addition ruins the direct usage of linear algebra to solve the problem. The initial approach that ChatGPT suggested, which is its own idea (not mine), was that we could bring in the integer carry bits as unknown variables and derive them via induction. I could come back to that idea, but I am sceptical that will work.
Eventually I got fed up with ChatGPT's implementation and it trying to help debug, which was only slowing me down. It kept trying to change the underlying data structures during the debugging. I had to scold it about that: you cannot change things when you are debugging it.
Ultimately, I did away with the linear algebra and just approached it from some simple observations about how bits affect other bits. It is linear algebra under the hood, but I did not use matrices at this point.
One of the reasons why I wrote the blog is to encourage more people to look at this. We should be able to invert this in 2 or 3 outputs, whereas Z3 requires 5. Nothing I am doing is complex. I would love to see someone produce a tool that breaks it really quickly. And I really mean a tool, not just a statement on why it is weak. We all know it is weak, but web security researchers need tools to use that demonstrate exploits based upon primitives that are wrongly used. So I would strongly encourage people with ideas to implement them and blog about the ones that work.
I have another idea on the plate that I think might bring the search down to 2^20 effort, but need time to work out details. Free time is the hardest thing in life for me to find: I just have a busy life. But I also have a passion for building fast tools and puzzle solving.
Ah, yes, the addition throws a spanner in the works a little. 3 successive Math.random() outputs should definitely be solvable with a 2^32 brute force (~seconds on CPU). I'll try to understand your 2^26 approach a little better though.