Secret Key to Mnemonic
Description
Section titled “Description”This example demonstrates how to use secret_key_to_mnemonic() to convert a 64-byte Algorand secret key to a 25-word mnemonic. Key concepts:
- Algorand secret keys are 64 bytes: bytes 0-31 are the seed, bytes 32-63 are the public key
- secret_key_to_mnemonic() extracts the first 32 bytes (seed portion) and converts to mnemonic
- This produces the same result as calling mnemonic_from_seed() on the seed directly
Prerequisites
Section titled “Prerequisites”No LocalNet required - pure utility function
Run This Example
Section titled “Run This Example”From the repository’s examples directory:
cd examplesuv run python algo25/03_secret_key_to_mnemonic.py# ruff: noqa: N999, C901, PLR0912, PLR0915"""Example: Secret Key to Mnemonic
This example demonstrates how to use secret_key_to_mnemonic() to convert a64-byte Algorand secret key to a 25-word mnemonic.
Key concepts:- Algorand secret keys are 64 bytes: bytes 0-31 are the seed, bytes 32-63 are the public key- secret_key_to_mnemonic() extracts the first 32 bytes (seed portion) and converts to mnemonic- This produces the same result as calling mnemonic_from_seed() on the seed directly
No LocalNet required - pure utility function"""
import secrets
from shared import format_hex, print_header, print_info, print_step, print_success
from algokit_algo25 import mnemonic_from_seed, secret_key_to_mnemonic
def main() -> None: print_header("Secret Key to Mnemonic Example")
# Step 1: Create a 64-byte secret key (simulating what Algorand uses) print_step(1, "Create a 64-byte Algorand Secret Key")
# In Algorand, the secret key is 64 bytes: # - Bytes 0-31: The seed (private key material) # - Bytes 32-63: The public key (derived from the seed) secret_key = secrets.token_bytes(64)
print_info(f"Secret key length: {len(secret_key)} bytes") print_info("Structure:") print_info(f" Bytes 0-31 (seed): {format_hex(secret_key[:32])}") print_info(f" Bytes 32-63 (public key): {format_hex(secret_key[32:64])}")
# Step 2: Display the secret key structure print_step(2, "Understand the Secret Key Structure")
print_info("Algorand secret keys are 64 bytes (512 bits):") print_info("") print_info(" +--------------------------------+--------------------------------+") print_info(" | Seed (32 bytes) | Public Key (32 bytes) |") print_info(" | Bytes 0-31 | Bytes 32-63 |") print_info(" | (Private key material) | (Derived from seed) |") print_info(" +--------------------------------+--------------------------------+") print_info("") print_info("The seed is the actual secret; the public key is appended for convenience.") print_info("When converting to mnemonic, only the seed portion is needed.")
# Step 3: Convert secret key to mnemonic using secret_key_to_mnemonic print_step(3, "Convert Secret Key to Mnemonic using secret_key_to_mnemonic()")
mnemonic_from_secret_key = secret_key_to_mnemonic(secret_key) words = mnemonic_from_secret_key.split(" ")
print_info(f"Mnemonic has {len(words)} words") print_info("Mnemonic words:") # Display words in rows of 5 for readability for i in range(0, len(words), 5): row = words[i : i + 5] numbered = " ".join(f"{i + j + 1:2}. {w:<10}" for j, w in enumerate(row)) print_info(f" {numbered}")
# Step 4: Explain what secret_key_to_mnemonic does internally print_step(4, "What secret_key_to_mnemonic() Does Internally")
print_info("secret_key_to_mnemonic(secret_key) performs these steps:") print_info(" 1. Extract the seed: secret_key[:32]") print_info(" 2. Call mnemonic_from_seed(seed) on the extracted 32 bytes") print_info(" 3. Return the resulting 25-word mnemonic") print_info("") print_info("This is equivalent to:") print_info(" seed = secret_key[:32]") print_info(" mnemonic = mnemonic_from_seed(seed)")
# Step 5: Compare with calling mnemonic_from_seed directly print_step(5, "Compare with mnemonic_from_seed() on First 32 Bytes")
seed = secret_key[:32] mnemonic_from_seed_direct = mnemonic_from_seed(seed)
print_info("Method 1: secret_key_to_mnemonic(64-byte secret_key)") print_info(f' Result: "{" ".join(mnemonic_from_secret_key.split(" ")[:5])}..."') print_info("") print_info("Method 2: mnemonic_from_seed(secret_key[:32])") print_info(f' Result: "{" ".join(mnemonic_from_seed_direct.split(" ")[:5])}..."')
mnemonics_match = mnemonic_from_secret_key == mnemonic_from_seed_direct print_info("") print_info(f"Mnemonics identical: {'Yes' if mnemonics_match else 'No'}")
if mnemonics_match: print_success("Both methods produce identical mnemonics!")
# Step 6: Demonstrate that only the seed portion matters print_step(6, "Only the Seed Portion Affects the Mnemonic")
# Create a second secret key with the same seed but different "public key" bytes secret_key2 = bytearray(64) secret_key2[:32] = seed # Same seed secret_key2[32:] = secrets.token_bytes(32) # Different public key portion secret_key2 = bytes(secret_key2)
mnemonic1 = secret_key_to_mnemonic(secret_key) mnemonic2 = secret_key_to_mnemonic(secret_key2)
print_info("Secret Key 1 (first 8 bytes of public key):") print_info(f" {format_hex(secret_key[32:40])}...") print_info("Secret Key 2 (first 8 bytes of public key):") print_info(f" {format_hex(secret_key2[32:40])}...") print_info("") print_info("Same seed, different public key bytes...") print_info(f'Mnemonic 1: "{" ".join(mnemonic1.split(" ")[:3])}..."') print_info(f'Mnemonic 2: "{" ".join(mnemonic2.split(" ")[:3])}..."') print_info(f"Mnemonics identical: {'Yes' if mnemonic1 == mnemonic2 else 'No'}")
if mnemonic1 == mnemonic2: print_success("The public key portion (bytes 32-63) does not affect the mnemonic.")
# Step 7: Use cases for secret_key_to_mnemonic print_step(7, "When to Use secret_key_to_mnemonic()")
print_info("Use secret_key_to_mnemonic() when you have a 64-byte Algorand secret key") print_info("and need to convert it to a mnemonic for backup or display.") print_info("") print_info("Common scenarios:") print_info(" - Exporting an account from a wallet") print_info(" - Displaying the recovery phrase after key generation") print_info(" - Converting keys from ed25519 libraries that output 64-byte keys") print_info("") print_info("Use mnemonic_from_seed() directly when you only have the 32-byte seed.")
# Step 8: Summary print_step(8, "Summary")
print_info("secret_key_to_mnemonic() converts a 64-byte secret key to a 25-word mnemonic:") print_info(" - Input: 64-byte bytes object (Algorand secret key format)") print_info(" - Output: Space-separated string of 25 words") print_info(" - Internally extracts bytes 0-31 (the seed portion)") print_info(" - Produces identical result to mnemonic_from_seed(seed)") print_info(" - Bytes 32-63 (public key portion) are ignored") print_info("") print_info("Relationship between functions:") print_info(" secret_key_to_mnemonic(sk) == mnemonic_from_seed(sk[:32])")
print_success("Secret Key to Mnemonic example completed successfully!")
if __name__ == "__main__": main()Other examples in Mnemonic Utilities
Section titled “Other examples in Mnemonic Utilities”- Mnemonic from Seed
- Seed from Mnemonic
- Secret Key to Mnemonic
- Master Derivation Key Functions
- Error Handling for Mnemonic Functions