Do you know how keys are made?

TL;DR: While problems with key generation have caused millions of crypto users to lose funds, Zengo wallet’s MPC technology solves the single-point-of-failure (SPOF) vulnerability associated with key generation in traditional wallets.

Introduction: The vulnerability (nearly) everyone overlooks

It’s time to have the conversation.

It’s time you know how babies keys are made. Why? Millions of crypto wallets have lost billions of dollars from an overlooked vulnerability at the core of most self-custodial wallets: Key generation.

While everyone focuses on securing their private keys (and seed phrases) for the long-term, key generation in of itself is a critical and overlooked part of every self-custodial security model. 

This blog is split into two sections: Beginner and Advanced. In the Beginner section we will use a simple analogy (a king and his treasure chest!) to explain the core problem with this overlooked vulnerability. In the Advanced section we will dive into how crypto keys are generated, the possible pitfalls with this process, and how a user can avoid them. Most importantly, we will demonstrate how this exemplifies the core problem of wallet key centralization, and how Zengo’s unique MPC technology solves the root cause of this problem by removing the single-point-of-failure (SPOF) vulnerability inherent to traditional seed phrase wallets.

Section A: Beginner

Introducing the king, his treasure, and his trustworthy(?) servants

Key generation is a one-time action that has broad and critical implications. To illustrate this point, let’s take the following brick and mortar analogy: A king wants to secure the kingdom’s crown jewels in a treasure chest. While the chest itself might be quite secure, it can only be opened with a key. So the question is: Where can the King securely store this key so no one else can find it but him?

The king calls his loyal servant and orders him to hide the chest’s tiny key in any randomly-selected place on planet earth (including deep inside of it). The servant does as instructed and tells the king its location.

If everything goes well, only the king can navigate to the relevant coordinates using GPS, access the key, and unlock the treasure chest. At the same time, any evil robber who wants to find this key would need to scan the entire planet earth to find it, rendering their mission probabilistically impossible.

Let’s pause the story for a moment: This is essentially the same process that happens during a traditional crypto wallet’s private key generation. A user, the king, has a crypto wallet, the chest, that can only be accessed with the special private key, the tiny key hidden somewhere in the world. Now, back to the story. Let’s find out what happens!

As time passes, the security-minded king realizes that many things can go wrong with the current system, especially because his servant represents a single-point-of-failure (SPOF):

  • The servant may be bribed or tortured by evil robbers in order to divulge the key coordinates and allow them to steal the key and unlock the treasure 
  • Whenever the king wants to access his crown jewels, the servant needs to fetch the key from its hiding place, thus giving an opportunity for the evil robbers to attack the servant and take the key
  • The servant may act in negligence or simply not be as good as hiding the key as the king expected he would be: Instead of hiding the key in a random place, the servant might put the key in a predictable place or even an area, making the evil robbers – who are quite sophisticated – able to find it easily

The king gets a great idea. What if he uses two parts of a key instead of just one? If there are two servants, and two parts of the key, then any single mistake would likely get mitigated by a reliance on the rest of the system to open the treasure chest.

Therefore, the king decides to split the key to the treasure chest into two, giving each part of the key to two different servants. The king then commands each servant, separately, to hide their part of the key independently – somewhere in the vast world.

As a result:

  • Even if one of the servants somehow reveals the coordinates of their half of the key and the evil robbers are somehow able to find it, the treasure chest cannot be opened without the other half of the key
  • Even if one of the servants is negligent and hides the key in a predictable location, the fact that the other servant had properly hidden the other half of the key saves the kingdom’s treasure

And the king and the kingdom lived happily ever after.

This story should illustrate the perils of the single-point-of-failure created by relying on a traditional seed phrase wallet. It doesn’t matter if it’s a mobile or hardware wallet – they share the same structural vulnerability: One key, generated one time, in one location, by one method, using one type of software (and sometimes one type of hardware).

