proof

package
v0.12.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package proof parses, downloads, and generates Truestamp proof bundles in both JSON and CBOR wire formats. Proofs are the self-contained artefacts consumers receive from the API; this package handles only serialization and I/O — cryptographic verification lives in internal/verify.

Index

Constants

View Source
const (
	CodeNotAJSONObject                      = "not_a_json_object"
	CodeMissingTypeCode                     = "missing_type_code"
	CodeInvalidSubjectTypeCode              = "invalid_subject_type_code"
	CodeMissingBlock                        = "missing_block"
	CodeNoExternalCommitments               = "no_external_commitments"
	CodeInvalidExternalCommitmentEntry      = "invalid_external_commitment_entry"
	CodeUnexpectedSubjectFieldsForBlockLike = "unexpected_subject_fields_for_block_like"
	CodeMissingSubject                      = "missing_subject"
	CodeMissingInclusionProof               = "missing_inclusion_proof"

	// CodeInvalidSubjectData covers a CBOR `s.d` value that has no JSON
	// counterpart (E.3). E.23 names no identifier for this class; this one
	// is taken verbatim from the Elixir reference verifier
	// (truestamp-v2 lib/truestamp/proof/binary.ex) so both implementations
	// report the same word for the same rejection.
	CodeInvalidSubjectData = "invalid_subject_data"
)

Hard-rejection identifiers from the whitepaper's error taxonomy (E.23). A hard rejection aborts before any report exists (E.6) — independent verifiers are required to agree on this vocabulary so their outcomes are comparable, which is only possible if the identifier travels with the error rather than living in prose.

Variables

This section is empty.

Functions

func Download

func Download(rawURL string) ([]byte, error)

Download fetches a proof bundle from a URL using context.Background. Prefer DownloadCtx when a cancellable context is available.

func DownloadCtx added in v0.3.0

func DownloadCtx(ctx context.Context, rawURL string) ([]byte, error)

DownloadCtx is the context-aware variant of Download. Honours ctx for cancellation (e.g. Ctrl-C while a proof is streaming).

func FileSize

func FileSize(filename string) int64

FileSize returns the size of the file in bytes.

func FileSizeFromData

func FileSizeFromData(data []byte) int64

FileSizeFromData returns the byte length of proof data.

func Generate

func Generate(apiURL, team, id, subjectType, format string) ([]byte, error)

Generate calls GenerateCtx with context.Background.

func GenerateCtx added in v0.3.0

func GenerateCtx(ctx context.Context, apiURL, team, id, subjectType, format string) ([]byte, error)

GenerateCtx requests a proof bundle from the Truestamp API for the given subject ID. subjectType MUST be one of the six canonical values on the server's /proof/generate type enum (empty string omits the field, which the server rejects under the post-cutover schema — callers should always pass an explicit value):

item | entropy_nist | entropy_stellar | entropy_bitcoin | block | beacon

"auto" and bare "entropy" were removed when the server cut over to the strict enum alongside t=11 beacon support. Use the matching subtype.

format is "json" or "cbor". Returns raw bytes ready to write to a file (pretty JSON or decoded CBOR binary). ctx cancels the in-flight request. The credential is applied by the process-wide auth.Authorizer.

func HasCBORTag added in v0.12.0

func HasCBORTag(data []byte) bool

HasCBORTag reports whether data begins with the RFC 8949 self-describing tag 55799 (0xd9 0xd9 0xf7).

func IsCBORProof

func IsCBORProof(data []byte) bool

IsCBORProof reports whether data is a CBOR proof bundle. E.3 requires a verifier to accept CBOR both wrapped in the self-describing tag 55799 and as a bare map, so a bare CBOR map — major type 5, first byte 0xa0-0xbf, definite or indefinite length — counts too. Those bytes are UTF-8 continuation bytes and can never open a valid JSON document, so widening the check cannot steal input from the JSON path.

func RejectionCode added in v0.12.0

func RejectionCode(err error) string

RejectionCode returns the E.23 identifier carried by err, or "" when err is not a hard rejection. Callers use it to distinguish "this bundle was refused at the structural layer" from "verification produced a report".

Types

type Block

type Block struct {
	ID                string `json:"id"`
	PreviousBlockHash string `json:"ph"`
	MerkleRoot        string `json:"mr"`
	MetadataHash      string `json:"mh"`
	SigningKeyID      string `json:"kid"`
}

Block represents the single block in the proof.

type ExternalCommit

type ExternalCommit struct {
	Type    ptype.Code `json:"t"`
	Network string     `json:"net"` // Stellar: "testnet"|"public" ; Bitcoin: "regtest"|"testnet"|"mainnet"

	// Epoch Merkle proof (base64url compact binary)
	EpochProof string `json:"ep"`

	// Stellar fields
	TransactionHash string `json:"tx,omitempty"`
	MemoHash        string `json:"memo,omitempty"`
	Ledger          int    `json:"l,omitempty"`
	Timestamp       string `json:"ts,omitempty"`

	// Bitcoin fields
	OpReturn        string `json:"op,omitempty"`
	RawTxHex        string `json:"rtx,omitempty"`
	TxoutproofHex   string `json:"txp,omitempty"`
	BlockMerkleRoot string `json:"bmr,omitempty"`
	BlockHeight     int    `json:"h,omitempty"`
}

ExternalCommit represents a commitment entry in the proof bundle. Type is an integer code from ptype (CommitmentStellar=40, CommitmentBitcoin=41). Each commitment carries an epoch Merkle proof (ep) linking the block hash to the committed value (Stellar: memo, Bitcoin: OP_RETURN payload).

func (ExternalCommit) MarshalJSON added in v0.12.0

func (c ExternalCommit) MarshalJSON() ([]byte, error)

MarshalJSON emits a commitment entry, always carrying `ep` and the chain-specific epoch-root key (`memo` for t=40, `op` for t=41) even when empty. E.6 hard-rejects an entry missing either, so letting `omitempty` drop an empty value would make the CLI emit a bundle its own parser refuses to read back.

type IDType

type IDType string

IDType is the syntactic shape of a subject id. It is NOT the subject's semantic kind (item / entropy / block / beacon): /proof/generate requires an explicit `type` from the caller — there is no server-side auto detection (see cmd/download.go's id-shape smart default). The authoritative label for a bundle in hand is its own signed `t`, readable only after ParseBytes / ParseCBOR. Use DetectIDType for pre-flight validation and for sanity-checking positional args.

const (
	IDTypeULID   IDType = "ulid"   // 26-char Crockford base32 (items)
	IDTypeUUIDv7 IDType = "uuidv7" // UUIDv7, with or without hyphens (entropy / block / beacon)
)

func DetectIDType

func DetectIDType(id string) (IDType, error)

DetectIDType returns the syntactic shape of id. Returns an error for values that are neither a valid ULID nor a parseable UUID.

type ProofBundle

type ProofBundle struct {
	Version   int        `json:"v"`
	T         ptype.Code `json:"t"`
	Timestamp string     `json:"ts"`
	PublicKey string     `json:"pk"`
	Signature string     `json:"sig"`

	// Subject is nil for block-like subjects (t ∈ {10, 11}). For all other
	// subject types it is non-nil after a successful parse.
	Subject *Subject `json:"-"`

	Block       Block            `json:"-"`
	Commitments []ExternalCommit `json:"-"`

	// InclusionProof is "" for block-like subjects and non-empty otherwise.
	InclusionProof string `json:"-"` // base64url compact Merkle proof

	// RawData is the subject-data JSON preserved byte-for-byte for JCS.
	// Empty for block-like subjects.
	RawData json.RawMessage `json:"-"`
}

ProofBundle is the top-level compact Truestamp proof structure (bundle version `v` is 1). Normative reference: Appendix E of `truestamp-v2/whitepaper/whitepaper.typ`; the wire shape is also described in `truestamp-v2/kb/verification/proof-bundle-format.md`.

The top-level integer field `t` discriminates subject types:

10  block            (no Subject, no InclusionProof)
11  beacon           (no Subject, no InclusionProof — same shape as block)
20  item
30  entropy_nist
31  entropy_stellar
32  entropy_bitcoin

func Parse

func Parse(filename string) (*ProofBundle, error)

Parse reads and parses a proof JSON file, preserving raw JSON for JCS.

func ParseBytes

func ParseBytes(data []byte) (*ProofBundle, error)

