macula_identity (macula v3.13.0)

View Source

Ed25519 identities and the S/Kademlia crypto puzzle.

A Macula NodeId is an Ed25519 public key (32 bytes). Identities are optionally "puzzle-hardened": the pubkey satisfies SHA-256(pubkey) having at least N leading zero bits. This raises the cost of mass identity minting (Sybil defence).

See plans/PLAN_MACULA_V2_PART1_FOUNDATIONS.md sections 4.1–4.4.

Summary

Functions

Generate a fresh Ed25519 key pair. Does not grind a puzzle.

Generate a key pair, optionally grinding until the puzzle is satisfied.

Load a key pair from disk.

NodeId of an identity. Phase 1: NodeId == public key.

SHA-256 of the public key — the proof-of-work output measured.

Puzzle validity against the application-configured difficulty.

Save a key pair to disk atomically (write-tmp + rename) with 0600 perms.

Types

key_pair/0

-type key_pair() :: #{public := pubkey(), private := privkey()}.

node_id/0

-type node_id() :: pubkey().

privkey/0

-type privkey() :: <<_:256>>.

pubkey/0

-type pubkey() :: <<_:256>>.

sig/0

-type sig() :: <<_:512>>.

Functions

generate()

-spec generate() -> key_pair().

Generate a fresh Ed25519 key pair. Does not grind a puzzle.

generate(Opts)

-spec generate(#{puzzle => boolean(), difficulty => non_neg_integer(), _ => _}) -> key_pair().

Generate a key pair, optionally grinding until the puzzle is satisfied.

Opts:

  • puzzle :: boolean() — default false
  • difficulty :: non_neg_integer() — leading zero bits required

load(Path)

-spec load(file:name_all()) -> {ok, key_pair()} | {error, term()}.

Load a key pair from disk.

node_id(Pub)

-spec node_id(key_pair() | pubkey()) -> node_id().

NodeId of an identity. Phase 1: NodeId == public key.

private(_)

-spec private(key_pair()) -> privkey().

public(_)

-spec public(key_pair()) -> pubkey().

puzzle_evidence(Pub)

-spec puzzle_evidence(pubkey() | key_pair()) -> <<_:256>>.

SHA-256 of the public key — the proof-of-work output measured.

puzzle_valid(X)

-spec puzzle_valid(pubkey() | key_pair()) -> boolean().

Puzzle validity against the application-configured difficulty.

puzzle_valid(X, Difficulty)

-spec puzzle_valid(pubkey() | key_pair(), non_neg_integer()) -> boolean().

save(Path, _)

-spec save(file:name_all(), key_pair()) -> ok | {error, term()}.

Save a key pair to disk atomically (write-tmp + rename) with 0600 perms.

sign(Msg, Priv)

-spec sign(iodata(), key_pair() | privkey()) -> sig().

verify(Msg, Sig, Pub)

-spec verify(iodata(), sig(), pubkey()) -> boolean().