CRYPTARCHIA-PROTOCOL

FieldValue
NameCryptarchia Protocol
Slug92
Statusraw
CategoryStandards Track
EditorDavid Rusu [email protected]
ContributorsÁlvaro Castro-Castilla [email protected], Giacomo Pasini [email protected], Thomas Lavaur [email protected], Mehmet [email protected], Marcin Pawlowski [email protected], Daniel Sanchez Quiros [email protected], Youngjoon Lee [email protected], Filip Dimitrijevic [email protected]

Timeline

  • 2026-05-2967e498e — chore: fix math issues (#350)
  • 2026-05-28d45eed2 — Chore: mirror blochain specs into github/mdbook (#347)

Revision History

VersionChangesDate
1.0.0Initial revision.2026-01-20
1.0.1Replaced Logos Blockchain name with Logos Blockchain2026-04-17
1.0.2Added details for block root computation2026-05-26

Introduction

Cryptarchia is the consensus protocol of the Logos Blockchain’s Bedrock layer. This document specifies how Bedrock comes to agreement to a single history of blocks.

The values that Cryptarchia optimizes for are resilience and privacy. These come at the cost of block times and finality. These values have significant implications on user experience and we should understand them well.

Resilience

In consensus, we are presented with a choice of prioritizing either safety or liveness in the presence of catastrophic failure (this is a re-formalization of the CAP theorem). Choosing safety means the chain never forks, instead the chain halts until the network heals. On the other hand, choosing liveness (a la Bitcoin/Ethereum) means that block production continues but finality will stall, leading to confusion around which blocks are on the honest chain.

On the surface both options seem to provide similar guarantees. If finality is delayed indefinitely, is this not equivalent to a halted chain? The differences come down to how safety or liveness is implemented.

Prioritizing Safety

Chains that provide a safety guarantee do so using quorum-based consensus. This requires a known set of participants (i.e. a permissioned network) and extensive communication between them to reach agreement. This restricts the number of participants in the network. Furthermore, quorum based consensus can only tolerate up to 1/3rd of the participants becoming faulty.

A small participant set and low threshold for faults generally pushes these networks to put large barriers to entry, either through large staking requirements or politics.

Prioritizing Liveness

Chains that prioritize liveness generally do so by relying on fork choice rules such as the longest chain rule from Nakamoto consensus. These protocols allow each participant to make a local choice about which fork to follow, and therefore do not require quorums and thus can be permissionless.

Additionally, due to a lack of quorums, these protocols can be quite message efficient. Thus, participation does not need to be artificially reduced to remain within bandwidth restrictions.

These protocols tolerate up to 1/2 of participants becoming faulty. The large fault tolerance threshold and the large number of participants provides for much higher resilience to corruption.

Privacy

The motivation behind the design of Cryptarchia can be boiled down to this statement:

A block proposer should not feel the need to self-censor when proposing a block.

Working to give leaders confidence in this statement has had ripple effects throughout the protocol, including that:

  • The block proposals should not be linkable to a leader. An adversary should not be able to connect together the block proposals of a leader in order to build a profile. In particular, one should not be able to infer a proposer's stake from their past on-chain activity.
  • Cryptarchia must not reveal the stake of the leader - that is, it must be a Private Proof of Stake (PPoS) protocol. If the activity of the leader reveals their stake values (e.g. through weighted voting), then this value can be used to reduce the anonymity set for the leader by bucketing the leader as high/low stake and can open him up to targeting.
  • Leaders should be protected against network triangulation attacks. This is outside of the scope of this document, but it suffices to say that in-protocol cryptographic privacy is not sufficient to guarantee a leader's privacy. This topic is dealt with directly in [1.0.0] Blend Protocol.

Limitations of Cryptarchia V1

Despite our best efforts, we cannot provide perfect privacy and censorship resistance to all parties. In particular:

  • We are unable to protect leaders from leaking information about themselves based on the contents of blocks they propose. The tagging attack is an example of this, where an adversary may distribute a transaction to only a small subset of the network. If the block proposal includes this transaction, the adversary learns that the leader was one of those nodes in that subset.
  • The leader is a single point of failure (SPOF). Despite all the efforts we go through to protect the leader, the network can be easily censored by the leader. The leader may choose to exclude certain types of transactions from blocks, leading to a worse UX for targeted parties.

As far as we can tell, these limitations are not insurmountable and we have sketches towards solutions that we will develop in following iterations of the protocol.

Overview

Cryptarchia is a probabilistic consensus protocol with properties similar to Bitcoin’s Nakamoto Consensus.

At a high level, Cryptarchia divides time into slots and at each slot, a leadership lottery is run. To participate in the lottery, a node must have held stake in the chain in the form of a note for a minimum time period. Given a sufficiently aged note, you can check if it has won a slot lottery by cryptographically flipping a weighted coin. The weight of the coin is proportional to the value of your note, thus higher valued notes lead to increased chances of winning. To ensure privacy and avoid revealing the note value, this lottery result is proven within a ZK proof system.

Our design starts from the solid foundation provided by Ouroboros Crypsinous: Privacy-Preserving Proof-of-Stake eprint.iacr.org and builds upon it, incorporating the latest research at the intersection of cryptography, consensus and network engineering.

Protocol

Constants

SymbolNameDescriptionValue
slot activation coefficientThe target rate of occupied slots. Not all slots contain blocks, many are empty. (see ANALYSIS-BLOCK-TIMES-BLEND-NETWORK for analysis leading to the choice of value)1/30
security parameterBlock depth finality. Blocks deeper than on any given chain are considered immutable.2160 blocks
noneslot lengthThe duration of a single slot.1 second
MAX_BLOCK_SIZEmax block sizeThe maximum size of the block body (not including the header)1 MB
MAX_BLOCK_TXSmax block transactionsThe maximum number of transactions in a block1024

Notation

SymbolNameDescriptionValue
slot security parameterSufficient slots such that blocks have been produced with high probability.
the block treeThis is the block tree observed by a node.
tips of block tree The set of concurrent forks of some block tree .
tip of local chainThe chain that a node considers to be the honest chain.
the latest immutable blockThe latest block which was committed (finalized) by the chain maintenance.
slot numberIndex of slot. denotes the genesis slot.
epoch numberIndex of epoch. denotes the genesis epoch.

Latest Immutable Block

The latest immutable block is the most recent block considered permanently finalized. The blocks deeper than in the local chain are never to be reorganized.

This is maintained locally by the Chain Maintenance procedure. When the Online fork choice rule is in use, corresponds to the -deep block. However, it may be deeper than the -deep block if the fork choice rule has been switched from Online to Bootstrap. Unlike the -deep block, does not advance as new blocks are added unless the Online fork choice rule is used.

The details of fork choice rule transitions are defined in the bootstrap spec: [1.0.0] Cryptarchia Bootstrapping & Synchronization

Slot

Time is divided up into slots of equal length, where one instance of the leadership lottery is held in each slot. A slot is said to be occupied if some validator has won the leadership lottery and proposed a block for that slot, otherwise the slot is said to be unoccupied.

Epoch

Cryptarchia has a few global variables that are adjusted periodically in order for consensus to function. Namely, we need:

  • Dynamic participation, thus the eligible notes must be refreshed regularly.
  • An unpredictable source of randomness for the leadership lottery. This source of randomness is derived from in-protocol activity and thus must be selected carefully to avoid giving adversaries an advantage.
  • Approximately constant block production rate achieved by dynamically adjusting the lottery difficulty based on observed participation levels.

The order in which these variables are calculated is important and is done w.r.t. the epoch schedule.

Epoch Schedule

An epoch is divided into 3 phases, as outlined below.

Epoch PhasePhase LengthDescription
Stake Distribution Snapshot slotsA snapshot of note commitments are taken at the beginning of the epoch. We wait for this value to finalize before entering the next phase.
Buffer phase slotsAfter the stake distribution is finalized, we wait another slot finality period before entering the next phase. This is to further ensure that there is at least one honest leader contributing to the epoch nonce randomness. If an adversary can predict the nonce, they can grind their coin secret keys to gain an advantage.
Lottery Constants Finalization slotsOn the slot into the epoch, the epoch nonce and the inferred total stake can be computed. We wait another slots for these values to finalize.

The epoch length is the sum of the individual phases: slots.

Epoch State

The epoch state holds the variables derived over the course of the epoch schedule. It is the 3-tuple described below.

SymbolNameDescriptionValue
Eligible Leader Notes CommitmentA commitment to the set of notes eligible for leadership.See Eligible Leader Notes
Epoch NonceRandomness used in the leadership lottery (selected once per epoch)See Epoch Nonce
Inferred Total Stake (Lottery Difficulty)Total stake inferred from watching the results of the lottery during the course of the epoch. is used as the stake relativization constant for the following epoch.See Total Stake Inference

Eligible Leader Notes

A note is eligible to participate in the leadership lottery if it has not been spent and was a member of the note set at the beginning of the previous epoch, i.e. they are members of .

Note Ageing

If an adversary knows the epoch nonce , they may grind a note that wins the lottery more frequently than should be statistically expected. Thus, it’s critical that notes participating in the lottery are sufficiently old to ensure that they have no predictive power over .

Epoch Nonce

The epoch nonce is evolved after each block.

Given block where

  • is the parent of block
  • is the slot that is occupying.
  • is the epoch nonce entropy contribution from the block’s leadership proof

Then, is derived as

where is the domain separator EPOCH_NONCE_V1, maps the slot number to the corresponding scalser in Poseidon’s scalar field and is Poseidon2 as specified in [1.0.2] Common Cryptographic Components .

The epoch nonce used in the next epoch is where is the last block before the start of the “Lottery Constants Finalization” phase in the epoch schedule.

Total Stake Inference

Given that stake is private in Cryptarchia, and that we want to maintain an approximately constant block rate, we must therefore adjust the difficulty of the slot lottery somehow based on the level of participation. The details can be found in the following document:

[1.0.0] Total Stake Inference

Epoch State Pseudocode

At the start of each epoch, each validator must derive the new epoch state variables. This is done through the following protocol:

:

The genesis epoch state is hardcoded upon chain initialization.

    

The epoch state is derived w.r.t. observations in the previous epoch. Here we compute the slot at the start of the previous epoch. We will query observations relative to this slot.

    

Notes eligible for leadership lottery are those present in the commitment root at the start of the previous epoch.

    

The epoch nonce for epoch is the value of at the beginning of the lottery constants finalization phase in the epoch schedule

    

Total active stake is inferred from the number of blocks produced in the previous epoch during the stake freezing phase. It is also derived from the previous estimate of total stake, thus we recurse here to retrieve the previous epochs estimate

    

The number of blocks produced during the first slots of the previous epoch

    

    

    

Leadership Lottery

A lottery is run for every slot to decide who is eligible to propose a block. For each slot, we can have 0 or more winners. In fact, it’s desirable to have short slots and many empty slots to allow for the network to propagate blocks and to reduce the chances of two leaders winning the same slot which are guaranteed forks.

Proof of Leadership

The specifications of how a leader can prove that they have won the lottery are specified in the following document:

Leader Rewards

As an incentive for producing blocks, leaders are rewarded with every block proposal. The rewarding protocol is specified in [1.0.0] Anonymous Leaders Reward Protocol.

Block Chain

Fork Choice Rule

We use two fork choice rules, one during bootstrapping and a second once a node completes bootstrapping.

During bootstrapping, we must be resilient to malicious peers feeding us false chains, this calls for a more expensive fork choice rule that can differentiate between malicious long-range attacks and honest chains.

After bootstrapping we commit to the most honest looking chain we found and switch to a fork choice rule that rejects chains that diverge by more than blocks

[1.0.0] Cryptarchia Fork Choice Rule

Block ID

Block ID is defined by the hash of the block header Block Header, where hash is Blake2b as specified in [1.0.2] Common Cryptographic Components

def block_id(header: Header) -> hash
    return hash(
        b"BLOCK_ID_V1",
        header.bedrock_version,
        header.parent_block,
        header.slot.to_bytes(8, byteorder='little'),
        header.block_root,
        # PoL fields
        header.proof_of_leadership.leader_voucher,
        header.proof_of_leadership.entropy_contribution,
        header.proof_of_leadership.proof.serialize(),
        header.proof_of_leadership.leader_key.compressed(),
    )

Block Header

class Header:                                # 297 bytes
      bedrock_version: byte                    # 1 bytes
      parent_block: hash                       # 32 bytes
      slot: int                                # 8 bytes
      block_root: hash                         # 32 bytes
      proof_of_leadership: ProofOfLeadership   # 224 bytes

class ProofOfLeadership:                     # 224 bytes
      leader_voucher: zkhash                   # 32 bytes
      entropy_contribution: zkhash             # 32 bytes
      proof: Groth16Proof                      # 128 bytes
      leader_key: Ed25519PublicKey             # 32 bytes

Block

[1.1.1] Block Construction, Validation and Execution

Block Header Validation

Given block and the block tree where:

  • is the header defined in Header
  • is the sequence of transactions in the block

We say returns True if all of the following constraints hold, otherwise it returns False.

  1. Ensure bedrock version number.

  2. Ensure block size is smaller than the maximum allowed block size

  3. Ensure the number of transactions in the block is below the limit

  4. Ensure block root is over the transaction list. Compute the block root by using transaction hashes (see 🔀[1.5.0] Mantle - Mantle Transaction Hash) as leaves, and 0 to represent the hash of an empty transaction, padding leaves to the closest power of two.

  5. Ensure the block’s slot comes after the parent block’s slot.

  6. Ensure this block’s slot time has elapsed. Local time is used in this validation. See Clocks for discussion around clock synchronization.

  7. Ensure we have already accepted the block’s parent into the block tree.

  8. Ensure the block comes after the latest immutable block. Assuming that prunes all forks diverged deeper than , this step, along with step 5, ensures that is descendant from . If all forks cannot be pruned completely in the implementation, this step must be replaced with , which checks whether is an ancestor of .

  9. Verify the leader’s right to propose and ensure it is the one proposing this block: Given leadership proof , where

A leaders proposal is valid if

  • Ensure that the leader who won the lottery is actually proposing this block since PoL’s are not bound to blocks directly.

Chain Maintenance

We define the chain maintenance procedure that governs how the block tree is updated.

Note: It’s assumed that block contents have already been validated by the execution layer w.r.t. the parent block’s execution state.

:

if :

Either we’ve already seen or it’s invalid, in both cases we ignore this block

    

Explicitly commit to the -deep block if the Online Fork Choice Rule is being used.

    

Commit

We define the procedure that commits to the block, which is deep from . This procedure computes the new latest immutable block .

Compute the latest immutable block, which is deep from .

Prune all forks diverged deeper than , so that future blocks on those forks can be rejected by Block Header Validation.

Fork Pruning

We define the fork pruning procedure that removes all blocks which are part of forks diverged deeper than a certain block.

If is a fork diverged deeper than , prune the fork.

    

    

      

Remove all blocks in the chain within range from .

    

    

Versioning and Protocol Upgrades

Protocol versions are signalled through the bedrock_version field of the block header. Protocol upgrades need to be co-ordinated well in advance to ensure that node operators have enough time to update their node. We will use block height to schedule the activation of protocol updates. E.g. bedrock version 35 will be active after block height 32000.

Annexes

Proof of Stake vs. Proof of Work

From a privacy and resiliency point of view, Proof of Work is highly attractive. The amount of hashing power of a node is private, they can provide a new public key for each block he mines ensuring that his blocks cannot be connected by this identity, and PoW is not susceptible to long range attacks as is PoS. Unfortunately, it is wasteful and demands that leaders have powerful machines. We want to ensure strong decentralization by having a low barrier to entry and we believe we can achieve a good enough level of security given by having participants have an economic stake in the protocol.

Clocks

Cryptarchia depends on honest nodes having relatively in-sync clocks. We are currently rely on NTP to synchronize clocks, this may be improved upon in the future, borrowing ideas from Ouroboros Chronos: Permissionless Clock Synchronization via Proof-of-Stake  eprint.iacr.org

References

  1. Ouroboros Crypsinous: Privacy-Preserving Proof-of-Stake eprint.iacr.org
  2. Ouroboros Chronos: Permissionless Clock Synchronization via Proof-of-Stake  eprint.iacr.org