Files
zeekay 165ae41805 luxfi/esign v0.2: Ed25519 sign/verify + ZAP RPC server + esignd
This commit lands the first end-to-end signable surface:

  * pkg/sign — Signer/Verifier interfaces, Ed25519 implementation
    (stdlib crypto/ed25519), method-dispatch helper. 8 unit tests:
    round-trip, deterministic-from-seed, bad-seed-length, tampered
    payload + sig, bad pubkey, bad sig length, zero-value verifier.

  * pkg/envelope — added Signature.SignerHashHex() and SeqString
    helper used by the verifier-side error reporting.

  * pkg/api — Handler with pluggable Store, in-memory MemStore for
    tests + small deployments. CreateRequest / SignRequest /
    TransitionRequest / VerifyResponse types form the wire surface.
    Handler.Sign runs cryptographic verify BEFORE calling
    envelope.AddSignature so a malformed sig never lands in the
    envelope. 3 e2e tests cover happy path, sig tampering detection,
    and crypto-fails-before-store ordering.

  * pkg/api — opcode table (Create/Get/Sign/Transition/Verify/Audit
    + Ping). ZAPServer serves [4B BE length][2B LE opcode][JSON body]
    framing with per-conn pipelining + idle timeout. Tests: ping,
    end-to-end create→sent→sign→verify, unknown opcode error,
    bad-JSON error.

  * cmd/esignd — standalone daemon. `--zap :9650` by default.
    SIGINT/SIGTERM shutdown drains inflight conns before exit.

Test summary: 3 packages, 22 tests, all green.
2026-06-07 11:28:46 -07:00

52 lines
2.3 KiB
Go

// Copyright 2026 Lux Industries Inc. and the luxfi/esign authors.
// Licensed under the Apache License, Version 2.0 (see LICENSE).
// Package sign abstracts the per-algorithm signer + verifier surface that
// pkg/envelope and pkg/api dispatch through.
//
// Signature algorithms supported:
//
// Ed25519 — stdlib (crypto/ed25519). Compact, fast, widely interoperable.
// ML-DSA-65 — luxfi/keys. Post-quantum, NIST-standardized. Larger sigs (~3KB).
// FROST — luxfi/threshold. Schnorr-based M-of-N threshold signing.
// ECDSA-P256 — stdlib (crypto/ecdsa). Adobe / Foxit interop on PAdES envelopes.
// RSA-PSS — stdlib (crypto/rsa). Legacy DocuSign interop.
//
// Every implementation satisfies the Signer + Verifier interfaces below
// so pkg/envelope can dispatch by SignMethod without knowing the algorithm.
//
// Note: payloads sent to Sign/Verify are SHA-256 hashes of the canonical
// document bytes, NOT the bytes themselves. Pre-hashing keeps the Signer
// surface algorithm-agnostic and avoids re-hashing on the verifier side.
package sign
import "errors"
// Errors returned by Sign / Verify implementations.
var (
ErrBadSignature = errors.New("sign: signature does not verify")
ErrBadPubKey = errors.New("sign: public key is malformed for this algorithm")
ErrUnknownMethod = errors.New("sign: unknown signature method")
ErrPayloadTooLong = errors.New("sign: payload exceeds maximum length for algorithm")
)
// Signer produces a signature over a fixed-size payload (typically a
// 32-byte SHA-256 hash of the document). Implementations are responsible
// for any pre-pending of context strings their algorithm requires.
type Signer interface {
// Sign returns the algorithm-specific signature bytes over payload.
Sign(payload []byte) ([]byte, error)
// Public returns the canonical public-key bytes for this signer.
// Wire format is algorithm-specific (raw 32 bytes for Ed25519,
// COSE-style for ML-DSA-65, etc.).
Public() []byte
}
// Verifier validates a signature against (pubKey, payload). Implementations
// MUST NOT panic on malformed inputs — bad bytes are an error, not a crash.
type Verifier interface {
// Verify returns nil iff sig is a valid signature over payload under pubKey.
// Returns ErrBadSignature on mismatch and ErrBadPubKey on malformed key.
Verify(pubKey, payload, sig []byte) error
}