Different types of blockchain applications and users demand varying types of private key management solutions, referred to as wallets. Custodial wallets are managed by third-party vendors such as a centralized crypto exchange, whereas non-custodial wallets give you full control and ownership over your private keys and funds.
Crypto-native users with experience managing their own digital assets prefer non-custodial, single-key wallets, either hardware-based wallets such as those offered by Ledger, or software-based wallets such as those offered by MetaMask. Institutions or decentralized autonomous organizations (DAOs), however, prefer more advanced wallet technologies that offer a higher degree of security and robust multi-party authorization systems, such as non-custodial multi-party computation (MPC) or multi-sig wallets.
Multi-sig wallets, such as those offered by Safe, are smart contract-based wallets that require a predefined minimum number of users to approve a transaction before execution. MPC wallets use cryptographic mechanisms that allow splitting private keys into multiple key shards distributed among different parties, allowing them to collectively sign transactions without ever reconstructing the full key in one place.
Whereas multi-sig wallets are usually on-chain, blockchain protocol-specific, and subject to higher transaction costs due to their smart contract-based nature, MPC wallets are deployed off-chain, are protocol agnostic, and produce a single signature, not causing additional transaction costs. For additional information on the differences between the two wallet types, refer to MPC vs. Multi-sig.
In this post, we focus on MPC wallets. We introduce the core concepts of MPC wallets, including the security features they offer that make MPC wallets uniquely well suited for institutional customers. We also detail the most critical aspects of implementing a distributed, highly secure MPC wallet on AWS, including a design for a single MPC cosigner that uses AWS Nitro Enclaves to protect the most sensitive information: the key shards.
Implement Fireblocks MPC wallets within Nitro Enclaves
In blockchain technology, the authenticity of transactions is verified through public key cryptography: a private key signs the transaction, and its corresponding public key enables others to validate the signature. This determines the most fundamental rule of blockchain wallets: whoever controls the private key controls the associated funds.
MPC algorithms allow multiple parties to collaboratively compute a function without revealing the private data they contributed to the computation.
In general, MPC algorithms are used to generate private key shards distributively (DKG), so that a complete and whole private key doesn’t exist in any single location. The key shards are stored in Fireblocks servers (named cosigners) and the customer’s mobile device or the customers cosigner server, which can run in on-premises or public cloud environments.
The MPC algorithm allows the collaborative generation of a valid signature based on the different available key shards in a trustless manner without a single party having access to the complete private key.
Sets of three key shards (two stored in Fireblocks cosigners and one with the customer) allow the signing of a transaction as if signed by a single private key, no matter which set of three key shards is delegated to the task (assuming proper DKG setup of the key shards in advance). That allows for a flexible setup where different devices or users on the customer’s side can sign different transactions, all corresponding to the same private key and therefore the same wallet.
To enhance security, all operations involving these shards on AWS customer cosigner servers are performed within Nitro Enclaves, making sure sensitive data is not exposed or manipulated. You can find more information about the announcement on Support for AWS Nitro Enclaves on Fireblocks.
Nitro Enclaves are isolated, hardened, and highly constrained virtual machines that provide proof of identity through cryptographic attestation, where the Nitro Hypervisor generates a signed attestation document containing unique enclave measurements and a certificate signed by the AWS Nitro Public Key Infrastructure (PKI). Validating the attestation document allows external services to verify the features like the enclave’s identity (PCR0) or the enclave author’s identity (PCR8), and conclude that only authorized code is running in the enclave.
The enclave identity, represented by the hash value of the image file, can also be tightly coupled with an AWS Key Management Service (AWS KMS) key, just granting decrypt permission to requests originating from within the enclave.
The following diagram illustrates the onboarding of a new customer cosigner (either a new mobile device or a cosigner server that is designated to hold a new key shard).
The new customer cosigner participates in an MPC protocol that includes messages passing between itself and three existing cosigners (including one existing cosigner on the customer side). In the end of that protocol, a new (orange) set of three key shards is created, allowing the new customer cosigner to collaboratively generate signatures with the Fireblocks cosigners indistinguishable from the signatures that the preexisting (blue) set of key shards generate.
As shown in the preceding diagram, such an MPC algorithm-based system provides significant flexibility. For example, if a customer needs to authorize a new employee to sign transactions, they can initiate the creation of new key shards in the employee’s mobile device or server.
This is done simply by using an existing device with a shard to authorize and generate a new set of shards. Consequently, a new triplet of shards corresponding to the same private key is formed, seamlessly integrating the new employee into the transaction signing process.
Fireblocks MPC wallet architecture overview
As depicted in the following architecture diagram, a distributed and highly available MPC wallet solution consists of multiple MPC cosigners per participant deployed in different AWS accounts, in multiple AWS Regions and multiple Availability Zones.
Each MPC cosigner connects to other MPC cosigners to create valid blockchain signatures such as ECDSA or EdDSA. Network-based message exchange can be done either using peer-to-peer (p2p) such as using a library like libp2p, or a central message broker such as Amazon Simple Queue Service (Amazon SQS) or an Amazon Managed Streaming for Apache Kafka (Amazon MSK) instance.
Nitro Enclave based MPC cosigner design
As depicted in the following architecture diagram, a cosigner implementation consists of two modules.
The cosigner pod is deployed on Amazon Elastic Kubernetes Service (Amazon EKS). It manages the lifecycle of a local Nitro enclave running the cosigner key shard handling component. It also provides all the required vsock proxy capabilities to enable inbound and outbound communication for the enclave.
The second module of the MPC cosigner is placed inside the enclave. The cosigner enclave is responsible for secure handling (creation, encryption, decryption, and application) of the key shards. The isolation properties and attestation features of Nitro Enclaves makes it particularly well suited as the runtime environment for critical key management tasks.
With this design, we can make sure key shards created during the DKG process are encrypted inside the enclave before being written to persistent storage like Amazon Simple Storage Service (Amazon S3).
To make sure key shards can only be decrypted inside the selected enclave, the architecture uses the Nitro Enclaves cryptographic attestation capability with AWS KMS. This is done using a customized KMS key resource policy.
The MPC signing protocol run between all cosigners has zero-trust and zero-knowledge gain principles built in. All communications are authenticated, and no cosigner can learn any sensitive information about each other during interaction.
Guiding principles for building a secure MPC wallet
In this section, we share some guidelines and best practices for building a secure MPC wallet.
Get your cryptography right
Although this is out of scope for this post, an open source implementation of the MPC-CMP algorithm used in Fireblocks can be found on GitHub.
Focus on the cosigner design and implementation
When discussing MPC wallets within Nitro Enclaves, the primary concern revolves around transaction signing capabilities. These wallets aim to minimize the attack surface by concentrating solely on running cryptographic operations. Functionalities such as balance viewing or transaction monitoring can be delegated to other services within the product ecosystem. Therefore, the focus should be on the secure design and implementation of the cosigner component itself, including aspects such as secure software development lifecycle, secure dependency management, threat modeling, and code audits, to name a few.
Establish a secure communication channel
In a zero-trust architecture, the cosigner doesn’t assume the message broker (and the other participating cosigners) to be honest. The broker may modify, omit, or replay any message sent from or to the cosigner.
The following diagram illustrates an example architecture.
MPC messages created by cosigners are protected using public key cryptography and validating each signature with the associated public key. That way, any potential intermediary risk can be mitigated.
Each MPC message has an attestation document enclosed as well. The attestation document is signed by the Nitro Hypervisor and enables each party to validate the image the cosigner is running using the associated PCR values. Also, external parties can verify that the cosigner is running in a trusted and isolated environment provided by AWS by validating the public certificate chain.
The customizable user data field incorporates a hash to link the MPC message with the attestation. This prevents attackers from using old attestations with malicious messages, and replay attacks are mitigated by tracking historical transactions using nonces.
Integrate the data persistence layer
Data persistence is required to store the key shards that are created in the end of the distributed key generation process and transient data for the lifetime of an MPC signature (for example, cryptographic commitments generated).
It’s critical to validate the availability of signatures’ transient data or key shards to avoid cosigner outages, for example, in case of a restart or other unforeseeable events.
Nitro enclaves generally lack persistent storage. As shown in the following architecture diagram, a secure solution is to use an encrypted SQLite database in volatile memory, syncing periodically with external storage like Amazon S3. Data encryption can be achieved by using symmetric keys along with the SQLite Encryption Extension.
To enforce data confidentiality, encryption and decryption keys should be derived using AWS KMS APIs that support Nitro Enclave attestation, allowing only the originating enclave to decrypt the data. You can use the AWS KMS GenerateRandom or GenerateDataKey API to securely derive the symmetric key required.
After, for example, a new version of the cosigner has been rolled out, the cosigner retrieves the encrypted database files from Amazon S3 along with the associated symmetric key, decrypts the key through AWS KMS, and uses the plaintext symmetric key to decrypt the database afterwards. The SQLite database then gets mounted into tmpfs.
You can use Amazon DynamoDB as an alternative; however, every interaction with the database service would introduce additional roundtrip latency and introduce additional encryption and decryption CPU time overhead.
Conclusion
In this post, we introduced the fundamentals of MPC-based crypto wallets. We explained the important aspects and trade-offs related to MPC solutions and explained in detail how to deploy these solutions and use Nitro Enclaves for secure key shard handling.
Sign up for the developer sandbox on Fireblocks and experience Fireblocks MPC wallets using Nitro Enclaves firsthand!
About the author
David-Paul Dornseifer is a Blockchain Development Architect at AWS. He focuses on helping customers design, develop and scale end-to-end blockchain solutions. His primary focus is on digital asset custody and key management solutions.
Ben Liderman is leading the confidential computing infrastructure and cosigners development at Fireblocks.
Source: Read More