Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making seed a BigInt is unsuitable for many algorithms #18

Open
bakkot opened this issue Nov 17, 2022 · 4 comments
Open

Making seed a BigInt is unsuitable for many algorithms #18

bakkot opened this issue Nov 17, 2022 · 4 comments

Comments

@bakkot
Copy link

bakkot commented Nov 17, 2022

Some PRNGs have state which is similar in size to their seed, but a lot of them have much more internal state. For example, Mersenne twisters (which we should not actually use, it's just a dramatic example) have 2.5KB of state. I don't think we should be trying to represent that as a single BigInt.

(In fact it's actually necessary for the state space to be larger than the size of the output to have good statistical properties, so at a minimum this would be a 128-bit BigInt - not necessarily a problem, but more annoying in many applications than 2 64-bit BigInts.)

So I think the seed getter should be replaced with a state getter (or function) which returns an object which can hold multiple BigInts. E.g. { algorithm: 'mersenne', state: [42n, 33333n, ...] }. And of course the constructor would need to be overloaded to accept a richer state argument.

@tabatkins
Copy link
Collaborator

I'm a little confused - what's the point of multiple BigInts? BigInt has infinite range - how do you deserialize multiple of them into the state vector you actually need?

I'd think what you actually want for large state vectors is a TypedArray, no?

@bakkot
Copy link
Author

bakkot commented Nov 20, 2022

I'm a little confused - what's the point of multiple BigInts?

Basically I'm thinking of multiple 64-bit integers, which is probably what the underlying C++ is going to use because that's how many of the algorithms are defined (e.g. there's a static uint64_t s[4] in xoroshiro).

And you need BigInts rather than Numbers because the Number can't represent a 64-bit integer.

But yes, a TypedArray (probably a BigUint64Array array) works fine too, and is probably more natural.

@tabatkins
Copy link
Collaborator

Yeah, "larger ints" in other langs are usually 64 or 128, but not in JS, which is why I found the suggestion a bit perplexing. ^_^ You didn't clarify that you meant for each BigInt to represent a particular bit width.

But yeah, in that case just using a typedarray seems far easier. I'm happy to allow that!

@bakkot
Copy link
Author

bakkot commented Aug 7, 2024

In light of https://github.com/tc39/proposal-arraybuffer-base64 I am now inclined to say this should be specifically a Uint8Array, to allow easy serializing/deserializing of the state. That's also now the usual direction on the web platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants