mirror of
https://github.com/luxfi/esign.git
synced 2026-10-30 16:58:18 +00:00
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.
52 lines
2.3 KiB
Go
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
|
|
}
|