Hacker Newsnew | past | comments | ask | show | jobs | submit | ScottContini's commentslogin

Also: I just realised who the person is that you were replying to, tptacek. Maybe you should Google his name. He's well known in cryptography, glad he is on my side! :-)


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.


The blog is not about going from one known internal state to the previous internal state.

It is about not knowing the internal state but figuring it out after having 2 (or 3) consecutive outputs of the random number generator.


You can call it recreational cryptography. I am no longer a professional cryptographer: I used to be. Now I have a full time job in the software industry and a family with kids. I don't have a lot of free time to work on cryptography like professional cryptographers do.

The person you replied to is correct. To my knowledge, the best inversion of Math.random( ) is this one: https://github.com/PwnFunction/v8-randomness-predictor . It takes 5 outputs from Math.random( ) to determine the seed. My research included a 2^50 algorithm to get it with 3 outputs. If there is a better implementation out there that does it in less than 2^50 work for 3 outputs, could you please provide a link to the implementation?

Also, as I said in the blog, this is a first step. I think I can bring it down by a factor of 2^6 with another trick I am working on, but details are still being tested. As the saying goes, attacks always get better, never worse.

The blog is also to encourage the aspiring or amateur cryptographer to have a look themselves. Nothing in my research is particularly deep, so I hope it shows a wider audience that what cryptographers do doesn't always require complex mathematics. This is a simple attack and I thought it was worth blogging about.

I have another blog about why I left cryptography. Part of it is about being stuck in doing research that has no practical implications. To a real cryptographer, attacking XorShift128+ and Math.random( ) may seem uninteresting. I have a different view. Engineers make mistakes and use the wrong tools for the job all the time. We tell them it is wrong, but it is so much more powerful to prove it. When I looked at CVE-2025-7783, I just shook my head: the web security community is stuck using less than ideal tools (requiring 5 outputs to invert the algorithm) because the cryptographic community does not value producing tools to invert things that are not designed for cryptographic purposes. I think this attitude is doing a disfavour to the web security community.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: