Skip to main content

🔐 Security and Wallet Safety

The number-one priority for many users when choosing a self-custody wallet is ensuring their digital assets are stored in a secure and reliable environment.

To maximize security and minimize the risk of being hacked, KryptoGO employs advanced technology and multiple layers of security measures in the creation, use, backup, and restoration of wallets.

KryptoGO provides diverse backup and restoration options for wallets, each accompanied by specific risks and protective measures. This section aims to compare these differences, offering users a clearer understanding to help choose their preferred method for backing up and restoring their wallets.

tip

This section is specifically about the security of KryptoGO’s Wallet app. If you want to read about the safety measures of KryptoGO’s Web SDK instead, refer to Web SDK Safety.

Glossary

Some helpful terms to know when reading this section:

TermDefinition
private keyUser’s private key, a long string of numbers and letters.
seed phraseUser’s seed phrase, usually a set of 12 English words.
Account Unlock KeyKey encryption key (KEK) generated based on the user’s password.
Account Public KeyUnique public key for each user. Forms a key pair with the Account Private Key.
Account Private KeyUnique private key for each user. Forms a key pair with the Account Public Key.
Encrypted Account Private KeyEncrypting the Account Private Key with the Account Unlock Key yields the Encrypted Account Private Key.
saltRandom string used for encryption and decryption. Each KryptoGO account has a unique string used as salt.
vaultA data structure that stores a user’s Account Public Key, Encrypted Account Private Key, and salt.
encrypted wallet dataWallet data encrypted with the Account Private Key.
Device Encryption KeyAn encryption key used to store wallets in local device storage.

Registering a KryptoGO Account

When a user initially registers for KryptoGO Wallet, a Curve25519 Account Public Key, Account Private Key, and salt will be generated locally on the device.

  • The Account Public Key is public and can be known by anyone.
  • The Account Private Key will never leave the user's device.
  • Salt is a randomly generated string on the local device.
PriKey,PubKeyKeyGen25519()saltRandBytes(32)\begin{align*} \mathbf{PriKey}, \mathbf{PubKey} &\leftarrow \text{KeyGen25519()} \\ \mathbf{salt}&\leftarrow \text{RandBytes(32)} \end{align*}

Creating or Importing a Wallet

Users have the option to either import a wallet or create a new one. In either case, KryptoGO Wallet generates a Device Encryption Key to encrypt the new wallet, storing the encrypted data in the device's local storage.

The Device Encryption Key will be stored in the device's secure storage, i.e., Keychain for iOS and Keystore for Android.

  • Secure storage is designed to isolate sensitive data from the general application storage, ensuring that unauthorized applications or external entities cannot access it.
  • Users are required to unlock their devices using their biometrics to retrieve the Device Encryption Key.

Using the Wallet for Transactions

Once the user successfully logs in and passes biometric authentication, the Device Encryption Key is used to decrypt wallet data, including the Private Key, and is stored in the local device's storage for transaction signing.

Wallet Backup and Restoration

KryptoGO Wallet offers users two backup options: Password Backup and Cloud Backup. Of course, both methods come with their corresponding wallet restoration methods: Restore Wallet with Password and Restore Wallet From Cloud.

Password Backup

When a user opts for password backup and inputs a password, the Key Derivation process is initiated. This process generates an Account Unlock Key (AUK), used for encrypting and decrypting the user's Account Private Key.

pAccount password from userssalt from local storagepnormalize(trim(p))AUKPBKDF2(p,s,310000)\begin{align*} \mathbf{p} &\leftarrow \text{Account password from user} \\ s &\leftarrow \text{salt from local storage} \\ \mathbf{p} &\leftarrow \text{normalize}(\text{trim}(\mathbf{p})) \\ \mathbf{AUK} &\leftarrow \text{PBKDF2}(\mathbf{p}, s, 310000) \\ \end{align*}

The Key Derivation process is as follows:

  1. First, the password is trimmed of whitespace characters and normalized using the Unicode Normalization Form Compatibility Decomposition (NFCD). This step is crucial to prevent decryption issues arising from varied encodings of the same Unicode on different devices.
  2. To further enhance protection against brute-force attacks, a Slow Hash algorithm, specifically PBKDF2-HMAC-SHA256 (Password-Based Key Derivation Function), is employed. This involves 310,000 rounds of hashing to generate the Account Unlock Key.
PBKDF2-HMAC-SHA256 is selected for its compatibility with a broad range of mobile devices, offering an efficient algorithm that maintains security without compromise.
PBKDF2(password,salt,iterations,dkLen):U1=HMAC(password,saltINT_to_BYTE(1))U2=HMAC(password,U1)Uiterations=HMAC(password,Uiterations1)T1=U1U2UiterationsTn=(computed similarly as T1)DK=T1T2Tnreturn DK[0dkLen]\begin{align*} \text{PBKDF2}&(password, salt, iterations, dkLen) : \\ &U_1 = \text{HMAC}(password, salt || \text{INT\_to\_BYTE}(1)) \\ &U_2 = \text{HMAC}(password, U_1) \\ &\dots \\ &U_{iterations} = \text{HMAC}(password, U_{iterations-1}) \\ &T_1 = U_1 \oplus U_2 \oplus \dots \oplus U_{iterations} \\ &\dots \\ &T_n = \dots \text{(computed similarly as \( T_1 \))} \\ &DK = T_1 || T_2 || \dots || T_n \\ &\text{return } DK[0 \dots dkLen]\end{align*}
Choosing 310,000 rounds for the Work Factor is based on the recommendation of the NIST FIPS-140 standard.

After computing the Account Unlock Key (AUK), it is used to encrypt the user's Account Private Key using AES-256 encryption, resulting in the Encrypted Account Private Key.

EncPriKeyEncAES-256(PriKey,AUK)\begin{aligned} EncPriKey \leftarrow \text{Enc}_{\text{AES-256}}(\text{PriKey}, \text{AUK}) \end{aligned}

The Account Private Key is then used to encrypt all wallet data with AES-256.

EncWalletsfor xWallets        yiEncAES-256(PriKey,x)        EncWalletsEncWallets{yi}endforreturn EncWallets\begin{aligned} &EncWallets \leftarrow \emptyset \\ &\text{for } x \in \textit{Wallets} \\ &\;\;\;\; y_i \leftarrow Enc_{\text{AES-256}}(PriKey, x) \\ &\;\;\;\; EncWallets \leftarrow EncWallets \cup \{y_i\} \\ &\text{endfor} \\ &\text{return }EncWallets \end{aligned}

The backup process is completed by backing up the encrypted wallets, salt, Account Public Key, and Encrypted Account Private Key to the cloud.

Restore Wallet with Password

Following a password backup, users can log into KryptoGO Wallet on other devices and use the password to restore all their private keys and seed phrases.

The process of restoring a wallet with password is as follows:

  1. Compute the Account Unlock Key locally using the correct password.
  2. Utilize the Account Unlock Key, in conjunction with the Encrypted Account Private Key retrieved from the cloud backup, to locally decrypt the Account Private Key .
  3. Use the Account Private Key to further decrypt all wallet private keys and seed phrases.
EncWallets,Salt,EncPriKeyCloud BackuppPassword input from userAUKPBKDF2(p,Salt,310000)PriKeyDecAES-256(AUK,EncPriKey)for xEncWallets        yiDecAES-256(PriKey,x)        WalletsWallets{yi}endforreturn Wallets\begin{aligned} &EncWallets, Salt, EncPriKey \leftarrow \text{Cloud Backup} \\ &\mathbf{p} \leftarrow \text{Password input from user} \\ &AUK \leftarrow \text{PBKDF2}(\mathbf{p}, Salt, 310000) \\ &PriKey \leftarrow Dec_{\text{AES-256}}(AUK, EncPriKey) \\ &\text{for } x \in \textit{EncWallets} \\ &\;\;\;\; y_i \leftarrow Dec_{\text{AES-256}}(PriKey, x) \\ &\;\;\;\; Wallets \leftarrow Wallets \cup \{y_i\} \\ &\text{endfor} \\ &\text{return }Wallets \end{aligned}

Password Backup Q&A

Why AES-256?

We have deliberately chosen AES-256, a mode of the AES algorithm known for its higher resistance to attacks. This selection is crucial to prevent the ciphertext from being vulnerable to cracking under specific conditions, such as chosen ciphertext attacks.

How challenging is it to breach the key derivation method employed?
  1. As of 2023, considering GPU computing power, calculating 2322^{32} hashes costs around $6. For a password with 40 bits of entropy, cracking it with two GPUs would take approximately 4-16 weeks, with an estimated cracking cost of around $770.
  2. In KryptoGO Wallet, when using password backup, the user is required to set a password that is at least 12 characters long, incorporating uppercase letters, lowercase letters, and numbers. The bit entropy for such a password is calculated as log2(6212)=12log2(62)71.45 bits.log_2(62^{12}) = 12log_2(62) ≈ 71.45\ bits.
  3. Each additional bit doubles the time or cost of cracking. Thus, the estimated cost to crack a KryptoGO Wallet password is at least 770271.4540=2.261012770 ⋅ 2^{71.45-40} = 2.26 ⋅ 10^{12}, equating to approximately 2.26 trillion USD. In terms of time, it would take at least 4271.4540/52=2.251084 ⋅ 2^{71.45-40}/52 = 2.25 ⋅ 10^8 years, which is about 225 million years.

The actual difficulty of cracking exceeds these estimates, as they only account for the process of hashing the Account Unlock Key. This does not include verifying whether this Account Unlock Key can decrypt the Encrypted Wallet data. Including this verification step would significantly increase the cracking difficulty.

