Node ID Generation

Table of Contents


We explain the node ID generation process.


Identity module is available on zbus over the following channel


Home Directory

identity keeps some data in the following locations



Identity manager is responsible for maintaining the node identity (public key). The manager make sure the node has one valid ID during the entire lifetime of the node. It also provide service to sign, encrypt and decrypt data using the node identity.

On first boot, the identity manager will generate an ID and then persist this ID for life.

Since the identity daemon is the only one that can access the node private key, it provides an interface to sign, verify and encrypt data. This methods are available for other modules on the local node to use.

On Node Booting

  • Check if node already has a seed generated
  • If yes, load the node identity
  • If not, generate a new ID
  • Start the zbus daemon.

ID generation

At this time of development the ID generated by identityd is the base58 encoded public key of a ed25519 key pair.

The key pair itself is generated from a random seed of 32 bytes. It is this seed that is actually saved on the node. And during boot the key pair is re-generated from this seed if it exists.


The signing and encryption capabilities of the identity module rely on this ed25519 key pair.

For signing, it directly used the key pair. For public key encryption, the ed25519 key pair is converted to its cure25519 equivalent and then use use to encrypt the data.

zinit unit

The zinit unit file of the module specify the command line, test command, and the order where the services need to be booted.

identityd require storaged to make sure the seed is persisted over reboots, to make sure node has the same ID during the full life time of the node. The identityd daemon is only considered running if the seed file exists.

exec: /bin/identityd
test: test -e /var/cache/modules/identity/seed.txt
  - storaged


For an up to date interface please check code here

package pkg

// Identifier is the interface that defines
// how an object can be used as an identity
type Identifier interface {
	Identity() string

// StrIdentifier is a helper type that implement the Identifier interface
// on top of simple string
type StrIdentifier string

// Identity implements the Identifier interface
func (s StrIdentifier) Identity() string {
	return string(s)

// IdentityManager interface.
type IdentityManager interface {
	// NodeID returns the node id (public key)
	NodeID() StrIdentifier

	// NodeIDNumeric returns the node registered ID.
	NodeIDNumeric() (uint32, error)

	// FarmID return the farm id this node is part of. this is usually a configuration
	// that the node is booted with. An error is returned if the farmer id is not configured
	FarmID() (FarmID, error)

	// Farm returns name of the farm. Or error
	Farm() (string, error)

	//FarmSecret get the farm secret as defined in the boot params
	FarmSecret() (string, error)

	// Sign signs the message with privateKey and returns a signature.
	Sign(message []byte) ([]byte, error)

	// Verify reports whether sig is a valid signature of message by publicKey.
	Verify(message, sig []byte) error

	// Encrypt encrypts message with the public key of the node
	Encrypt(message []byte) ([]byte, error)

	// Decrypt decrypts message with the private of the node
	Decrypt(message []byte) ([]byte, error)

	// EncryptECDH aes encrypt msg using a shared key derived from private key of the node and public key of the other party using Elliptic curve Diffie Helman algorithm
	// the nonce if prepended to the encrypted message
	EncryptECDH(msg []byte, publicKey []byte) ([]byte, error)

	// DecryptECDH decrypt aes encrypted msg using a shared key derived from private key of the node and public key of the other party using Elliptic curve Diffie Helman algorithm
	DecryptECDH(msg []byte, publicKey []byte) ([]byte, error)

	// PrivateKey sends the keypair
	PrivateKey() []byte

// FarmID is the identification of a farm
type FarmID uint32
Last change: 2024-02-27