ParseBytes parses a proof from raw bytes, dispatching to ParseCBOR for CBOR input and parsing JSON otherwise.

Only the hard rejections E.6 enumerates abort here; everything else is a step failure the report has to surface. In particular a missing or wrong `v`, a missing or malformed `pk` / `sig`, and missing or wrong-sized hash / kid fields all parse cleanly so the pipeline can grade them. Every abort returns a RejectionError carrying its E.23 identifier.

func ParseCBOR

func ParseCBOR(data []byte) (*ProofBundle, error)

ParseCBOR decodes a CBOR proof bundle into a ProofBundle. The output is structurally identical to what ParseBytes produces from JSON, and the two paths agree on the verdict for the same logical bundle: E.6's rejections are enforced from the same helpers, and every CBOR-only value-space class (E.3) is refused here rather than coerced into a JSON counterpart.

The two do not always agree on the *kind* of refusal. A duplicate `s.d` key is a hard rejection on this path, because RFC 8949 section 5.6 makes the document invalid CBOR, while the JSON path reaches it as a failing JCS step. Both refuse the bundle; only the stage differs.

func (*ProofBundle) IsBlockLike added in v0.6.0

func (b *ProofBundle) IsBlockLike() bool

IsBlockLike returns true if this bundle is either a block (t=10) or a beacon (t=11). Use this in verification-pipeline guards that skip subject / inclusion-proof / subject-hash-derivation steps — those are shape concerns and beacon proofs have the same shape as block proofs.

func (*ProofBundle) IsEntropy

func (b *ProofBundle) IsEntropy() bool

IsEntropy returns true if this bundle is an entropy subject (t in {30,31,32}).

func (*ProofBundle) IsItem added in v0.6.0

func (b *ProofBundle) IsItem() bool

IsItem returns true if this bundle is an item subject (t=20).

func (*ProofBundle) MarshalCBOR added in v0.5.0

func (b *ProofBundle) MarshalCBOR() ([]byte, error)

MarshalCBOR produces the canonical CBOR representation of the proof bundle. Byte-valued fields (`pk`, `sig`, hashes) are emitted as CBOR major-type-2 byte strings; identifier fields (ULID, UUIDv7, timestamps) and the E.3 text-string fields `rtx` / `txp` remain text. The subject data (`s.d`) is decoded back from its preserved raw JSON and encoded as a nested CBOR structure. `t` is emitted as a CBOR integer at the top level and per commitment entry.

`ip` and `ep` are emitted as byte strings even though E.3's table lists them as text: that table governs what a verifier MUST accept on decode, and byte strings are what the backend puts on the wire. The decoder accepts both forms.

Round-trip guarantee: `cbor → Parse → MarshalCBOR` is byte-stable for inputs that are themselves deterministically encoded. Non-deterministic source CBOR is normalized on the first round trip.

func (*ProofBundle) MarshalJSON

func (b *ProofBundle) MarshalJSON() ([]byte, error)

MarshalJSON produces the compact JSON wire format from a parsed ProofBundle. Subject and InclusionProof are omitted for block-like subjects (t ∈ {10, 11}). Used when sending a CBOR-decoded proof to the API as JSON.

type RejectionError added in v0.12.0

type RejectionError struct {
	Code   string
	Detail string
}

RejectionError is a structural hard rejection: the bundle is malformed in a way E.6 says MUST abort before any step runs, so no Report is produced. Code is the E.23 identifier; Detail is the human-facing explanation.

func (*RejectionError) Error added in v0.12.0

func (e *RejectionError) Error() string

type Subject

type Subject struct {
	ID           string          `json:"id"`
	Data         json.RawMessage `json:"d"`
	MetadataHash string          `json:"mh"`
	SigningKeyID string          `json:"kid"`
}

Subject represents the unified subject within a non-block proof bundle. For item proofs (T=20), Data contains the claims map. For entropy subjects (T in {30,31,32}), Data contains the entropy observation. The source is carried in the top-level ProofBundle.T field; no per- subject `src` discriminator is emitted.

Directories

Path Synopsis
Package ptype holds the frozen registry of proof type integer codes used by Truestamp proof bundles.
Package ptype holds the frozen registry of proof type integer codes used by Truestamp proof bundles.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL