(see Section 4.7); and π, with threshold of f + 1 for the execution protocol (see Section 4.4).
We assume a computationally bounded adversary that cannot do better than known attacks as of 2017 on the
cryptographic hash function SHA256 and on BLS BN-P254 [BGDM
+
10] based signatures. We use a PKI setup
between replicas for authentication. Clients need to know just one public key, which is needed for verification of the
threshold signature π, unlike PBFT, where every client needs to maintain membership and know the public keys of all
replicas.
3 Service Properties
Our algorithm provides a scalable fault tolerant implementation of a generic replicated service. We implement an
authenticated key-value store that uses a Merkle tree interface [Mer88] for data authentication. We begin by defining
the generic service interface and the authenticated data structure framework needed to leverage SBFT’s benefits. We
then detail the safety, liveness and scalability guarantees of our system.
3.1 Service interface
As a generic replication library, SBFT requires an implementation of the following service interface to be received
as an initialization parameter. The interface implements any deterministic replicated service with state, deterministic
operations and read-only queries. An execution val = execute(D, o) modifies state D according to the operation o
and returns an output val. A query val = query(D, q) returns the value of the query q given state D (but does not
change state D). These operations and queries can perform arbitrary deterministic computations on the state.
The state of the service moves in discrete blocks. Each block contains a series of requests. We denote by D
j
the state of the service at the end of sequence number j. We denote by req
j
the series of operations of block j, that
changed the state from state D
j−1
to state D
j
.
An authenticated key-value store. For our blockchain implementation we use a key-value store. In order to sup-
port efficient client acknowledgement from one replica we augment our key-value store with a data authentication
interface. As in public permissionless blockchains, we use a Merkle trees interface [Mer88] to authenticate data. To
provide data authentication we require an implementation of the following interface:
(1) d = digest(D) returns the Merkle hash root of D as digest.
(2) P = proof (o, val, s, D, l) returns a proof that operation o was executed as the lth operation in the the series
of requests in the decision block whose sequence number is s, whose state is D and the output of this operation was
val. For a key-value store, proof for a put operation is a Merkle tree proof that the put operation was conducted as
the lth operation in the requests of sequence number s. For a read only-query q, we write P = proof (q, val, s, D) and
assume all queries are executed with respect to D
s
(the state D after completing sequence number s). For a key-value
store, proof for a get operation is a Merkle tree proof that at the state with sequence number s the required variable
has the desired value;
(3) verify(d, o, val, s, l, P ) returns true iff P is a valid proof that o was executed as the lth operation in sequence
number s and the resulting state after this decision block was executed has a digest of d and val is the return value for
operation o (and similarly verify(d, q, val, s, P ) when q is a query). For a key-value store and a put operation above,
the verification is the Merkle proof verification [Mer88] rooted at the digest d (Merkle hash root).
3.2 Replication service guarantees
For n = 3f + 2c + 1 replicas SBFT obtains the following properties:
(1) Safety in the asynchronous mode (adversary controlling at most f Byzantine nodes and all network delays).
This means that any two replicas that execute a decision block for a given sequence number, execute the same decision
block.
(2) Liveness in the synchronous mode (adversary controlling at most f Byzantine nodes). Roughly speaking,
liveness means that client requests return a response.
5