Skip to content

Objective 11a - Naughty/Nice List with Blockchain Investigation Part 1

Objective

Even though the chunk of the blockchain that you have ends with block 129996, can you predict the nonce for block 130000? Talk to Tangle Coalbox in the Speaker UNpreparedness Room for tips on prediction and Tinsel Upatree for more tips and tools. (Enter just the 16-character hex value of the nonce)

Analysis

In this and the next objectives, you're going to explore and manipulate the blockchain that Santa uses to track his naughty and nice list.

Tip

Watch Professor Qwerty Petabyte's talk Working with the Official Naughty/Nice Blockchain for some important background on this topic.

Tip

Read about the Snowball Fight terminal, as it lays the foundation for completing this task.

Solution

Step 1: Download the following items:

Unpack the tools zip file and copy blockchain.dat and mt19937predictor.py to the same directory.

Step 2: Create a program that extracts the last 624 nonces from the blockchain.dat file, loads them into the predictor's MT array, and then predicts the next several nonces. Use naughty_nice.py as a module, as it contains pre-built functions to read blocks and the data inside them.

Note

The Mersenne-Twister predictor I've chosen to use for this example is able to create 64-bit random numbers, which is necessary for the nonce values found in Santa's blockchain.

#!/usr/bin/env python3
# Requires mt19937predictor.py from
# https://github.com/kmyk/mersenne-twister-predictor

import naughty_nice
import random
from mt19937predictor import MT19937Predictor

predictor = MT19937Predictor()

# Import the official public key
with open('official_public.pem', 'rb') as fh:
    official_public_key = naughty_nice.RSA.importKey(fh.read())

# Read the blockchain data into c2
c2 = naughty_nice.Chain(load=True, filename='blockchain.dat')
print("Number of blocks in chain: %i" % (len(c2.blocks)))

# Verify the blockchain data
print("C2: Block chain verify: %s" % (c2.verify_chain(official_public_key,c2.blocks[0].previous_hash)))

# Select the blocks to load nonces from
interesting_blocks = c2.blocks[-624:]

# Load nonces into Mersenne-Twister array
for i in range(len(interesting_blocks)):
    predictor.setrandbits(interesting_blocks[i].nonce, 64)
    print("%i: Set nonce value %i (%16.16x)" % (interesting_blocks[i].index, interesting_blocks[i].nonce, interesting_blocks[i].nonce))
    index = interesting_blocks[i].index

# Print the next 5 predicted nonces
for i in range(5):
    x = predictor.getrandbits(64)
    print("%i: Predict nonce value %i (%16.16x)" % (index+i+1, x, x))

Step 3: Run the program and use the nonce predicted for block 130000 to answer the objective.

$ ./obj-11a.py
129997: Predict nonce value 13205885317093879758 (b744baba65ed6fce)
129998: Predict nonce value 109892600914328301 (01866abd00f13aed)
129999: Predict nonce value 9533956617156166628 (844f6b07bd9403e4)
130000: Predict nonce value 6270808489970332317 (57066318f32f729d)
130001: Predict nonce value 3451226212373906987 (2fe537f46c10462b)

Answer: 57066318f32f729d