Skip to content

Identity

import "github.com/eljojo/nara/identity"

const (
SeedLen = 32
TagLen = 8
SoulLen = SeedLen + TagLen // 40 bytes total
)

func CollectSoulFragments() string

func ComputeNaraID(soulBase58 string, name types.NaraName) (types.NaraID, error)

ComputeNaraID computes a deterministic, stable ID from soul and name. This allows distinguishing naras with the same name but different souls.

Computation: ID = Base58(SHA256(soul_bytes || name_bytes))

Where:

  • soul_bytes: Base58-decoded 40-byte soul (32-byte seed + 8-byte tag)
  • name_bytes: UTF-8 encoded name string
  • Result: Base58-encoded hash for human readability

The ID is:

  • Deterministic: Same soul+name always produces same ID
  • Stable: Survives restarts (doesn’t depend on ephemeral keypairs)
  • Unique: Different souls with same name produce different IDs

func ComputeTag(seed [SeedLen]byte, name types.NaraName) [TagLen]byte

ComputeTag computes the HMAC tag that bonds a seed to a name

func FormatPublicKey(pub ed25519.PublicKey) string

FormatPublicKey encodes a public key as Base64 for transmission

func FormatSoul(soul SoulV1) string

FormatSoul encodes a SoulV1 as a Base58 string

func Gemstone(name string, soul string) string

func GenerateName(id string) string

func HashBytes(data []byte) []byte

HashBytes creates a SHA256 hash of the given data

func HashHardware(fragments string) []byte

HashHardware creates a hardware fingerprint hash

func IsGenericHostname(hostname string) bool

func NameFromSoul(soul SoulV1) types.NaraName

NameFromSoul derives the generated name from a soul’s seed

func ParsePublicKey(s string) (ed25519.PublicKey, error)

ParsePublicKey decodes a Base64 public key

func SignContent(s Signable, kp NaraKeypair) string

SignContent signs a Signable’s content directly (no pre-hashing). This matches the existing signing pattern used throughout the codebase. Returns a base64-encoded Ed25519 signature.

func ValidateBond(soul SoulV1, name types.NaraName) bool

ValidateBond checks if a soul is validly bonded to a name

func VerifyContent(s Signable, publicKey []byte, signature string) bool

VerifyContent verifies a signature against a Signable’s content. The signature should have been created with SignContent.

func VerifySignature(publicKey ed25519.PublicKey, message, signature []byte) bool

VerifySignature verifies a signature against a public key and message

func VerifySignatureBase64(publicKey []byte, message []byte, signatureBase64 string) bool

VerifySignatureBase64 verifies a base64-encoded signature

EncryptionKeypair holds a symmetric key derived from an Ed25519 private key Used for self-encryption (encrypt data that only the owner can decrypt)

type EncryptionKeypair struct {
SymmetricKey []byte // 32-byte key for XChaCha20-Poly1305
}

func DeriveEncryptionKeys(privateKey ed25519.PrivateKey) EncryptionKeypair

DeriveEncryptionKeys derives a symmetric encryption key from an Ed25519 private key Uses HKDF with SHA-256 to derive a 32-byte key for XChaCha20-Poly1305

func (kp EncryptionKeypair) DecryptForSelf(nonce, ciphertext []byte) ([]byte, error)

DecryptForSelf decrypts ciphertext using XChaCha20-Poly1305

func (kp EncryptionKeypair) EncryptForSelf(plaintext []byte) (nonce, ciphertext []byte, err error)

EncryptForSelf encrypts plaintext using XChaCha20-Poly1305 with a random nonce Returns the nonce and ciphertext separately so the nonce can be stored with the payload

type IdentityResult struct {
Name types.NaraName // Changed from string
Soul SoulV1
ID types.NaraID // Nara ID: deterministic hash of soul+name
IsValidBond bool
IsNative bool
}

func DetermineIdentity(nameArg types.NaraName, soulArg, hostname string, hwFingerprint []byte) IdentityResult

DetermineIdentity resolves name and soul from arguments and hardware. hostname should be the short hostname (no domain suffix).

NaraKeypair holds an Ed25519 keypair derived from a soul

type NaraKeypair struct {
PrivateKey ed25519.PrivateKey
PublicKey ed25519.PublicKey
EncryptionKey EncryptionKeypair // Cached encryption key for self-encryption
}

func DeriveKeypair(soul SoulV1) NaraKeypair

DeriveKeypair deterministically derives an Ed25519 keypair from a soul’s seed. The soul’s 32-byte seed is exactly Ed25519’s SeedSize, so same soul = same keypair. Also derives and caches the encryption key for efficiency.

func (kp NaraKeypair) Open(nonce, ciphertext []byte) ([]byte, error)

Open decrypts ciphertext using the cached encryption key. Convenience method on NaraKeypair that delegates to EncryptionKey.

func (kp NaraKeypair) Seal(plaintext []byte) (nonce, ciphertext []byte, err error)

Seal encrypts plaintext using the cached encryption key. Convenience method on NaraKeypair that delegates to EncryptionKey.

func (kp NaraKeypair) Sign(message []byte) []byte

Sign signs a message with the keypair’s private key

func (kp NaraKeypair) SignBase64(message []byte) string

SignBase64 signs a message and returns the signature as a base64 string

Signable is implemented by types that can produce canonical content for signing. This provides a unified interface for cryptographic signing across different message types.

type Signable interface {
// SignableContent returns the canonical string representation for signing.
// The string should be deterministic and include all fields that need authentication.
SignableContent() string
}

type SoulV1 struct {
Seed [SeedLen]byte
Tag [TagLen]byte
}

func NativeSoulCustom(hwFingerprint []byte, name types.NaraName) SoulV1

NativeSoulCustom generates a deterministic soul for a custom name on given hardware

func NativeSoulGenerated(hwFingerprint []byte) SoulV1

NativeSoulGenerated generates a deterministic soul for generated-name mode

func ParseSoul(s string) (SoulV1, error)

ParseSoul decodes a Base58 string into a SoulV1

Generated by gomarkdoc