Francesco Ceccon

How to generate Stellar keys

What is a key pair?

Stellar keys are used to authenticate and identify users on the network. Stellar accounts are uniquely identified by their public key, also known as account id. A Stellar account id is a string that starts with the letter G, this key is safe to share with others. Accounts are controlled using a secret key seed, a string starting with S, and they should never be shared with other people or applications. The secret key seed is used to derive the private key. A private key and a public key together are known as a key pair. The private key is used to sign operations that modify the Stellar account state on the ledger.

Generate key pairs with one of the SDKs

Now that we know what is a key pair and what it is used for, we can see how to generate it using four different SDKs.

Javascript

The stellar-base package is officially maintained by the Stellar Development Foundation and is available on npm.

import { Keypair } from "stellar-base";

// Generate random key pair
Keypair.random();

// Generate key pair from secret
Keypair.fromSecret("SA6KO...PRET");

// Generate key pair from account id
Keypair.fromPublicKey("GBMZ...ZPJK");

Rust

The stellar-base crate provides low-level Stellar types, including key pairs. You can fetch it directly from crates.io. The Rust SDK provides a KeyPair type that contains both the private and public keys, and a PublicKey type that contains only the public key. With this API design, it’s impossible to accidentally sign a transaction with a key pair that was constructed from the public key only.

use stellar_base::crypto::{KeyPair, PublicKey};

// Generate random key pair
KeyPair::random()?;

// Generate key pair from secret
KeyPair.from_secret_seed("SA6KO...PRET")?;

// Generate public key from account id
PublicKey::from_account_id("GBMZ...ZPJK")?;

C#

The dotnet-stellar-sdk is a C# library to interact witth the Stellar ecosystem. It can be used in any language that targets .NET Standard 2.0 or above.

using stellar_dotnet_sdk;

// Generate random key pair
KeyPair.Random();

// Generate key pair from secret
KeyPair.FromSecretSeed("SA6KO...PRET");

// Generate key pair from account id
KeyPair.FromAccountId("GBMZ...ZPJK");

Python

The Python stellar-sdk is available on PyPi and can be installed with pip.

from stellar_sdk import Keypair

# Generate random key pair
Keypair.random();

# Generate key pair from secret
Keypair.from_secret("SA6KO...PRET");

# Generate key pair from account id
Keypair.from_public_key("GBMZ...ZPJK");

What’s happening behind the scenes?

Stellar uses the EdDSA signature scheme for its transactions. A private key starts its life as a 32 bytes seed that is then used to generate the private key itself. The public key can be derived from the private key or created directly from a buffer of 32 bytes. I’m not going into too much detail how the private and public keys are derived, if you’re interested you can find more in this excellent blog post by Brian Warner.

Going from a Stellar account id to a public key is very simple, you start by decoding the account id (a string starting with G) as base32 and obtaining a buffer of 35 bytes. The first byte contains information about the type of key (secret seed, account id, pre-authorized transaction, or hash(x)), the next 32 bytes contain the key itself (or the secret key seed), finally the last 2 bytes contain the key checksum. Stellar uses CRC-16 XMODEM for the checksum of bytes 1 to 32.

Public key derivation from account id
Figure 1. Public key derivation from account id

The process to compute a Stellar account id from a public key is similar, we concatenate the version byte with the public key bytes to obtain a 33 byte long payload. We then compute the 16 bit CRC of the payload. Finally, we concatenate the payload and its checksum and encode it using base32.