| Crates.io | valinor-identity |
| lib.rs | valinor-identity |
| version | 0.1.0 |
| created_at | 2026-01-09 14:51:46.062639+00 |
| updated_at | 2026-01-09 14:51:46.062639+00 |
| description | Cryptographic identity and key management for MudWorld platform |
| homepage | |
| repository | https://github.com/douglance/mudworld |
| max_upload_size | |
| id | 2032210 |
| size | 24,812 |
Cryptographic identity management for the MudWorld ecosystem, providing Ed25519-based key generation, signing, verification, and principal ID derivation.
valinor-identity solves the fundamental problem of cryptographic identity in distributed systems. It provides a minimal, auditable implementation for:
Use valinor-identity when you need to:
msg_, room_, user_)Add to your Cargo.toml:
[dependencies]
valinor-identity = { path = "../valinor-identity" }
Or if published:
[dependencies]
valinor-identity = "0.1"
| Type | Description |
|---|---|
Identity |
Ed25519 keypair with signing capabilities |
IdentityError |
Error type for key/signature operations |
| Function | Description |
|---|---|
Identity::generate() |
Create a new random identity |
Identity::load(path) |
Load identity from base64-encoded file |
Identity::save(path) |
Persist identity to file |
Identity::sign(message) |
Sign arbitrary bytes |
Identity::principal_id() |
Get stable principal ID string |
verify_signature(pubkey, message, signature) |
Verify a detached signature |
derive_principal_id(pubkey) |
Derive principal ID from raw public key bytes |
generate_id(prefix) |
Generate a unique ID with custom prefix |
use valinor_identity::Identity;
let identity = Identity::generate();
// Get the principal ID (stable identifier derived from public key)
let principal = identity.principal_id();
println!("Principal: {principal}"); // e.g., "p_abc123..."
// Access raw public key bytes
let pubkey: [u8; 32] = identity.public_key_bytes();
use valinor_identity::Identity;
use std::path::Path;
// Generate and save
let identity = Identity::generate();
identity.save(Path::new("~/.config/mudworld/identity")).unwrap();
// Load later
let loaded = Identity::load(Path::new("~/.config/mudworld/identity")).unwrap();
assert_eq!(identity.public_key_bytes(), loaded.public_key_bytes());
use valinor_identity::{Identity, verify_signature};
let identity = Identity::generate();
let message = b"authenticate this request";
// Sign
let signature = identity.sign(message);
// Verify (e.g., on server side with only the public key)
let pubkey = identity.public_key_bytes();
verify_signature(&pubkey, message, &signature.to_bytes()).unwrap();
use valinor_identity::generate_id;
let message_id = generate_id("msg_"); // e.g., "msg_V1StGXR8_Z5jdHi6B"
let room_id = generate_id("room_"); // e.g., "room_Uakgb_J5m9g-0JDMbcJqL"
let user_id = generate_id("u_"); // e.g., "u_FybRnyPW3Ie4dXe"
use valinor_identity::derive_principal_id;
let pubkey: [u8; 32] = /* from external source */;
let principal = derive_principal_id(&pubkey);
// Returns "p_" + URL-safe base64 of first 10 bytes of SHA-256 hash
use valinor_identity::{Identity, IdentityError};
match Identity::load(path) {
Ok(id) => println!("Loaded: {}", id.principal_id()),
Err(IdentityError::InvalidKeyFormat) => eprintln!("Corrupted or invalid key file"),
Err(IdentityError::Io(e)) => eprintln!("File error: {e}"),
Err(IdentityError::SignatureInvalid) => unreachable!(), // Not returned by load
}
Identity files are base64-encoded 64-byte keypairs (32-byte secret + 32-byte public). Example:
aW1hZ2luZSB0aGlzIGlzIGEgdmFsaWQgNjQgYnl0ZSBrZXlwYWlyIGVuY29kZWQgYXMgYmFzZTY0...
SigningKey and zeroed on drop (via ed25519-dalek)OsRng for cryptographically secure random generation| Crate | Relationship |
|---|---|
valinor-auth |
Uses Identity for authentication flows |
valinor-session |
Associates sessions with principal IDs |
valinor-wire |
Serializes signatures for network transport |
valinor-acl |
Maps principal IDs to permissions |
MIT