# How to calculate a random seed?

For example, we have 126/128 nonces, revealed in cycle 99. /chains/main/blocks/409599/context/raw/json/cycle/98/nonces?depth=1

If I understand correctly, using these nonces we can calculate the random seed. Can anybody explain how to do this?

We will need these operations:

• `blake2b`: size 32
• `concat`: concatenation of byte arrays

Also, let `zero_bytes` be 32 zero bytes.

My answer is based on seed_storage.ml and seed_repr.ml, with some experimentation.

# Initial seeds

Let's start at the beginning.

The initial preserved_cycles+2 = 7 seeds were determined ahead of time, as follows. The first seed is the hash of the empty message:

``````seed[0] = blake2b([]) = 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8
``````

The remaining 6 initial seeds are each computed from the previous:

``````seed[n] = blake2b(concat(seed[n-1], zero_bytes))
``````

This gives the following initial seeds:

``````| cycle | seed                                                             |
|-------+------------------------------------------------------------------|
|     0 | 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8 |
|     1 | c8db55740733852aa18aa82e108e4475b1abcf3f1f077ac966e9cecca86612ec |
|     2 | 270da140de63850f631d09a95eab26dc39cc92f8feae73875c7cf9aaa3bf4cac |
|     4 | 0c7ea5ee0b25b7105f934c6511756ec20abcf5c6eea4d45721c138c3e751469b |
|     6 | 5e695ae038c2bdc54706547fc743eb3564ca5a0b4b5d8e9de2ca4780157ca61e |
``````

# The next cycle's seed

From here, we use the revealed nonces to compute the next seed from the previous seed:

``````seed[n] = seed[n-1]
seed[n] = blake2b(concat(seed[n], zero_bytes))
# then use the revealed nonces:
for nonce in nonces_for[n]:
seed[n] = blake2b(concat(seed[n], nonce))
``````

The nonces are taken in decreasing level order.

For example, to calculate the random seed for cycle 7, we can grab the nonces revealed over the course of cycle 0:

``````# The best level seems to be ((n-5)*4096)-1?
# Warning, this is not complete, see below.
# 8191 = ((7-5)*4096)-1
# 0 = 7-7
curl -s http://localhost:18732/chains/main/blocks/8191/context/raw/json/cycle/0/nonces?depth=1 \
| jq -r '.[] | "\(.[0])\t\(.[1])"' | sort -rnk1 | cut -f2
``````

The first nonce (in decreasing level order) is "1ee95fe66b...", and the last is "d1012e79ab...", so we compute:

``````# seed == "5e695ae038c2bdc54706547fc743eb3564ca5a0b4b5d8e9de2ca4780157ca61e"

# zero nonce
seed = blake2b(concat(seed, "0000000000000000000000000000000000000000000000000000000000000000"))
# seed == "9b7328e5393a466fc47ef16eb74121939b06e6ec4c17295eb25611f1b76d6a33"

# first nonce
seed = blake2b(concat(seed, "1ee95fe66bb3dc2a62195dd41a07a30835e63b91db395aa64150da3decc3be1c"))

# ... the other nonces ...
# seed == "469a48304fc415870289ac8bd875b04107381a2471a878a2a8da16e43dfc5880"

# last nonce
seed = blake2b(concat(seed, "d1012e79abc75ffc4228f69ace060e1003c8fff0aa9d58a2d78816713b72c278"))
# seed == "1bcd1d832aff2d72a8d16a9f9e5f994e177e29eac789138b019f0c4a30c4e5ec"
``````

So far so good:

``````\$ curl http://localhost:18732/chains/main/blocks/24575/context/raw/json/cycle/7/random_seed
"1bcd1d832aff2d72a8d16a9f9e5f994e177e29eac789138b019f0c4a30c4e5ec"
``````

# How to get the nonces?

However, if you keep going, you will run into a problem.

I don't believe it is possible to use `context/raw/json/cycle/<cycle>/nonces` to get all the revealed nonces. If a nonce is revealed just at cycle dawn, I believe it will be deleted by the protocol immediately upon use, before it is made available via the raw context RPC.

The first problem seems to be the revelation in the block at level 200704.

Of course, if you are building an alt-shell, you will naturally acquire the nonces, and if, like me, you are just curious, this doesn't matter.

• Neat explanation, thanks! You made a typo here `seed[n] = blake2b(concat(seed[n-1], nonce))` - it should be `concat(seed[n], nonce)` ;) Btw, I created a gist on C# with generation of a random seed, maybe someone would find it useful. gist.github.com/Groxan/c0f11a896bcf9a43e0fff9ba2e46223b Commented May 16, 2019 at 14:44
• As for the revelation in the block at level 200704 - it was a surprise for me =) I tried to get the seed an it was incorrect until I appended the last nonce. Sadly, there are so many pitfalls that are not described in the docs. Commented May 16, 2019 at 15:03
• Whoops, thanks, that is what I get for trying to write imperative pseudocode. ;)
– Tom
Commented May 16, 2019 at 15:42