As you can now see, architecture that creates redundancy and splits the key generation between multiple parties using secure Multi-Party Computation (MPC) can be vastly superior. This distribution of responsibility is pivotal not just for the ongoing security of protecting the keys from theft but also for the random generation of these keys that was the root cause of the security incidents mentioned above.

In the advanced section below, this blog will tie the above analogy to the technical details of crypto wallets and specifically to private key generation. Readers who are less interested in the technical details may want to skip to the final concluding section.

Section B: Advanced

Seeds, private keys, public keys, and addresses

Some might think their crypto wallet’s private key needs to be generated in a clever way, however the truth is much more simple: Almost any key will do, as long as it is randomly generated.

A key is generated by following this steps (standardized in BIP-39) :

  1. Selecting a number at random from a large enough set of numbers
    1. To allow backup functionality this number can be encoded into a seed phrase, by grouping every 11 bits together and assigning to each group a word out of 2048 word dictionary (some redundancy is added on the way to allow error detection) and writing it down for backup purposes
  2. That number is then manipulated by multiple one-way functions (one-way means that it is very hard to find the inputs that created that output) so that it can effectively create multiple private keys such that the wallet can securely support multiple addresses and different chains without having to regenerate a random number for each 
  3. Using Elliptic Curve arithmetic a public key is computed from the private key
  4. From the public key an address is derived (e.g. in Ethereum the address is the hexadecimal representation of the first 20 bytes of the hash of the public key)

As we can see, the main requirements for the initial number is for it to be:

  • Selected in random
  • From a large enough set 

If one of these requirements is not fulfilled then attackers might be able to guess that number and then repeat the aforementioned steps to recreate the private key and run away with the king’s user’s funds.

Returning to the hidden tiny physical key analogy above: If the coordinates of the key are expressed with 128 bits, and the servant can hide it anywhere on planet earth (including deep inside) then the volume of the key is about 3 cubic micrometers. By comparison, the volume of the smallest man-made object, the Trust sculpture, is 160,000 cubic micrometers or more than 50,000 times larger than this key!

