I would like a random number for a program with the following qualities:
-
Periodic: The random number needs to be random for a certain window of time. Preferably hourly but could be more. Once the period is over, the next random number can be generated and previously generated values can be regenerated based on seed values which are publicly available.
-
Unpredictable: The next random number cannot be easily determined. The publicly available seed must not be public yet.
-
Verifiable: The seed for the random number should come from some publicly available source. Perhaps a scientific research organization or government body is publishing a daily or hourly number(s). For example, a group of temperatures that are recorded. Or for example, it could be as simple as a website that publishes hourly or daily random numbers.
-
Seed should be at least a 64 bit integer. If it’s too small then the random number could be guessed from a small set.
-
Industrial-strength or exacting randomness is not required. Not interested in extreme, high-precision randomness.
I see https://avkg.com/ generates large, daily random numbers and this is actually very close and if nothing else looks better I will probably use it. Especially since it archives past results and so that satisfies the verifiable requirement. The problem is the site does not have a clean and documented API and it’s not hourly. HTML scraping for this information is not ideal.
Another idea I had was to use a hash of a specific group of people’s latest Tweets (X). Doing something like this would allow for verification. The problem is I don’t know if they will tweet daily or hourly. Also, Elon has now made Twitter (X) non-public so you need to sign in to gather this information.
Another idea is to just create a my own version of AVKG.
Of course, a date will not work since that does not satisfy the above unpredictable requirement.
Any ideas?
Thank you so much.
2
Answers
Given what you’ve written I think I’d just use a symmetric cipher (e.g. ChaCha20) in counter mode to generate requested data, and a KDF (e.g. Argon2) for transitioning between keys.
Your private state would be:
key
the private key used for this periodsalt
the salt used to transition to this keyYour public state would be:
ctr
the current counter valuelog
previously used private keys and saltsWhen somebody makes a request, you’d atomically:
key
andctr
to produce a new block of random data,data
i = len(log)
,ctr
,data
ctr
When you move into the next period, you’d atomically:
key
andsalt
tolog
ctr
to zerosalt
key
using the KDF to mix thissalt
with the previous period’skey
When users want to verify their
data
, they’d:log[i]
andctr
produce theirdata
If users want to verify their
key
was generated securely, they’d:key
fromlog[i-1]
with thesalt
inlog[i]
produces thekey
inlog[i]
Users could anonymously (e.g. from multiple unrelated hosts) request the public state to verify:
Period Price
20240506310 44924
20240506309 44913
20240506308 44897
20240506307 44875
20240506306 44886
20240506305 44895
20240506304 44919
20240506303 44915
20240506302 44920
20240506301 44956
What price will come for period 20240506311
20240506312
20240506313