First Code: The Crypto Layer

First Code: The Crypto Layer

This week, I finally write the first real C++ code for ZooBC.

After two weeks of staring at diagrams, dependency graphs, and architecture notes, it feels almost strange to open the editor and start typing something that actually compiles. But there is no better place to begin than the cryptography layer. In a blockchain system, cryptography is not just another module. It is the ground everything else stands on.

Hash functions link blocks together.
Digital signatures authenticate transactions.
Random number generators decide who produces the next block.

Get any of these wrong, and the chain does not fail gracefully. It breaks completely.

That is why this first step feels heavy, in a good way. Sitting in my lab in Bali, late afternoon light coming through the window, I am very aware that mistakes here would silently poison everything built on top of it.

Choosing the Right Tools

For signatures, I use libsodium and its Ed25519 implementation. For hashing, OpenSSL. These are not trendy choices, but they are boring in the best possible way. Both libraries are battle-tested, widely audited, and provide constant-time implementations that resist timing attacks.

I have no interest in reinventing cryptography. The job here is not to be clever, but to be correct.

The interfaces are clean, minimal, and explicit. Keys are immutable once created. Buffers are sized deliberately. Ownership is obvious. No surprises.

The Real Challenge: Deterministic Randomness

The part that demands the most attention is the random number generator.

ZooBC relies on deterministic randomness for consensus. Blocksmith selection must produce the same result on every node, every time, given the same inputs. If even a single bit differs, nodes will disagree on who produces the next block, and the network fractures.

ZooBC uses xoroshiro128+, seeded deterministically from the block seed. This is not negotiable. Every node must generate the exact same random sequence.

To get this right, I go back to the Go implementation and trace the seeding path line by line, not trusting memory or assumptions.

The process is precise:

  • Concatenate the prefix "zbc-blocksmith" with the block seed
  • Hash the result using SHA3-256, producing 32 bytes
  • Interpret those bytes as a big-endian integer
  • Extract the low 64 bits
  • Feed that into splitmix64 to generate two 64-bit values
  • Use those values to initialize xoroshiro128+

There is no room for interpretation here. Every constant matters. Every shift matters.

Verifying, Not Assuming

I do not trust myself to get this right on the first try.

So I create test vectors in Go. Known inputs, known outputs. Then I replicate the same logic in C++ and compare results bit by bit. Only when both implementations produce identical sequences do I move forward.

The constants are unforgiving. splitmix64 relies on 0x9E3779B97F4A7C15. xoroshiro128+ rotates by 24 and 37 bits. The output uses addition, not XOR. One wrong constant, one wrong operation, and nodes would silently disagree on block producer selection forever.

Here is the core of the implementation:

void Xoroshiro128Plus::SeedFromInt64(int64_t seed) {
    Splitmix64 sm(seed);
    state_[0] = sm.Next();  // First splitmix output
    state_[1] = sm.Next();  // Second splitmix output
}

uint64_t Xoroshiro128Plus::Next() {
    uint64_t s0 = state_[0];
    uint64_t s1 = state_[1];
    uint64_t result = s0 + s1;  // Addition, not XOR
    s1 ^= s0;
    state_[0] = Rotl(s0, 24) ^ s1 ^ (s1 << 16);
    state_[1] = Rotl(s1, 37);
    return result;
}

This code is small, but it carries a lot of weight.

A Quiet Milestone

At the end of the day, there is no visible product. No UI. No running node. Just a cryptography module and a verified random number generator.

But it matters.

The RNG is now proven to behave identically across implementations. Given the same block seed, both Go and C++ select the same blocksmith, every time. That single fact removes an entire class of consensus bugs before they can exist.

It is a quiet milestone, but a real one.

ZooBC has written its first line of code again, and this time, it starts from solid ground.