The Trust sculpture standing inside the eye of a needle: The world’s smallest man made object (source:

However, if the servant puts the key in a predictable place or in a small area, then the attacker’s mission of scanning becomes feasible. For example, if the servant is using only 32 bits of randomness instead of 128, then the possible area for the attacker to scan dramatically shrinks from the whole of planet earth into 4.5 KM cube!

Here are the calculations: According to NASA’s fact sheet, planet earth’s volume is 108.321*1010 km3 or 108*1037 in cubic micrometers, as 1 KM is 109 micrometers. The result of dividing it by the size of the key space span by 128 bits, namely  2128 , yields that the volume of such a physical key would be 3 cubic micrometers. According to the Trust story the sculpture dimensions are  80 x 100 x 20 micrometers or 160000 cubic micrometers. A physical area of span by just 32 bit would be 232  * 3 cubic micrometers or  96* 227 = 96 km3 .Taking a cubic root out of it yields 4.5, which means the attacker search area is equivalent to a cube where each side 4.5 km long.

An actual example in which the first requirement of “selection in random” was not met is the “brain wallet” case, in which the initial number was the result of a humanly selected passphrase.

In 2015, Ryan Castellucci showed that he could crack many brain wallets quickly as humans tend to select not so random passphrases (e.g. “Down the Rabbit-Hole”- held about 85 BTC in July 2012).
Another actual example in which the second requirement of “a large enough set” is the Trust wallet extension case in which the set from which the number was selected was only of 32 bits.

The problem with random numbers

The problem with random numbers is that there is no such a thing.

“Random number“ is a colloquialism for “a number selected at random”. This is not merely a matter of linguistic nit-picking, but a matter of great importance. Since the randomness is a property of the process and not of the number itself, there is no way to find out if a number is random.

Going back to our king above, the king cannot know if the key’s coordinates were generated randomly, or selected by the servant simply because the numbers represented his social security number multiplied by the birth dates of the his family members.


Therefore users and programs are almost totally at the mercy of the environment in which they execute (i.e. the computing device’s hardware and operating system) when it comes to randomness.

While some obvious mistakes can be found with code auditing, it is virtually impossible to know for a fact if the specific computing device had indeed randomly selected a value and that this selection process was not abused by some hardware implant, glitch or malware.

As a result, wallet users must blindly trust the computing device that generates the key for the critical task of generating it in a random manner.

A better approach: MPC and randomness

The final part of connecting the story above to the concrete technical details of crypto wallets is the technology that eliminates the single-point-of-failure (SPOF) and allows the king to split the responsibility between multiple servants. In cryptography, this technology is called Multi-Party Computation (MPC).

Zengo was launched on the premise of creating a secure non-custodial crypto wallet that has no single-point-of-failure (SPOF). By leveraging Multi-Party Computation (MPC) cryptography, Zengo launched the first consumer MPC crypto wallet in 2019. To date, this distributed system has secured over 1 million Zengo wallets, with zero instances of hacks, wallets drained, or accounts taken over.

Using a 2-of-2 Multi-Party Computation (MPC) framework, each of the two Zengo parties (Zengo Server and Zengo app on the user device) independently generate their own “Secret Share” during the wallet creation process. The share randomly generated on the user’s device is called the Personal Share, is tied to the user’s device hardware, and leverages the device’s hardware based random generator (TRNG) where applicable. The share randomly generated on Zengo’s remote server is called the Remote Share. Only the Personal share can initialize and sign transactions, all of which are verified by the device’s hardware (Secure Enclave or Trusted Execution Environment). Learn more.

Using MPC, these two “Secret Shares” are able to compute their corresponding public key and make sure the process was done in a secure manner.

To sign transactions and effectively spend the cryptoassets, the parties engage in a multi-staged protocol to mutually sign the transaction without revealing their shares to one another.

This elegant architecture solves many SPOF vulnerabilities associated with traditional crypto wallets, such as:

  • The SPOF of the private key is solved by ensuring that private key generation is shared by two parties in two locations using two different methods
  • The SPOF of the private key for daily transactions is solved by requiring the two secret shares to compute together, each of which are protected and secured in different and orthogonal ways 
  • The SPOF of seed phrase recovery is solved by Zengo’s 3-factor Secure Recovery feature

Most importantly for this topic of randomness, Zengo’s process solves the SPOF of random number generation: Since each of the secret shares is distributively generated it means that even if the random number generation of one of the parties is faulty or even abused by malware, the randomness of the other party compensates for that, such that the overall randomness of the private key is sufficient.

More technically speaking, since MPC security is proven against a fully malicious party, it is by definition protected against a somewhat malicious party that its maliciousness is limited to the random number generation phase.

It should be noted that other projects, such as Drand, are harnessing the power of distributed computing with MPC to solve the issue of randomness generation SPOF, for non cryptocurrency-related use cases.

Summing it up: Trust MORE (parties) – not less

The topic of crypto wallet private key generation has been largely overlooked by most users, but proves to be an issue that keeps haunting wallets and causing great losses.

Since a private key cannot be generated by the users themselves, but also cannot be proven to be random, users do not have a way to validate the randomness of their key and must trust their wallet for it. 

This issue is yet another manifestation of the greater core issue of relying on a single party for a wallet. In order to solve this core issue along with the specific randomness issue, we must accept the fact that users need to trust some external entities and switch to a more robust architecture that strives to reduce the trust in each involved party by increasing the number of parties.

Adding parties reduces the required trust in each and makes the system more robust (See

Zengo’s unique MPC architecture allows users to avoid many Single Points of Failure (SPOFs) including this specific issue of randomness.

Learn more and dive into our open-source MPC library on our Github:, follow us @Zengo and reach out at [email protected] with questions.