What are the reasons for using the Curve25519 elliptic curve in generating the Account Private Key and Account Public Key?
  1. Computational efficiency

    With Curve 25519, the Account Public Key enables quick verification of whether the Account Private Key corresponds to it when the user enters the password to decrypt the Account Private Key. This approach obviates the need for executing the decryption process with the Account Private Key when an incorrect password is entered.

  2. Social recovery

    Social recovery allows a user A to designate another person B as an emergency contact. A and B can generate a Shared Key through the Diffie-Hellman key exchange algorithm and use this Shared Key to encrypt A’s Account Private Key, and backup the result to the cloud.

    SharedKeyPubKeyBPriKeyAEncPriKeyABEncAES-256(SharedKey,PriKeyA)\begin{aligned} &SharedKey \leftarrow PubKey_B^{PriKey_A} \\ &EncPriKey_{AB} \leftarrow Enc_{\text{AES-256}}(SharedKey, PriKey_A) \\ \end{aligned}

    If A forgets their password and requires assistance from B to recover the wallet, once B receives A's encrypted Account Private Key, B can decrypt the key using the following process:

    SharedKeyPubKeyAPriKeyBPriKeyADecAES-256(SharedKey,EncPriKeyAB)\begin{aligned} &SharedKey \leftarrow PubKey_A^{PriKey_B} \\ &PriKey_A \leftarrow Dec_{\text{AES-256}}(SharedKey, EncPriKey_{AB}) \\ \end{aligned}

    Upon completing the social recovery process, A can generate a new pair of Account Private Key and Account Public Key. This step is taken to mitigate the risk of A's Account Private Key being compromised.

Cloud Backup

Think passwords are a hassle? To offer a more convenient alternative, we have introduced a password-free backup option using cloud backups. Users can opt-in to use cloud storage to securely safeguard their private key and seed phrase.

tip

Cloud backups are opt-in. Without your consent, nothing will be saved to the cloud.

The fundamental idea behind cloud backups involves dividing the Account Private Key into several fragments, known as Key Shares, and backing them up to various cloud storages. A key feature of these Key Shares is that acquiring any two fragments enables the restoration of the user's Account Private Key.

The underlying algorithm for this process is Shamir's Secret Sharing Scheme (SSS), an efficient and secure method for secret sharing. SSS generates nn independent fragments (Secret Shares) from confidential data (Secret). With any k(kn)k (k ≤ n) out of the nn fragments, the original Secret can be reconstructed through calculations.

Here’s how Shamir’s Secret Sharing works:

  1. Let the original Secret be SS. Randomly generate a k1k-1 degree polynomial f(x)f(x) that satisfies f(x)=a0+a1x+a2x2+...+ak1xk1,where a0=Sf(x)=a_0+a_1x+a_2x^2+...+a_{k-1}x^{k-1}, where\ a_0=S.

    For each i (0in1)i\ (0≤i≤n-1), randomly generate the corresponding Key Share (xi,f(xi))(x_i, f(x_i))

  2. When the user obtains kk Key Shares, the original polynomial f(x)f(x) can be restored using the Lagrange interpolating polynomial.

    Assuming, without loss of generality, that the user acquires kk Key Shares x0,x1,...,xk1x_0, x_1,...,x_{k-1}. It can be derived that

    f(x)=i=0k1f(xi)0j<k,jixxjxixj f(x) = \sum_{i=0}^{k-1} f(x_i) \prod_{0 \leq j \lt k, j \neq i} \frac{x-x_j}{x_i-x_j}

    Thus, the original Secret f(0)f(0) can be calculated.

Restore Wallet from Cloud

In practical terms, we opt for k=2k = 2, meaning any two fragments can restore the original Secret, such as the Account Private Key. Provided that nn is any number greater than 2, multiple Key Shares can be generated and stored across different cloud backups. With just two Key Shares, users have the ability to restore their Account Private Key and decrypt the encrypted wallets’ data, thereby accessing the complete private key or seed phrase.

Users have the option to store Key Shares in cloud storages beyond KryptoGO’s own, including iCloud and Google Drive. This approach ensures that users are not solely reliant on KryptoGO's cloud backup, thereby offering the highest guarantee of data availability.

Cloud Backup Q&A

Is k=2k=2 secure enough?

With the n-choose-k cloud backup method, a hacker accessing k1k-1 Key Shares gains no insight into the final Secret value, meaning the difficulty of cracking the Secret remains unchanged. The risk emerges only if kk Key Shares are exposed simultaneously. Given the robust security of major cloud providers, the likelihood of multiple cloud accounts being compromised at once is exceedingly low. Hence, a k=2k = 2 setting is deemed sufficiently secure, given that you believe in the security of major cloud providers such as Google and Apple.

What happens if a user loses access to a Secret Share?

Suppose a Secret Share is lost on one of the cloud platforms, for instance, due to accidental deletion. In this scenario, the user can still generate a new Key Share using the existing Secret and the values of k1k-1 Key Shares stored on their local device.

By consistently monitoring the backed-up Key Share data, we can guarantee that users are always able to restore their private key or seed phrase from these cloud platforms.