Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Secret Network is built with the Cosmos SDK and the Tendermint consensus engine. Secret Network provides a platform for scalable, private permissionless smart contracts which can connect to the interchain.
Secret Network leverages novel key management techniques, encryption schemes, and Trusted Execution Environment (TEE) technology to bring encrypted input, output, and state to the blockchain.
The decentralized network of computers that host Secret Network come to a consensus (delegated Proof-of-Stake — Byzantine Fault Tolerance) without ever obtaining access to the data they process. Users can use “viewing keys” to view their sensitive data or enable third parties to do the same.
Secret brings privacy to the Interchain by leveraging CosmWasm IBC compatible smart contracts and IBC native token bridging. In this Section we dive into all of these elements of the techstack.
Steps Of A Private Transactions - overview
For a video introduction to the Secret techstack you can watch this playlist:
In distributed systems, replication of information on all machines is fundamental. In our case, Tendermint is responsible for replicating securely and consistently the state-machine amongst the nodes of the system.
It is composed of a Byzantine-Fault-Tolerance (BFT) Proof-of-Stake (PoS) consensus algorithm and a peer-to-peer networking protocol. It communicates to the application layer through the ABCI protocol.
Tendermint allows developers to focus on the application level and not take care of peer discovery, block propagation, consensus, etc …
In short, BFT represents the ability of a system to continue operating even if some of its nodes fail or act maliciously. In the Tendermint case, it can only tolerate up to 1/3 of failures, meaning that the blockchain will halt momentarily until 2/3 of the validator set comes to consensus.
Unlike Nakamoto consensus where it is subject to 51% attack (meaning that 51% of the actors acting maliciously could attack and alter the blockchain), Tendermint is more resistant as it is subject to a 66% attack.
Tendermint consensus module relies on Proof-of-stake and BFT.
Let’s take a look at the consensus process from a high-level standpoint:
Transactions are received by the node and go into a local cache mempool
Before going into the node mempool, Tendermint asks the application if the transaction is valid through “CheckTx” ABCI message
If it’s valid, transaction is added to the mempool and broadcasted to the peer nodes
A new consensus round is initiated with a Proposer Node
The Proposer selects transactions in the mempool to be included in a new block
This proposed block is broadcasted to all nodes (Pre-vote phase) and nodes verify that the block is valid, simultaneously verifying that the Proposer is also valid and sign the pre-vote message
If >2/3 of nodes pre-vote for this block, block is valid (but not committed) and we enter the pre-commit phase
Same as pre-vote, Tendermint will wait for >2/3 of nodes to sign the pre-commit message
There are two stages of voting to tolerate Byzantine faults, meaning that the pre-commit ensures that enough validators witnessed the result of pre-vote stage
The block is then committed, broadcasted to all nodes and transactions in this block executed by the application to update its state (for example account balance update etc)
Once a block is committed, there is no way to revert it and that gives an instant finality
All nodes are processing the transactions of every block even if they are not the block proposer
A new round is proposed and a new proposer is designated
This consensus ensures that all nodes maintain the same blockchain, i.e. the same list of blocks containing the past transactions and that all nodes could propose a block through Proposer rotation.
Users, known as delegators here, can choose which validator they want to delegate based on their reputation, stability, security and infrastructure. The amount of the native chain token owned and delegated to a validator represents its voting power, giving them the opportunity to be a new block proposer more often. Decentralization here is “measured” by the voting power distribution amongst the validators and not the number of validators.
ABCI layer is the communication protocol for Tendermint to make requests to the Application, like CheckTx (as we saw in the consensus explanation), indicate a Begin or End of a block, Deliver transactions to the application through DeliverTx, Query the application for account balance for example.
Finally, below a figure representing the Tendermint stack and all elements we went through in this paragraph:
A simple way to describe a blockchain is that it’s a distributed ledger on a peer-to-peer (P2P) network where each node of that network contains a copy of the blockchain state. The state of the blockchain is updated by an application and broadcast to each node, agreeing on this new state through consensus.
Want to learn about Cosmos and the Secret Techstack via a video instead? Check this video series on the Secret Network Youtube.
Cosmos is an ecosystem of independent, interconnected and application specific blockchains commonly referred to as the internet of blockchains. By having all these application specific interconnected blockchains, the ecosystem can easily scale horizontally which avoids most of the bottlenecks and scalability issues we know today on other heterogenous blockchains.
The conceptual layers of a blockchain are:
We will cover in this article the following three layers for an ease of understanding:
Network layer: Responsible for the propagation of transactions between the nodes of the ecosystem
Consensus layer: Enables the nodes to agree on the current state of the system.
Application layer: Responsible for updating the state given a set of transactions, i.e. processing transactions
To reach adoption and grow the internet of blockchain, developers should focus on their application specific development. They should not spend time on building from scratch the consensus and networking layers. That’s what Tendermint core is taking care of by providing Networking and Consensus layers saving a lot of time and headaches for the developers.
The following figure shows the Networking and Consensus layers as “Tendermint Core” and Cosmos SDK as the “Application layer”:
On top of Tendermint Core, Cosmos introduced the Cosmos SDK, an open-source framework for building application specific blockchains with composable modules (plugins) to help developers build their blockchain faster and easier. Developers could build their application directly on Tendermint core using ABCI to interact with Tendermint but Cosmos SDK allows a faster and battle tested path to bootstrap an application.
In order to scale horizontally and fulfill the vision of an internet of interoperable blockchains, blockchains can support the Inter-Blockchain Communication Protocol (IBC), which enables value transfers, token transfers, and other communication between chains, all without the need to involve exchanges or make compromises regarding the chains' sovereignties. Following figures show blockchains interconnected with IBC (IBC Networks)\
Blockchain technology is a complex base layer allowing open-source protocols and decentralized applications to be built on top of it. Secret is a sovereign layer 1 of the Cosmos ecosystem built with the Cosmos SDK.
This section will walk you through the Secret technology stack to get a better understanding of what’s under the hood of the privacy hub for Web3. This "Blockchain technology" section starts with a quick grasp of the different blockchain layers are and an explanation of the Cosmos stack
In this section we will explain in depth the components of the blockchain stack:
The Cosmos part of the Secret Techstack is also covered Part 1 and Part 2 of the Secret Network techstack video series.
Smart contract blockchains are typically public by default. This means that the ledger, the transactions, and the data contained in the smart contract are accessible to anyone. However, this is not the case with Secret Network as it’s the first blockchain that offers programmable privacy through privacy-preserving smart contracts (“Secret Contracts”). “Secret Contracts” have both public and private metadata. Private data on Secret Network is encrypted at input, state, and output and therefore never accessible to any nodes, developers, users, or everyone else.
Programmable privacy is the ability to compute with private data while allowing for not only transfers (transactional privacy) but arbitrarily private complex computations. This allows developers to include sensitive data in their smart contracts without moving off-chain to centralized (and less secure) systems; allowing for truly private and scalable decentralized applications— the true vision of the decentralized web.
To achieve such programmable privacy, Secret Network uses a combination of techniques which will be explained in the further sections of this documentation.
Want to learn about Privacy for smart contracts and the Secret network techstack? Check out the following video series for an introduction:
The following process is based on how Tendermint works to reach consensus in a standard app chain but with specificity related to the privacy features of Secret Network. Please note that Secret Network is permissionless, validators and nodes can join the network at any time.
Developers write and deploy Secret Contracts which are executed by the validators, the binary for these contracts is public.
Users submit transactions to the mempool — which can include encrypted data inputs
Validators receive encrypted data from users and execute the Secret Contract
During Secret Contract execution:
Encrypted inputs are decrypted inside a Trusted Execution Environment
Requested functions are executed inside a Trusted Execution Environment
Read/write state from Tendermint can be performed (state is always encrypted when at rest, and is only decrypted within the Trusted Execution Environment)
Outputs are encrypted
The block-proposing validator proposes a block containing the encrypted outputs and updated encrypted state
At least 2/3 of participating validators achieve consensus on the encrypted output and state following Tendermint BFT
The encrypted output and state is committed on-chain to the specific contract
Using the Eliptic-Curve Diffie Hellman key exchange (ECDH) the user generates a shared secret from their private key and the Secret Network public key. The network can generate the same shared secret using the user public key and the Network private key (only available within the Trusted Execution Environment (TEE)).
The user then generates a shared tx_encryption_key
using HKDF-SHA256 and the shared secret generated in step 1. The pseudo-random HDKF is used to ensure deterministic consensus across all nodes. The random component comes from a 256-bit nonce so that each transaction has its own encryption key, an AES-256-GCM encryption key is never used twice.
After initiating a transaction the user encrypts the input data with the shared transaction encryption key, using an AES-256-GCM authenticated encryption scheme.
The user then sends a single transaction with encrypted input data, gas fee in SCRT, and optionally a SCRT deposit (as required by the contract) to the contract address. The transaction adds a message with the user public key and the used Nonce so that the network can generate the same tx_encryption_key.
Validators receive the transaction in the shared mempool, after the Tendermint check_tx
is deemed successful, and take up the data to process the transaction.
Each validator runs on a machine with an Intel SGX compatible CPU. The enclave within this CPU is the trusted component, whereas the process interacting with the enclave locally from the outside is the untrusted component. The encrypted transaction input is passed from the untrusted to the trusted component.
The enclave uses ECDH to derive the same shared secret from the users public key and the networks private key. The network then derives the tx_encryption_key
from the public signed nonce and this shared secret using HDKF. Within the trusted component the transaction input is decrypted to plaintext.
The requested contract computation is executed on the plaintext input by the WASMI runtime, which is instantiated within the trusted enclave.
There are several possible outcomes from each computation, all of which occur on-chain simultaneously:
The contract state is updated.
The transaction output is encrypted for the transaction sender and committed on-chain
If present, callbacks to other contracts.
If present, send messages to other modules.
The output of the computation is encrypted using the tx_encryption_key
and an AES-256-GCM authenticated encryption scheme.
The encrypted output is then returned to the untrusted component of the validator node.
The validator that proposes the current block broadcasts the encrypted output.
Other validators compare their result to that of the block proposer. If more than two-thirds of the current voting power agrees on the result, the proposed block (and all transactions within it) are included in the Secret Network.
Want to learn about Secret transactions in a video format instead? Check out the last part of the Secret Network techstack video series.
An extensive discussion of Secret Network's cryptography
💡 For a graphic view of this consensus process check:
Secret Network uses both symmetric and asymmetric encryption protocols. Specifically, asymmetric cryptography is used for achieving consensus and sharing secrets between nodes and users, whereas symmetric cryptography is used for input/output encryption with users of Secret Contracts, as well as internal contract state encryption.
Secret Network Protocol uses the Elliptic-curve Diffie-Hellman (ECDH) key exchange mechanism between users and validators. This process involves the user, the Secret Blockchain, as well as the trusted component of the Secret Protocol. It is initiated any time a transaction is sent from the user to the Secret Contract.
The encryption and key derivation logic Secret Network uses are as follows:
HKDF-SHA256 function for deterministic key derivation;
ECDH (x25519) function for generating public / private key pairs; and
AES-128-SIV symmetric encryption scheme.
A combination of the above symmetric and asymmetric encryption methods is used to create a safe process for the bootstrapping of the decentralized network, the addition of new SGX nodes, and the encryption of input, output, and state. The management of all the private and public keys may only be shared under specific conditions, and others never leave the SGX instance to ensure private data handling.
The Secret Network uses a random number called the “consensus seed” as a parameter to derive a public and private key set used by the Network for encryption purposes. The consensus seed is unknown to any party in the ecosystem and was created at the genesis of the network by the network itself. For deterministic key generation, the network uses a known “salt” which is chosen to be the hash of the Bitcoin halving block.
As a transaction is initiated by a user of the network they derive Input Key Material (IKM) using their own private key and the network-generated public key, the network derives the same IKM using the user's public key and the network-generated private key. An encryption key for the transaction is then derived inside the TEE from the IKM, the salt, and a random number generated with the consensus seed. The encryption key is used to encrypt the input specific to this transaction. Only the protocol and the user signing the transaction have access to the encryption key, and therefore access to the input, output, and state related to this specific smart contract computation.
When a full node resumes network participation, it reads consensus_seed
from $HOME/.sgx_secrets/consensus_seed.sealed
, does the same key derivation steps as above in steps 2-5.
The new full node verifies the remote attestation proof of the bootstrap node from genesis.json
and creates a remote attestation proof for their own machine to show to the network that the node's Enclave is genuine.
Using HKDF-SHA256, hkdf_salt
and nonce
(a 256 bit true random) a private key is derived. From registration_privkey
calculate registration_pubkey
The node needs to send an secretcli tx register auth
transaction with the following inputs:
The remote attestation proof the node's Enclave is genuine
registration_pubkey
256 bits true random nonce
On the consensus layer, inside the enclave of every full node the auth transaction comes in.
The Network validator nodes:
Receive the secretcli tx register auth
transaction
Verify the remote attestation proof that the new node's Enclave is genuine
seed_exchange_key
seed_exchange_key
: An AES-128-SIV encryption key is used to send consensus_seed
to the new node
This key is derived in several steps:
This IKM is never publicly available and protects the Secret network private entropy
In the second step seed_exchange_key
is derived using HKDF-SHA256 from seed_exchange_ikm
and nonce
. When sending the seed_exchange_key
to new nodes the Nonce is added as plaintext, it just serves the function of making each seed_exchange_key
unique.
consensus_seed
with the new nodeThe seed_exchange_key
generated in step 5 is used to encrypt the consensus_seed
. The AD
for this encryption algorithm is the public key of the new node: new_node_public_key
All this logic is done in side the Authorization transaction. secretcli tx register auth
outputs the encrypted_consensus_seed
The encrypted output is received by the new full node. The new node now has access to the encrypted_consensus_seed
and will have to decrypt to plaintext to receive the consensus_seed
seed_exchange_key
The AES-128-SIV encryption key seed_exchange_key
is used to decrypt consensus_seed
To derive this the reverse logic is followed highlighted in step 5.
First the same seed_exchange_ikm
is derived using ECDH (x25519) with consensus_seed_exchange_pubkey
(public in genesis.json
) and registration_privkey
(available only inside the new node's Enclave) This is the DH-key echange in action as this is the reverse public/private input of the IKM generation in step 5.
seed_exchange_key
is derived using HKDF-SHA256 with seed_exchange_ikm
and nonce
encrypted_consensus_seed
encrypted_consensus_seed
is encrypted with AES-128-SIV, seed_exchange_key
as the encryption key and the public key of the registering node as the ad
as the decryption additional data The new node now has all of these parameters inside its Enclave, so it's able to decrypt consensus_seed
from encrypted_consensus_seed
and then seal consensus_seed
to disk at $HOME/.sgx_secrets/consensus_seed.sealed
Intel SGX is one of the most used and widely available implementations of Trusted Execution Environments (TEEs). Secret Network has selected this technology for the initial version of the Secret Network for two main reasons: Usability & Security.
SGX is more performant and more flexible than other solutions for privacy-preserving computation. The Secret Network is building a platform for decentralized, general-purpose private computation. This requires a privacy solution that can enable a wide range of use cases. It also requires computations to be on par, performance-wise, with non-privacy preserving computation, so that speed does not limit application usability.
SGX is one of the most widely adopted technologies for TEEs, it is also battle-hardened. Attacks are often theoretical, executed in laboratory settings, and are rapidly addressed by Intel. Many high-value targets exist that have not been compromised. No privacy solution is 100% secure, but we believe the security guarantees provided by Intel SGX are adequate for a wide range of use cases.
Secret Network only allows for Intel SGX chips, AMD-SEV or other TEE technologies are not usable for running nodes on the network.
SGX comes in 2 forms; SGX-ME and SGX-SPS. SGX-ME (management engine) uses small extra chips to manage functions related to the enclave such as memory and energy management. SGX-SPS (Server Platform Services) allows the bypassing of the ME chip. To further reduce the number of possible attack vectors on the network, Secret Network has opted to only use SGX-SPS. Hence, all attack vectors of the ME chip do not apply to Secret Network.
Furthermore, each full node on Secret Network creates an attestation report that proves that their CPU is using the latest firmware/microcode (processor firmware) upgrades before it registers. The entire network verifies the attestation report of the new node on-chain, to ensure that node operators cannot decrypt anything. Once the new node gets the shared key of the consensus they become part of the consensus and are able to process computations and transactions in parallel to the network.
The main difference when it comes to Cosmos compared to virtual-machine blockchain, is the application-specific blockchain concept. Developers can build from scratch their application specific blockchain on top of Tendermint through ABCI protocol. Cosmos SDK is the framework offering a bank of independent modules for implementing the application state machine, ABCI, service routers to route messages between modules, and a flavor of features like governance, staking, slashing, etc …
Below a figure showing the architecture differences between a VM blockchain and Cosmos:
A virtual-machine interprets Smart Contracts to change the state of the underlying blockchain state machine. It’s developer friendly and easy to use to deploy applications but comes with certain limitations:
Specific programming language accepted by the VM
VM limited set of functions and lack of flexibility
Smart Contracts are all run by the same virtual machine restraining performance as all application compete for block resources
Limited sovereignty, meaning that the application is dependent of the underlying blockchain governance decision
In Cosmos, developers have all the keys to develop a sovereign, secure, flexible and tailor made application specific blockchain.
Cosmos SDK allows developers to tweak, if needed, the framework or the consensus engine or any modules to match their application/network requirements.
As the application is not competing with others for blockspace or is limited by the VM computation, the performance is enhanced and only limited by the state-machine itself.
In terms of security, developers are not constrained by the VM cryptographic functions or any VM exploitable mechanisms and can rely on their own cryptography or audited libraries.
In conclusion Cosmos SDK is giving an easy and fast way to bootstrap an application specific blockchain relying on an efficient and proven technology without tradeoffs on security and sovereignty and with access to an extensive modules library.
💡 For more information about the Cosmos SDK: High-level Overview | Cosmos SDK & Main Components of the Cosmos SDK
Secret Network uses Intel's Software Guard Extensions (SGX) implementation of TEE technology. TEE refers to a secure area of a processor where data is inaccessible to any other component in the system. A TEE acts as a blackbox for computation, input and output can be known, but the state inside the TEE is never revealed.
Intel’s Software Guard Extensions (SGX) is a set of security-related instructions built into certain Intel CPUs enabling TEEs. By using SGX chips, the chip owners, system operators, and observers have strong cryptographic guarantees that no party can view what's happening inside of the Secret memory space.
This part of the documentation will discuss all aspects of TEE technology and the way that Secret Network implements it for a secure private computation environment.
Secret Network is set up to perform computation while having encrypted state, input and output. The state is encrypted using private keys generated during the network bootstrapping from a consensus_seed
. The bootstrap node was the first full node on the network and generated the shared secrets similar to a universal trusted zero knowledge setup.
The bootstrap node first does a remote attestation to prove they are running a genuine SGX enclave with updated software. After registering the bootstrap node handled the initialization of following variables:
Consensus_seed
a true random 256 bit seed used as entropy for generating shareable keypairs between the nodes of the network.
consensus_seed_exchange_pubkey
- consensus_seed_exchange_pubkey
an HDKF private key and a matching curve25519 public key for encryption of the random seed and sharing this with other full nodes in the network.
consensus_io_exchange_pubkey
- consensus_io_exchange_pubkey
an HDKF private key and a matching curve25519 public key for encrypting transactions IO in the network. Also referenced as the "Secret Network keypair".
consensus_state_ikm
An input keyring material (IKM) for HKDF-SHA256 is used to derive encryption keys for contract state.
consensus_callback_secret
A curve25519 private key is used to create callback signatures when contracts call other contracts
The bootstrap node proves to have a genuine enclave after which it can participate in the network. More information can be found on .
consensus_seed
The bootstrap node is instructed when started to generate a true random 256 bit seed inside the enclave, the consensus_seed
.
The consensus_seed
is sealed with MRSIGNER to a local file : $HOME/.sgx_secrets/consensus_seed.sealed
For the network to start decentralizing the bootstrap node needs to be able to share the consensus_seed
. The network can then use the seed to create shared secrets while in the enclave. To securely share the seed the Network uses a DH-key exchange.
Using HKDF-SHA256, hkdf_salt
and consensus_seed
a private key is derived. From consensus_seed_exchange_privkey
calculate consensus_seed_exchange_pubkey
Using HKDF-SHA256, hkdf_salt
and consensus_seed
a private key is derived. - From consensus_io_exchange_privkey
calculate consensus_io_exchange_pubkey
consensus_state_ikm
Using HKDF-SHA256, hkdf_salt
and consensus_seed
derive consensus_state_ikm
5. consensus_callback_secret
Using HKDF-SHA256, hkdf_salt
and consensus_seed
derive consensus_callback_secret
Publish to genesis.json
:
The remote attestation proof that the Enclave is genuine
consensus_seed_exchange_pubkey
consensus_io_exchange_pubkey
Secret Network recently upgraded to , which rotated the network consensus seed during the upgrade.
A consensus seed is a true random 256 bit seed that is used as entropy for generating shareable keypairs between the nodes of the network.
Previously, the consensus seed remained unchanged ever since the network’s inception–the network state was encrypted using private keys generated during the network bootstrapping from a consensus seed, similar to a universal trusted zero knowledge setup. However, if anyone were to gain access to this seed they would have the master key to decrypt the state of the entire network. Thus, Secret Network has introduced consensus seed rotation in order to increase network security.
In order to protect against potential future breaches, Secret Network developed a two-part protocol for changing the consensus seed:
Rotate the current seed (The "Genesis" seed) and change the encryption scheme
Implement contract state migration and allow seed rotation on upgrade (currently in development)
It is important to note that the upgrade to consensus seed rotation does not change the state (and the consensus seed) of the network prior to the upgrade. This means that the new encryption scheme must be able to distinguish between values that were encrypted with the genesis seed and those that will be encrypted with future seeds. To this end, the following features were implemented:
A way to distinguish between values that were encrypted with the genesis seed and those that will be encrypted with future seeds
The ability to iterate over all of the keys for a specific contract using CosmWasm iterators (currently in development)
The ability to decrypt state keys, rotate the seed, and decrypt and re-encrypt all keys & values in the state
In order to rotate the Genesis seed, a new seed must be created that will be shared with all current nodes as well as new nodes. To this end, Secret Labs updated all of the existing nodes with the new seed and every new node that joins the network will contain 2 consensus seeds (The genesis and the current) and will use them both based on the encrypted value.
The new seed can be received via three methods:
On upgrade: When upgrading to 1.7.1, the node will identify that the current seed is missing and will communicate with Secret Labs’ seed service in order to obtain the seed
On Registration: On registration, both the current and the genesis seed will be passed to the newly registered node
On Bootstrap: Boostrap will access the seed service unless the "use_seed_service_on_bootstrap" feature is off (Which is the default state in localsecret). If so, it will generate one instead.
In the previous encryption scheme, the key and the value were stored as follows:
In the new encryption scheme, the plaintext key is no longer necessary in order to decrypt the value. The encrypted value also looks a bit different in the new scheme:
This new encryption scheme ensures that:
the encrypted_state_key encrypts differently between different keys
The salt will verify that on different instances, the same value is encrypted differently for the same key. The salt is the current block's timestamp and the msg id, which is a counter of the messages and allows for different values between different messages in the same block.
In order to authenticate a node, the node first sends an attestation report to the designated /authenticate endpoint as the request body. The server then responds with a challenge, which is a randomly generated 4-byte value that is linked to the public key of the node. The node then creates a new attestation report that incorporates the challenge into its quote, which proves that the node can generate new attestation reports certified by Intel while also rendering old certificates invalid. Subsequently, the node transmits this new attestation report to the /seed/[id] endpoint, where the ID represents the desired seed. Upon receiving the attestation report, the server verifies it and sends the seed to the node.
The port of the service is 4487 and there are 2 DNS names that are used.
On MainNet - sss.scrtlabs.com
On Pulsar - sssd.scrtlabs.com
Secret Network has implemented consensus seed rotation in the upgrade to version 1.7.1. Previously, the consensus seed remained unchanged since the network's inception, but this posed a security risk as anyone with access to the seed would have the master key to decrypt the entire network's state. The new consensus seed rotation includes a two-part protocol to change the genesis seed and encryption scheme, and implement contract state migration to allow seed rotation on upgrade. The upgrade does not change the network state prior to the upgrade, so the new encryption scheme distinguishes between values encrypted with the genesis seed and those encrypted with future seeds. Secret Labs updated all existing nodes with the new seed and new nodes joining the network will have both the genesis and current seeds, using them based on the encrypted value. These updates increase the security of Secret Network by protecting against potential future breaches.
Secret Network leverages TEE technology to do computation with encrypted input, output, and state. The consensus and computation layer of the Secret Network is combined; every validator uses an Intel SGX CPU and processes every transaction.
Private metadata used in Secret Contracts is encrypted before sent to validators for computation. Data is only decrypted inside the TEE of any specific validator, which is inaccessible to them. Computations following the smart contract are done over the decrypted data and the output is encrypted and written to state.
The consensus encryption seed of the network is only stored inside the TEE of each validator node; no entity has access to the encryption keys.
Enclaves also go through a detailed registration and attestation process. Specifically, the attestation process which each validator running an SGX enclave must go through ensures the following assertions regarding privacy and correctness:
The application’s identity
Its intactness (that it has not been tampered with)
That it is running securely within an enclave on an Intel SGX enabled platform
For more detailed information on the Intel SGX remote attestation process you can check out this page:
Enclaves generate and contain their private signing/attestation keys, preventing access from any entity outside of each enclave. All data can only be signed using keys associated with specific instruction sets running in each enclave. For more details on key generation and management within enclaves, see our section about .
For our purposes, the attestation key is only used once upon registration. After registration new keys are provisioned to the enclave and used to communicate with the network. This process is described in more detail below.
When a contract is executed on chain the state of the contracts needs to be encrypted so that observers can not see the computation that is initialized. The contract should be able to call certain functions inside the enclave and store the contract state on-chain.
A contract can call 3 different functions: write_db(field_name, value)
, read_db(field_name)
, and remove_db(field_name)
. It is important that the field_name
remains constant between contract calls.
We will go over the different steps associated with the encryption of the contract state.
contract_key
The contract_key
is the encryption key for the contract state and is a combination of two values: signer_id || authenticated_contract_key
. Every contract has its own unforgeable encryption key. The concatenation of the values is what makes every unique and this is important for several reasons
Make sure the state of two contracts with the same code is different
Make sure a malicious node runner won't be able to locally encrypt transactions with it's own encryption key, and then decrypt the resulting state with the fake key
so to reiterate, every contract on Secret Network has its own unique and unforgeable encryption key contract_key
This process of creating contract_key
is started when the Secret contract is deployed on-chain. First authentication_key
is generated using HDKF-SHA256 inside the enclave from the following values:
consensus_state_ikm
HDK-salt
signer_id
From the authentication_key
create authenticated_contract_key
by calling the hmac-SHA256 hash function with the contract code_hash
as hashing data.
This step makes sure the key is unique for every contracts with different code.
Lastly concat the signer_id
and authenticated_contract_key
to create contract_key
. This step makes it so the key is unforgeable as the key can only be recreated with the current signer_id
contract_key
with enclaveEvery time a contract execution is called, contract_key
should be sent to the enclave. In the enclave, the following verification needs to happen to proof a genuine contract_key
write_db(field_name, value)
read_db(field_name)
remove_db(field_name)
Very similar to read_db
.
To do deterministic key generation inside the SGX enclave Secret Network leverages HDKF-SHA256 . HDKF-SHA256 is a key derivation function for symmetric (private key) encryption. The function generates a 256-bit encryption key from a common public "salt" and a piece of Input Key Material (IKM). The salt
for the use in the Secret Network encryption schemes is chosen to be the Bitcoin's block halving hash hkdf_salt = 0x000000000000000000024bead8df69990852c202db0e0097c1a12ea637d7e96d
HDKF is commonly used to extract entropy from a larger source and deliver smaller output (eg. an encryption key) as well as expand already existing random output into a larger cryptographic-ally independent output. The deterministic keys coming from HDKF can be shared amongst network participants without revealing the underlying randomness. In the end this symmetric function is used to ensure safety for the pseudo-random consensus_seed
and secure the shared secrets of the network participants.
The output of the HDKF is a curve25519 private key, which can be used to derive a public key as well.
Elliptic-curve Diffie-Hellman () is a key derivation protocol designed to support assymetric encryption by returning a public-private key pair. ECDH allows for sharing secrets over public channels as one needs the private key to decrypt information while using the public key for sending the encrypted message. These Shared secrets can be used by both parties to then set up subsequent symmetric keys with functions like HDKF as mentioned above. ECDH delivers 256 bits Curve25519 encryption keys which have a probabilistic level of security of 2^128.
ECDH also allows for a special way of generating shared secrets which involves using the private and public key of both participants. Participant A and B can create a shared secret by doing: ecdh(Apriv, Bpub) == ecdh(Bpriv, Apub)
, this feature is called "key-exchange" and is the basis of sharing information amongst network participants on Secret Network.
For additional explanation of Diffie-Hellman, check out .
Advanced Encyption Standard (AES) is an encryption algorithm slightly varying from the block cipher "Rijndael" set to a fixed 128 bits size block. The algorithm generates 256 bit encryption keys which offer very high security guarantees.
The AES-SIV encryption scheme is a perfect addition to the ECDH keypairs used in SGX enclaves. The combination allows for sharing encrypted data amongst nodes and protecting the private entropy of the protocol. was chosen to prevent IV misuse by client libraries. The algorithm does not pad ciphertext which leaks information about the plaintext, in particular its size.
Remote attestation, an advanced feature of Intel SGX, is the process of proving an enclave is established in a secure hardware environment. A remote party should be able to verify that the right application is running inside an enclave on an Intel SGX enabled platform.
Remote attestation provides verification for three things:
The application’s identity
Its intactness (that it has not been tampered with)
That it's running securely within an enclave on an Intel SGX enabled platform
Attestation is necessary in order to make remote access secure because an enclave’s contents may have to be accessed remotely, not from the same platform []
The attestation process consists of seven stages, encompassing several actors, namely the service provider (referred to as a challenger) on one platform; and the application, the application’s enclave, the Intel-provided Quoting Enclave (QE), and Provisioning Enclave (PvE) on another platform. A separate entity in the attestation process is Intel Attestation Service (IAS), which carries out the verification of the enclave [][][].
In short, the seven stages of remote attestation comprise of making a remote attestation request (stage 1), performing a local attestation (stages 2-3), converting the local attestation to a remote attestation (stages 4-5), returning the remote attestation to the challenger (stage 6), and verifying the remote attestation (stage 7) [][].
Intel Remote Attestation also includes the establishment of a secure communication session between the service provider and the application. This is analogous to how the familiar TLS handshake includes both authentication and session establishment.
Trusted Execution Environments are essentially stateless. To preserve information that’s stored in an enclave, it must be explicitly sent outside the enclave to untrusted memory. SGX provides a capability called data sealing which encrypts enclave data in the enclave using an encryption key derived from the CPU. This encrypted data block can only be decrypted, or unsealed, on the same system. This SGX-specific method for storing data is not used to store computation input/output data in the Secret Network. It is used to store the enclave’s signing key.
We seal the signing key because this key is created during the remote attestation process. We do not want the enclave to be required to perform remote attestation between each computation. If the enclave fails for some reason, and the key is lost, the worker would be obligated to go through the remote attestation process again. The only way to store persistent data from the enclave is through sealing.
Secret Contracts are enabled by the “compute” module of the Cosmos SDK, and execute over plaintext while still allowing for encrypted inputs, outputs, and states because of trusted and verifiable computations. Consensus with an encrypted state is reached by using shared secrets amongst the validator nodes of the network.
In this part of the documentation, we highlight the flow of data for interactions on the secret network and dive into the design of Secret Contracts and their differentiations from standard CosmWasm contracts.
A Secret Contract’s code is always deployed publicly on-chain, so users and developers know exactly what code will be executed on submitted data. However, the data that is submitted is encrypted, it cannot be read by a developer, anyone observing the chain, or anyone running a node. If the behavior of the code is trusted (which is possible because it is recorded on chain), a user of Secret Contracts obtains strong privacy guarantees.
The encrypted data can only be accessed from within the “trusted execution environment”, or enclave, that the compute module requires each validator to run. The computation of the Secret Contract is then performed, within this trusted enclave, where the data is decrypted. When the computation is completed, the output is encrypted and recorded on-chain.
Want to learn more about the encryption specification of the contract state? - Read the technical specification on Contract state encryption here.
Secret contracts are an altered version of the CosmWasm Rust based smart contract framework and share many resemblance. The contracts written in Rust compile to a Wasm binary that is than run by the Wasmd module of the cosmos SDK. The version of Secret is altered in such a way that all executions are done inside the secure enclave requiring additional data verification and more. This also means queries of the contract state or contract execution are permissioned to only the signer of the transaction themselves. Contract state queries requiring opening up the VM in the enclave and are therefore more intensive to run than generic plaintext cosmos-sdk queries.
More info coming soon
Now that we have a better understanding of how Secret is leveraging SGX, let’s see how the TEE and enclaves works with the Trusted and Untrusted cores.
Responsible for running the Cosmos SDK and Tendermint.
Contains code for creating and managing the enclave (load and destroy).
Can call the CosmWasm module and kick off Secret Contract execution within the enclave.
Responsible for executing Secret Contracts.
Responsible for SGX-specific mechanisms: Remote Attestation and Sealing.
Able to make read/write calls from the Tendermint state at any point during execution.
The enclave only stores the seed. The enclave may also store the local node's key pair.
Note: During contract execution, only the state of the contract being executed can be changed. Other contracts can be queried (i.e. run code that can't change the state of another contract) synchronously, but calls to other contracts and requests for transactions can only be queued. Those operations will happen after the contract has finished running. This is intentional as it prevents a lot of bugs, like the re-entrancy bugs plaguing Ethereum.
Below is a diagram of how the Untrusted and Trusted behave on a User transaction and Secret Contract execution:
\
An introduction to CosmWasm
CosmWasm is a modular framework for writing secure smart contracts in Rust, and using them in any blockchain built with the Cosmos SDK. It's a low-level tool developers use to implement entirely new features. The framework enables the creation of modular and reusable code for smart contracts, without being exposed to the underlying nature of the blockchain and its inner workings. These smart contracts are run securely inside a WebAssembly (WASM) virtual machine (VM). WASM acts as an intermediate language compiler for the VM.
Everything in blockchain is a smart contract. To understand what this means, it helps to know that a smart contract is simply a set of rules that describe how parties interact with each other. These rules are written as code and stored on the blockchain, where they can be executed by the network itself.
The blockchain world has seen several attempts to make smart contracts safer, but these solutions were either too complicated or simply didn't work. CosmWasm is different because it's easy to use and works well in practice.
CosmWasm wraps Rust binaries as secure smart contracts. The source code is verified by the compiler and the resulting binary contains all of its dependencies statically linked. This prevents attackers from modifying any part of the contract after it has been deployed on-chain.
You don't have to write Rust code in order to use CosmWasm. If you're a developer and want to write your own contracts using CosmWasm, you can! As long as your programming language generates a WASM binary with no external dependencies, and defines the correct entry points it will work with CosmWasm. This means you can use any programming language of your choosing. You could write your contract in Go or Python, for example, and then deploy it with CosmWasm.
💡 For more information on CosmWasm navigate to:
The core vision of Cosmos is to scale horizontally by having an ecosystem of interconnected application specific blockchains. Inter-Blockchain Communication Protocol (IBC) is responsible for interconnecting heterogeneous blockchains or in another way, relaying data packets between arbitrary state machines (i.e application blockchains).
It could also be defined as a generic and standard protocol implementation for transferring value between chains, not only limited to Cosmos chains as other blockchains with different consensus could support IBC to communicate with the Cosmos Ecosystem (Polkadot, Ethereum through a peg zone for example).
IBC provides a common protocol for blockchains to communicate in a standardized and trustless way.
There is a lot to talk about IBC in terms of current and future capabilities, and the technology layers, but that’s not the goal of this paragraph. We’ll go through the high level principles here.
IBC is composed of two layers:
Transport layer (IBC/TAO) - provides the infrastructure for establishing secure connections and data packets authentication between chains
Application layer (IBC/APP) - defines how data packets should be packaged and interpreted by sending and receiving chains
This is wrapped up in a “light client” and relayers are external components for passing messages through blockchains:
Relayers are off-chain actors ensuring the “physical” connection between two chains, scanning the state of the two interconnected chains, looking for an intention to send a transaction on a chain and then relaying the data and its commitment proof to the other chain.
For example in the case of fungible token transfer between two chains, the relayers are responsible for proving that your tokens are locked in Chain A and giving a representation (Voucher) on Chain B.
Relayers are using the light client of each blockchain to verify incoming messages on chain A and submit them (and the proof of commitment) on chain B. Chain A can’t send data directly to chain B and instead “commit” the hash of the data packet in its own state machine. That’s this specific state that relayers are monitoring to send this packet and its proof to the chain B.
The major difference of IBC compared to existing bridge solutions is that there are no third parties to trust, no multisig involved, for transferring value/messages between blockchains. This concept of IBC native security means that if you trust chain A and chain B then you also trust IBC-TokenA on chain B and vice versa. As long as relayers are operated by any party and channels/ports are open and authentication successful between blockchains, messages can be passed along.
An analogy of IBC could be seen as an internet application on a computer. A channel is an IP connection, with the IBC portID being an IP port and the IBC channelID being an IP address.
IBC security does not depend on third parties to verify the validity of transactions between blockchain. IBC security is mostly done by the light clients who verify proofs of commitments and the state of the two interconnected blockchain. In short terms, IBC security is based on::
Trust in the chains you connect with
Fault isolation mechanisms, to limit damage done if a chain is acting maliciously
IBC is then still Byzantine resistant thanks to the proof validation by the light client. If a relayer were to act maliciously, the packet would be rejected by the counterparty chain because the proof would be invalid (because light client and relayers are independent).
Fungible token transfer is one example but IBC allows for Non-Fungible token transfer, multi-chain smart contracts and interchain accounts (interacting on a blockchain account from another source blockchain). This is the function enabling Secret Network to be the privacy hub for the Interchain. Other Cosmos chains can store and manipulate private data (even private keys) on Secret Network from the comfort of their own chain, Privacy as a service.
Finally, below a figure explaining the travel of an IBC packet between blockchains:
Transaction encryption unlike contract state encryption has two parties who need data access. The scheme therefore makes use of the DH-key exchange as described in the previous section to generate a shared encryption key. This symmetric tx_encryption_key
is unique for every transaction and can be used by both the network and the user to verify the completed transactions.
Using the Eliptic-Curve Diffie Hellman key exchange (ECDH) the user generates a shared secret from consensus_io_exchange_pubkey
and tx_sender_wallet_privkey
.
tx_encryption_key
- user sideThe user then generates a shared tx_encryption_key
using HKDF-SHA256 and the tx_encryption_ikm
generated in step 1. The pseudo-random HDKF is used to ensure deterministic consensus across all nodes.
The random component comes from a 256-bit nonce so that each transaction has its own encryption key, An AES-256-GCM encryption key is never used twice.
After initiating a transaction the user encrypts the input data with the shared transaction encryption key, using an AES-256-GCM authenticated encryption scheme.
The input (
msg
) to the contract is always prepended with the sha256 hash of the contract's code. This is meant to prevent replaying an encrypted input of a legitimate contract to a malicious contract, and asking the malicious contract to decrypt the input.
In this attack example the output will still be encrypted with a tx_encryption_key
that only the original sender knows, but the malicious contract can be written to save the decrypted input to its state, and then via a getter with no access control retrieve the encrypted input.
tx_ecryption_key
- network sideThe enclave uses ECDH to derive the same tx_encryption_ikm
from the tx_sender_wallet_pubkey
and the consensus_io_exchange_privkey
. The network then derives the tx_encryption_key
from the publicly signed nonce
and this shared secret using HDKF.
Within the trusted component the transaction input is decrypted to plaintext.
The output must be a valid JSON object, as it is passed to multiple mechanisms for final processing:
Logs are treated as Tendermint events
Messages can be callbacks to another contract call or contract init
Messages can also instruct sending funds from the contract's wallet
A data section which is free-form bytes to be interpreted by the client (or dApp)
An error section
Here is an example output for an execution:
on a Contract
message, the msg
value should be the same msg
as in our tx_input
, so we need to prepend the nonce
and tx_sender_wallet_pubkey
just like we did on the tx sender above
On a Contract
message, we also send a callback_signature
, so we can verify the parameters sent to the enclave (read more here: ......)
For the rest of the encrypted outputs we only need to send the ciphertext, as the tx sender can get consensus_io_exchange_pubkey
from genesis.json
and nonce
from the tx_input
that is attached to the tx_output
with this info only they can decrypt the transaction details.
Here is an example output with an error:
An example output for a query:
The output of the computation is encrypted using the tx_encryption_key
The transaction output is written to the chain and only the wallet with the right tx_sender_wallet_privkey
can derive tx_encryption_key
. To everyone else but the tx signer the transaction data will be private.
Every encrypted value can be decrypted by the user following:
For output["ok"]["messages"][i]["type"] == "Contract"
, output["ok"]["messages"][i]["msg"]
will be decrypted in by the consensus layer when it handles the contract callback