From 109965fcb19b9880f9d8424cf1e6ab863a273e16 Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Tue, 3 Feb 2026 02:46:43 -0800 Subject: [PATCH 1/6] Add BCR-2026-004: Anchor Predicates Proposes Known Values for anchoring assertions to cryptographic event logs. Core registry codepoints 87-93 in XID Documents section. Seeking community review. Signed-off-by: Christopher Allen --- papers/bcr-2026-004-anchor-predicates.md | 389 +++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 papers/bcr-2026-004-anchor-predicates.md diff --git a/papers/bcr-2026-004-anchor-predicates.md b/papers/bcr-2026-004-anchor-predicates.md new file mode 100644 index 0000000..d000c78 --- /dev/null +++ b/papers/bcr-2026-004-anchor-predicates.md @@ -0,0 +1,389 @@ +# Anchor Predicates + +## BCR-2026-004 + +**© 2026 Blockchain Commons** + +Authors: Christopher Allen
+Date: February 2, 2026 + +--- + +## Abstract + +This document specifies Known Value predicates for anchoring assertions to cryptographic event logs in Gordian Envelopes. These predicates enable independent attestation that an assertion exists, providing verifiable proof of existence and ordering without implying consent or approval. + +These predicates are proposed for the **core registry** (codepoints 87-93), as they represent fundamental cryptographic infrastructure for envelopes. + +## Status: Core Registry Proposal + +This BCR proposes additions to the **Blockchain Commons Core Registry** (codepoints 0-99) as defined in [BCR-2023-002](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-002-known-value.md). + +### Placement Rationale + +The proposed codepoints (87-93) follow the XID Privileges range (70-86), which ends with `Revoke` (86). This placement is logical because: +- Anchoring is cryptographic infrastructure, like XID operations +- Both anchoring and revocation deal with assertion state management +- The 87-100 range is currently unassigned + +### Request for Community Review + +We invite feedback on: +- Whether these predicates belong in the core registry +- Whether the proposed codepoint assignments are appropriate +- Any conflicts with existing or planned predicates +- Suggested refinements to predicate definitions + +Please submit feedback via: +- [Gordian Developer Community Discussions](https://github.com/BlockchainCommons/Gordian-Developer-Community/discussions) +- Pull requests to this specification + +## Introduction + +### Problem Statement + +Assertions in Gordian Envelopes may need independent attestation that they exist at a particular point in time. This is distinct from: +- **Signing** — which implies consent or authorship +- **Witnessing** (human) — which implies observation of events + +Cryptographic event logs (as in Certificate Transparency, Key Transparency, and CEL) provide append-only structures where independent parties can attest to having observed an assertion, without implying approval. + +### Terminology Distinction + +The term "witness" is overloaded: +- **Fair Witness** (human attestation) — a neutral party observing and attesting to facts +- **Cryptographic witness** — an entity anchoring assertions to a log + +This BCR uses **anchor** terminology to avoid confusion with human witnessing concepts. + +### Solution + +This specification defines predicates for cryptographic log anchoring: + +| Predicate | Purpose | +|-----------|---------| +| `anchoredBy` | Who anchored the assertion | +| `anchors` | What assertion is anchored | +| `anchoredAt` | When it was anchored | +| `anchorHash` | Cryptographic binding | +| `anchorLog` | Which log contains the anchor | + +Optional extensions for multi-anchor scenarios: +| Predicate | Purpose | +|-----------|---------| +| `anchorQuorum` | Minimum anchors required | +| `anchorIndex` | Position in log | + +### Inference Source + +These predicates are derived from concepts in: +- [Cryptographic Event Logs (CEL)](https://digitalbazaar.github.io/cel-spec/) +- Certificate Transparency (RFC 6962) +- Key Transparency systems + +## Terminology + +**Anchor**: A cryptographic attestation that an assertion exists in a log, without implying consent or approval. + +**Anchor Assertion**: An envelope asserting that another assertion has been anchored to a log. + +**Event Log**: An append-only, cryptographically verifiable data structure (e.g., Merkle tree). + +**Checkpoint**: A signed summary of log state at a point in time. + +## Proposed Known Value Assignments + +All proposed codepoints are in the **Core Registry** range (0-99). + +### Anchor Predicates (87-93) + +--- + +#### 87: `anchoredBy` + +**Type**: property +**Definition**: Identifies the entity that anchored an assertion to a cryptographic event log. +**Domain**: Any assertion +**Range**: XID, DID, or URI identifying the anchoring entity +**Usage**: Declares which entity provided the anchor attestation. + +``` +{ + CID(my-assertion) [ + 'anchoredBy': XID(log-operator) + 'anchoredAt': 2026-02-02T12:00:00Z + ] +} +``` + +**Notes**: +- Anchoring is attestation of existence, not consent or approval +- Multiple `anchoredBy` assertions may exist for the same assertion (different anchors) + +--- + +#### 88: `anchors` + +**Type**: property +**Definition**: References the assertion that is being anchored. +**Domain**: Anchor assertion +**Range**: CID or URI of the anchored assertion +**Usage**: Establishes an explicit, verifiable link between an anchor assertion and the assertion it attests to. + +``` +{ + CID(anchor-assertion) [ + 'anchors': CID(original-assertion) + 'anchoredBy': XID(log-operator) + 'anchorHash': "sha256:abc123..." + ] +} +``` + +--- + +#### 89: `anchoredAt` + +**Type**: property +**Definition**: The time at which the assertion was anchored to the log. +**Domain**: Anchor assertion +**Range**: xsd:dateTime (ISO 8601) +**Usage**: Supports temporal ordering, auditability, and equivocation detection. + +**Notes**: +- This is when the anchor was created, not when the original assertion was created +- Use `date` (16) or `validFrom` (21) for the original assertion's timestamp + +--- + +#### 90: `anchorHash` + +**Type**: property +**Definition**: A cryptographic hash of the canonical form of the assertion being anchored. +**Domain**: Anchor assertion +**Range**: Multihash or hash string +**Usage**: Cryptographically binds the anchor to a specific assertion representation. + +``` +{ + CID(anchor-assertion) [ + 'anchors': CID(original-assertion) + 'anchorHash': "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ] +} +``` + +**Notes**: +- Enables verification that the anchored content hasn't changed +- Should use the canonical envelope hash + +--- + +#### 91: `anchorLog` + +**Type**: property +**Definition**: Identifies the cryptographic event log in which the assertion was anchored. +**Domain**: Anchor assertion +**Range**: URI identifying the log +**Usage**: Enables cross-log comparison and detection of inconsistent log views. + +``` +{ + CID(anchor-assertion) [ + 'anchors': CID(original-assertion) + 'anchorLog': "https://log.example.com/v1" + ] +} +``` + +--- + +#### 92: `anchorQuorum` + +**Type**: property +**Definition**: Specifies the minimum number of distinct anchors required for an assertion to satisfy anchoring requirements. +**Domain**: Any assertion +**Range**: Integer or policy expression +**Usage**: Expresses governance or trust thresholds independently of verification. + +``` +{ + CID(high-value-assertion) [ + 'anchorQuorum': 3 + ] +} +``` + +**Notes**: +- This is a policy declaration, not a verification mechanism +- Verification of quorum satisfaction is application-specific + +--- + +#### 93: `anchorIndex` + +**Type**: property +**Definition**: The index or position of the anchored assertion in the log. +**Domain**: Anchor assertion +**Range**: Integer +**Usage**: Supports detection of log equivocation and inconsistent ordering claims. + +``` +{ + CID(anchor-assertion) [ + 'anchors': CID(original-assertion) + 'anchorLog': "https://log.example.com/v1" + 'anchorIndex': 12345 + ] +} +``` + +--- + +## Usage Patterns + +### Basic Anchoring + +``` +{ + CID(anchor-assertion) [ + 'anchors': CID(original-document) + 'anchoredBy': XID(transparency-log) + 'anchoredAt': 2026-02-02T12:00:00Z + 'anchorHash': "sha256:..." + 'anchorLog': "https://log.example.com/v1" + ] +} +``` + +### Multiple Anchors (Quorum) + +``` +{ + CID(important-assertion) [ + 'anchorQuorum': 2 + ] +} + +// Anchor 1 +{ + CID(anchor-1) [ + 'anchors': CID(important-assertion) + 'anchoredBy': XID(log-operator-a) + ] +} + +// Anchor 2 +{ + CID(anchor-2) [ + 'anchors': CID(important-assertion) + 'anchoredBy': XID(log-operator-b) + ] +} +``` + +### Anchor with Revocation + +Using `supersedes` from BCR-2026-005 (General Assertions): + +``` +{ + CID(revocation-anchor) [ + 'anchors': CID(revoked-assertion) + 'supersedes': CID(original-anchor) + 'anchoredBy': XID(log-operator) + ] +} +``` + +## Relationship to Other Predicates + +### Core Registry + +| Codepoint | Predicate | Relationship | +|-----------|-----------|--------------| +| 21 | `validFrom` | Use for assertion validity, not anchor time | +| 22 | `validUntil` | Use for assertion expiry | +| 86 | `Revoke` | XID key revocation (different from assertion supersession) | + +### BCR-2026-005 (General Assertions) + +| Predicate | Usage with Anchors | +|-----------|-------------------| +| `supersedes` | Anchor revocation/updates | +| `revocationReason` | Why an anchor was superseded | + +## Security Considerations + +### Anchoring vs. Signing + +Anchoring attests to **existence**, not **approval**. An anchor assertion means "I observed this assertion in my log view" — it does not mean "I agree with this assertion" or "I authorize this assertion." + +### Log Trust + +Relying parties must evaluate: +- Whether they trust the log operator (`anchoredBy`) +- Whether the log itself is trustworthy (`anchorLog`) +- Whether sufficient anchors exist (`anchorQuorum`) + +### Equivocation Detection + +The `anchorIndex` predicate supports detection of log equivocation — where a log operator presents different views to different parties. Cross-log comparison using `anchorLog` and `anchorIndex` can reveal inconsistencies. + +### Hash Binding + +The `anchorHash` provides cryptographic binding between the anchor and the anchored content. Verifiers should confirm that the hash matches the canonical form of the referenced assertion. + +## Open Questions + +### Relationship to Provenance Marks + +[BCR-2025-001: Provenance Marks](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2025-001-provenance-mark.md) provides a powerful mechanism for **self-sovereign, permissionless provenance** through forward-commit chains. Provenance Marks: + +- Require no external infrastructure — they are self-proving +- Enable permissionless operation — no log operators needed +- Use forward commits to establish temporal ordering +- Create cryptographic chains within a document series + +Anchor predicates address a **different use case**: external attestation by independent parties. They are useful when: + +- Third-party attestation is required (regulatory, compliance) +- Cross-organization verification is needed +- Independent witnesses add trust beyond self-attestation +- Integration with existing transparency log infrastructure is desired + +| Aspect | Provenance Marks | Anchor Predicates | +|--------|------------------|-------------------| +| Infrastructure | None required (self-sovereign) | Requires log operators | +| Permission model | Permissionless | Depends on log access | +| Proof type | Forward-commit chain | External attestation | +| Trust model | Self-proving sequence | Independent witnesses | +| Primary use | Document series integrity | Cross-party attestation | + +**These mechanisms are independent**: Anchor predicates can be used without Provenance Marks, and Provenance Marks work without external anchoring. They may also be **complementary** — external anchors could potentially strengthen Provenance Mark chains for high-assurance scenarios. + +**Questions for community review:** + +1. When both mechanisms are used together, what is the recommended pattern? +2. Should external anchors reference Provenance Mark chain hashes, or individual assertions? +3. Are there use cases where one mechanism clearly subsumes the other? + +We invite feedback on how these specifications should interoperate. See also the [Provenance Mark developer documentation](https://developer.blockchaincommons.com/provemark/). + +## References + +- [BCR-2023-002: Known Value Registry](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-002-known-value.md) +- [Cryptographic Event Logs (CEL)](https://github.com/w3c-ccg/cel-spec) +- [Certificate Transparency (RFC 6962)](https://datatracker.ietf.org/doc/html/rfc6962) +- [Gordian Envelope Specification](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-001-envelope.md) +- [BCR-2025-001: Provenance Marks](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2025-001-provenance-mark.md) + +## Related BCRs + +- **BCR-2026-005: General Assertion Predicates** — `supersedes` for anchor updates +- **BCR-2026-007: Principal Authority Predicates** — Authority relationships + +--- + +*BCR-2026-004: Anchor Predicates* +*Draft - February 2, 2026* From 2d278beab326fe9cde02f5af94f7fb3166583308 Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Wed, 4 Feb 2026 00:34:42 -0800 Subject: [PATCH 2/6] Update BCR-2026-004 per reviewer feedback --- papers/bcr-2026-004-anchor-predicates.md | 95 +++++++++++++++--------- 1 file changed, 60 insertions(+), 35 deletions(-) diff --git a/papers/bcr-2026-004-anchor-predicates.md b/papers/bcr-2026-004-anchor-predicates.md index d000c78..97da412 100644 --- a/papers/bcr-2026-004-anchor-predicates.md +++ b/papers/bcr-2026-004-anchor-predicates.md @@ -46,7 +46,27 @@ Assertions in Gordian Envelopes may need independent attestation that they exist - **Signing** — which implies consent or authorship - **Witnessing** (human) — which implies observation of events -Cryptographic event logs (as in Certificate Transparency, Key Transparency, and CEL) provide append-only structures where independent parties can attest to having observed an assertion, without implying approval. +Cryptographic event logs (as in Certificate Transparency, Key Transparency, and CEL) provide **append-only** structures where independent parties can attest to having observed an assertion, without implying approval. + +### Why Anchoring Matters + +Anchoring provides **proof of existence and ordering** without requiring trust in the asserter: + +1. **Certificate Transparency** — Public logs prove certificates existed at a point in time, enabling detection of misissued certificates even after the fact +2. **Key Transparency** — Append-only logs of key bindings prevent silent key replacement attacks +3. **Software Transparency** — Binary hashes in logs prove what code was distributed, enabling detection of supply chain attacks + +In all cases, the value comes from the log's **append-only, publicly auditable nature**. Once an assertion is anchored, it cannot be removed or altered — the log provides permanent evidence that the assertion existed. + +### Use Cases + +**Timestamp Authority**: An independent service anchors assertions to prove they existed before a certain time — useful for intellectual property, contract precedence, or regulatory compliance. + +**Multi-Party Attestation**: Multiple log operators anchor the same assertion (quorum), providing resilience against any single operator being compromised or unavailable. + +**Audit Trails**: Anchoring creates tamper-evident records of assertions for compliance, legal discovery, or forensic analysis. + +**Revocation Detection**: When combined with `supersedes` (BCR-2026-005), anchoring enables detection of attempts to silently replace assertions — the original anchor remains in the log even after supersession. ### Terminology Distinction @@ -65,7 +85,7 @@ This specification defines predicates for cryptographic log anchoring: | `anchoredBy` | Who anchored the assertion | | `anchors` | What assertion is anchored | | `anchoredAt` | When it was anchored | -| `anchorHash` | Cryptographic binding | +| `anchorDigest` | Cryptographic binding | | `anchorLog` | Which log contains the anchor | Optional extensions for multi-anchor scenarios: @@ -74,13 +94,15 @@ Optional extensions for multi-anchor scenarios: | `anchorQuorum` | Minimum anchors required | | `anchorIndex` | Position in log | -### Inference Source +### Conceptual Foundation -These predicates are derived from concepts in: +These predicates are **Envelope-native vocabulary** for expressing anchoring relationships within Gordian Envelopes, which uses concepts inspired by: - [Cryptographic Event Logs (CEL)](https://digitalbazaar.github.io/cel-spec/) - Certificate Transparency (RFC 6962) - Key Transparency systems +> **Note**: This is not a bridge format or interoperability specification for CT/CEL. Round-trip conversion to/from external log formats would require a separate specification. + ## Terminology **Anchor**: A cryptographic attestation that an assertion exists in a log, without implying consent or approval. @@ -109,7 +131,7 @@ All proposed codepoints are in the **Core Registry** range (0-99). ``` { - CID(my-assertion) [ + Digest(my-assertion) [ 'anchoredBy': XID(log-operator) 'anchoredAt': 2026-02-02T12:00:00Z ] @@ -127,15 +149,15 @@ All proposed codepoints are in the **Core Registry** range (0-99). **Type**: property **Definition**: References the assertion that is being anchored. **Domain**: Anchor assertion -**Range**: CID or URI of the anchored assertion +**Range**: Digest or URI of the anchored assertion **Usage**: Establishes an explicit, verifiable link between an anchor assertion and the assertion it attests to. ``` { - CID(anchor-assertion) [ - 'anchors': CID(original-assertion) + Digest(anchor-assertion) [ + 'anchors': Digest(original-assertion) 'anchoredBy': XID(log-operator) - 'anchorHash': "sha256:abc123..." + 'anchorDigest': Digest(abc123...) ] } ``` @@ -156,26 +178,27 @@ All proposed codepoints are in the **Core Registry** range (0-99). --- -#### 90: `anchorHash` +#### 90: `anchorDigest` **Type**: property -**Definition**: A cryptographic hash of the canonical form of the assertion being anchored. +**Definition**: A cryptographic digest of the canonical form of the assertion being anchored. **Domain**: Anchor assertion -**Range**: Multihash or hash string +**Range**: Digest **Usage**: Cryptographically binds the anchor to a specific assertion representation. ``` { - CID(anchor-assertion) [ - 'anchors': CID(original-assertion) - 'anchorHash': "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + Digest(anchor-assertion) [ + 'anchors': Digest(original-assertion) + 'anchorDigest': Digest(e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855) ] } ``` **Notes**: - Enables verification that the anchored content hasn't changed -- Should use the canonical envelope hash +- Uses the native Envelope `Digest` type for type safety +- Should use the canonical envelope digest --- @@ -189,8 +212,8 @@ All proposed codepoints are in the **Core Registry** range (0-99). ``` { - CID(anchor-assertion) [ - 'anchors': CID(original-assertion) + Digest(anchor-assertion) [ + 'anchors': Digest(original-assertion) 'anchorLog': "https://log.example.com/v1" ] } @@ -208,7 +231,7 @@ All proposed codepoints are in the **Core Registry** range (0-99). ``` { - CID(high-value-assertion) [ + Digest(high-value-assertion) [ 'anchorQuorum': 3 ] } @@ -230,8 +253,8 @@ All proposed codepoints are in the **Core Registry** range (0-99). ``` { - CID(anchor-assertion) [ - 'anchors': CID(original-assertion) + Digest(anchor-assertion) [ + 'anchors': Digest(original-assertion) 'anchorLog': "https://log.example.com/v1" 'anchorIndex': 12345 ] @@ -246,11 +269,11 @@ All proposed codepoints are in the **Core Registry** range (0-99). ``` { - CID(anchor-assertion) [ - 'anchors': CID(original-document) + Digest(anchor-assertion) [ + 'anchors': Digest(original-document) 'anchoredBy': XID(transparency-log) 'anchoredAt': 2026-02-02T12:00:00Z - 'anchorHash': "sha256:..." + 'anchorDigest': Digest(...) 'anchorLog': "https://log.example.com/v1" ] } @@ -260,42 +283,44 @@ All proposed codepoints are in the **Core Registry** range (0-99). ``` { - CID(important-assertion) [ + Digest(important-assertion) [ 'anchorQuorum': 2 ] } // Anchor 1 { - CID(anchor-1) [ - 'anchors': CID(important-assertion) + Digest(anchor-1) [ + 'anchors': Digest(important-assertion) 'anchoredBy': XID(log-operator-a) ] } // Anchor 2 { - CID(anchor-2) [ - 'anchors': CID(important-assertion) + Digest(anchor-2) [ + 'anchors': Digest(important-assertion) 'anchoredBy': XID(log-operator-b) ] } ``` -### Anchor with Revocation +### Anchor with Supersession -Using `supersedes` from BCR-2026-005 (General Assertions): +Using `supersedes` from BCR-2026-005 (General Assertions) to indicate an assertion has been replaced: ``` { - CID(revocation-anchor) [ - 'anchors': CID(revoked-assertion) - 'supersedes': CID(original-anchor) + Digest(supersession-anchor) [ + 'anchors': Digest(superseding-assertion) + 'supersedes': Digest(original-anchor) 'anchoredBy': XID(log-operator) ] } ``` +> **Important**: This creates a **new** anchor entry in the log. The original anchor remains permanently in the append-only log — it is not modified or deleted. The `supersedes` predicate creates a forward reference, allowing verifiers to discover that a newer version exists. This is how Certificate Transparency handles certificate revocation: the original certificate's log entry persists, but a newer entry supersedes it. + ## Relationship to Other Predicates ### Core Registry @@ -332,7 +357,7 @@ The `anchorIndex` predicate supports detection of log equivocation — where a l ### Hash Binding -The `anchorHash` provides cryptographic binding between the anchor and the anchored content. Verifiers should confirm that the hash matches the canonical form of the referenced assertion. +The `anchorDigest` provides cryptographic binding between the anchor and the anchored content. Verifiers should confirm that the hash matches the canonical form of the referenced assertion. ## Open Questions From 3e1f139d5c9d57b58aa0086c4f5e0a4d09352bb4 Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Wed, 4 Feb 2026 00:51:26 -0800 Subject: [PATCH 3/6] Remove unnecessary envelope wrapping from unsigned examples --- papers/bcr-2026-004-anchor-predicates.md | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/papers/bcr-2026-004-anchor-predicates.md b/papers/bcr-2026-004-anchor-predicates.md index 97da412..26ef246 100644 --- a/papers/bcr-2026-004-anchor-predicates.md +++ b/papers/bcr-2026-004-anchor-predicates.md @@ -130,12 +130,10 @@ All proposed codepoints are in the **Core Registry** range (0-99). **Usage**: Declares which entity provided the anchor attestation. ``` -{ Digest(my-assertion) [ 'anchoredBy': XID(log-operator) 'anchoredAt': 2026-02-02T12:00:00Z ] -} ``` **Notes**: @@ -153,13 +151,11 @@ All proposed codepoints are in the **Core Registry** range (0-99). **Usage**: Establishes an explicit, verifiable link between an anchor assertion and the assertion it attests to. ``` -{ Digest(anchor-assertion) [ 'anchors': Digest(original-assertion) 'anchoredBy': XID(log-operator) 'anchorDigest': Digest(abc123...) ] -} ``` --- @@ -187,12 +183,10 @@ All proposed codepoints are in the **Core Registry** range (0-99). **Usage**: Cryptographically binds the anchor to a specific assertion representation. ``` -{ Digest(anchor-assertion) [ 'anchors': Digest(original-assertion) 'anchorDigest': Digest(e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855) ] -} ``` **Notes**: @@ -211,12 +205,10 @@ All proposed codepoints are in the **Core Registry** range (0-99). **Usage**: Enables cross-log comparison and detection of inconsistent log views. ``` -{ Digest(anchor-assertion) [ 'anchors': Digest(original-assertion) 'anchorLog': "https://log.example.com/v1" ] -} ``` --- @@ -230,11 +222,9 @@ All proposed codepoints are in the **Core Registry** range (0-99). **Usage**: Expresses governance or trust thresholds independently of verification. ``` -{ Digest(high-value-assertion) [ 'anchorQuorum': 3 ] -} ``` **Notes**: @@ -252,13 +242,11 @@ All proposed codepoints are in the **Core Registry** range (0-99). **Usage**: Supports detection of log equivocation and inconsistent ordering claims. ``` -{ Digest(anchor-assertion) [ 'anchors': Digest(original-assertion) 'anchorLog': "https://log.example.com/v1" 'anchorIndex': 12345 ] -} ``` --- @@ -268,7 +256,6 @@ All proposed codepoints are in the **Core Registry** range (0-99). ### Basic Anchoring ``` -{ Digest(anchor-assertion) [ 'anchors': Digest(original-document) 'anchoredBy': XID(transparency-log) @@ -276,33 +263,26 @@ All proposed codepoints are in the **Core Registry** range (0-99). 'anchorDigest': Digest(...) 'anchorLog': "https://log.example.com/v1" ] -} ``` ### Multiple Anchors (Quorum) ``` -{ Digest(important-assertion) [ 'anchorQuorum': 2 ] -} // Anchor 1 -{ Digest(anchor-1) [ 'anchors': Digest(important-assertion) 'anchoredBy': XID(log-operator-a) ] -} // Anchor 2 -{ Digest(anchor-2) [ 'anchors': Digest(important-assertion) 'anchoredBy': XID(log-operator-b) ] -} ``` ### Anchor with Supersession @@ -310,13 +290,11 @@ All proposed codepoints are in the **Core Registry** range (0-99). Using `supersedes` from BCR-2026-005 (General Assertions) to indicate an assertion has been replaced: ``` -{ Digest(supersession-anchor) [ 'anchors': Digest(superseding-assertion) 'supersedes': Digest(original-anchor) 'anchoredBy': XID(log-operator) ] -} ``` > **Important**: This creates a **new** anchor entry in the log. The original anchor remains permanently in the append-only log — it is not modified or deleted. The `supersedes` predicate creates a forward reference, allowing verifiers to discover that a newer version exists. This is how Certificate Transparency handles certificate revocation: the original certificate's log entry persists, but a newer entry supersedes it. From fcde09101ee260c8bf9590f477ac9ad4a777727a Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Wed, 4 Feb 2026 01:12:22 -0800 Subject: [PATCH 4/6] Remove supersedes references (moved to structural predicates BCR) --- papers/bcr-2026-004-anchor-predicates.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/papers/bcr-2026-004-anchor-predicates.md b/papers/bcr-2026-004-anchor-predicates.md index 26ef246..4e6995a 100644 --- a/papers/bcr-2026-004-anchor-predicates.md +++ b/papers/bcr-2026-004-anchor-predicates.md @@ -66,7 +66,7 @@ In all cases, the value comes from the log's **append-only, publicly auditable n **Audit Trails**: Anchoring creates tamper-evident records of assertions for compliance, legal discovery, or forensic analysis. -**Revocation Detection**: When combined with `supersedes` (BCR-2026-005), anchoring enables detection of attempts to silently replace assertions — the original anchor remains in the log even after supersession. +**Revocation Detection**: Anchoring enables detection of attempts to silently replace assertions — the original anchor remains in the log even after revocation or update. ### Terminology Distinction @@ -285,19 +285,18 @@ All proposed codepoints are in the **Core Registry** range (0-99). ] ``` -### Anchor with Supersession +### Anchor Updates -Using `supersedes` from BCR-2026-005 (General Assertions) to indicate an assertion has been replaced: +When an assertion is revoked or updated, a new anchor entry is created: ``` - Digest(supersession-anchor) [ - 'anchors': Digest(superseding-assertion) - 'supersedes': Digest(original-anchor) - 'anchoredBy': XID(log-operator) - ] +Digest(update-anchor) [ + 'anchors': Digest(updated-assertion) + 'anchoredBy': XID(log-operator) +] ``` -> **Important**: This creates a **new** anchor entry in the log. The original anchor remains permanently in the append-only log — it is not modified or deleted. The `supersedes` predicate creates a forward reference, allowing verifiers to discover that a newer version exists. This is how Certificate Transparency handles certificate revocation: the original certificate's log entry persists, but a newer entry supersedes it. +> **Important**: This creates a **new** anchor entry in the log. The original anchor remains permanently in the append-only log — it is not modified or deleted. This is how Certificate Transparency handles certificate revocation: the original certificate's log entry persists, but a newer entry indicates the update. ## Relationship to Other Predicates @@ -313,8 +312,7 @@ Using `supersedes` from BCR-2026-005 (General Assertions) to indicate an asserti | Predicate | Usage with Anchors | |-----------|-------------------| -| `supersedes` | Anchor revocation/updates | -| `revocationReason` | Why an anchor was superseded | +| `revocationReason` | Why an anchor was revoked | ## Security Considerations @@ -383,7 +381,7 @@ We invite feedback on how these specifications should interoperate. See also the ## Related BCRs -- **BCR-2026-005: General Assertion Predicates** — `supersedes` for anchor updates +- **BCR-2026-005: General Assertion Predicates** — `revocationReason` for anchor revocations - **BCR-2026-007: Principal Authority Predicates** — Authority relationships --- From bbde93f92cbf015c7019b4c32e2fb14464001bd9 Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Wed, 4 Feb 2026 13:29:56 -0800 Subject: [PATCH 5/6] =?UTF-8?q?Renumber:=20BCR-2026-004=20=E2=86=92=20BCR-?= =?UTF-8?q?2026-011=20Anchor=20Predicates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moved to end of sequence as this BCR requires community review for core registry codepoints (87-93). File renamed: bcr-2026-004-anchor-predicates.md → bcr-2026-011-anchor-predicates.md Cross-references updated to reflect new BCR numbering across suite. Signed-off-by: Christopher Allen --- ...predicates.md => bcr-2026-011-anchor-predicates.md} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename papers/{bcr-2026-004-anchor-predicates.md => bcr-2026-011-anchor-predicates.md} (98%) diff --git a/papers/bcr-2026-004-anchor-predicates.md b/papers/bcr-2026-011-anchor-predicates.md similarity index 98% rename from papers/bcr-2026-004-anchor-predicates.md rename to papers/bcr-2026-011-anchor-predicates.md index 4e6995a..6262c00 100644 --- a/papers/bcr-2026-004-anchor-predicates.md +++ b/papers/bcr-2026-011-anchor-predicates.md @@ -1,6 +1,6 @@ # Anchor Predicates -## BCR-2026-004 +## BCR-2026-011 **© 2026 Blockchain Commons** @@ -97,11 +97,11 @@ Optional extensions for multi-anchor scenarios: ### Conceptual Foundation These predicates are **Envelope-native vocabulary** for expressing anchoring relationships within Gordian Envelopes, which uses concepts inspired by: -- [Cryptographic Event Logs (CEL)](https://digitalbazaar.github.io/cel-spec/) - Certificate Transparency (RFC 6962) - Key Transparency systems +- [Cryptographic Event Logs (CEL)](https://digitalbazaar.github.io/cel-spec/) -> **Note**: This is not a bridge format or interoperability specification for CT/CEL. Round-trip conversion to/from external log formats would require a separate specification. +> **Note**: This is not a bridge format or interoperability specification for CT/KT/CEL. Round-trip conversion to/from external log formats would require a separate specification. ## Terminology @@ -382,9 +382,9 @@ We invite feedback on how these specifications should interoperate. See also the ## Related BCRs - **BCR-2026-005: General Assertion Predicates** — `revocationReason` for anchor revocations -- **BCR-2026-007: Principal Authority Predicates** — Authority relationships +- **BCR-2026-006: Principal Authority Predicates** — Authority relationships --- -*BCR-2026-004: Anchor Predicates* +*BCR-2026-011: Anchor Predicates* *Draft - February 2, 2026* From ffeda7161d931011cccaf1249dd058e12f565324 Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Thu, 5 Feb 2026 10:21:11 -0800 Subject: [PATCH 6/6] Rename to BCR-2026-XXX temporary designation Per Wolf's recommendation: use temporary letter designations. Actual BCR numbers will be assigned at merge time. Updated all internal cross-references to XXX format. Signed-off-by: Christopher Allen --- .../bcr-2026-004-signing-event-assertions.md | 288 ++++++++++++++++++ ...s.md => bcr-2026-xxx-anchor-predicates.md} | 10 +- 2 files changed, 293 insertions(+), 5 deletions(-) create mode 100644 papers/bcr-2026-004-signing-event-assertions.md rename papers/{bcr-2026-011-anchor-predicates.md => bcr-2026-xxx-anchor-predicates.md} (98%) diff --git a/papers/bcr-2026-004-signing-event-assertions.md b/papers/bcr-2026-004-signing-event-assertions.md new file mode 100644 index 0000000..3b5496e --- /dev/null +++ b/papers/bcr-2026-004-signing-event-assertions.md @@ -0,0 +1,288 @@ +# Signing Event Assertions + +## BCR-2026-004 + +**© 2026 Blockchain Commons** + +Authors: Christopher Allen
+Date: February 4, 2026 + +--- + +## Abstract + +A cryptographic signature proves a key signed content. It does not prove who holds the key, when signing occurred, or what the signature means. This BCR defines predicates for signers to attest these facts, bound to their signatures using the pattern from BCR-2024-009. + +## Status: Draft + +## Introduction + +### What Signatures Prove + +A signature proves exactly one thing: + +> **The private key for a specific public key produced this signature over this content.** + +A signature does not prove who holds the key, whether the key was compromised or delegated, when signing occurred, why it happened, or that the signer agreed to anything. + +``` +{ + Digest(contract) +} 'signed': Signature +``` + +This proves the key signed. It does not prove Alice controls that key, that she is CEO, or that she signed for Acme Corp. + +### The Problem + +Alice signing personally and Alice signing as CEO for Acme Corp produce identical signatures. The difference is what Alice attests about her signing act. To express this in Gordian Envelope: + +1. Predicates linking signatures to identity (XIDs) +2. Predicates expressing representation +3. A pattern binding assertions to signatures + +### Solution + +This BCR defines: + +- `signer` (300) — links signature to signer's identity +- `signedOnBehalfOf` (301) — identifies who the signer represents +- References `xades:ClaimedRole` and `xades:CommitmentType` from XAdES + +Two patterns bind assertions to signatures: +- **Signature-with-assertions** — signer's own assertions (primary) +- **Wrapped signing** — third-party assertions + +## Binding Assertions to Signatures + +### The Problem + +Assertions alongside a signature aren't cryptographically bound: + +``` +// WRONG: Anyone could add these assertions +{ + Digest(contract) +} [ + 'signed': Signature + 'signer': XID(alice) +] +``` + +### Pattern 1: Signature-with-Assertions + +For a signer's own assertions, use the pattern from BCR-2024-009: make the Signature the subject, add assertions, wrap, sign. + +``` +{ + Digest(contract) +} [ + 'signed': { + Signature [ + 'signer': XID(alice) + 'signedOnBehalfOf': XID(acme-corp) + 'xades:ClaimedRole': "CEO" + 'xades:CommitmentType': "approval" + ] + } ['signed': Signature] +] +``` + +The inner signature covers content. The outer signature binds assertions to the inner signature. Both must verify against the same key. + +### Pattern 2: Wrapped Signing + +For third-party assertions (timestamps, notarization), wrap the signed content, add assertions, sign: + +``` +{ + { + Digest(contract) + } [ + 'signed': { + Signature ['signer': XID(alice)] + } ['signed': Signature] + ] + [ + 'anchoredAt': 2026-02-04T12:00:00Z + 'anchoredBy': XID(timestamp-authority) + ] +} [ + 'signed': { + Signature [ + 'signer': XID(timestamp-authority) + 'xades:CommitmentType': "timestamp" + ] + } ['signed': Signature] +] +``` + +The third party's signature binds their assertions about the already-signed content. + +### When to Use Each + +| Pattern | Who Asserts | About What | +|---------|-------------|------------| +| Signature-with-assertions | Signer | Their signing act | +| Wrapped signing | Third party | Signed content | + +Examples of wrapped signing: timestamp authorities, notaries, witnesses, endorsers. + +### Dates vs Timestamps + +A date in signing assertions is a claim, not proof. For provable timestamps, a third party must counter-sign — they couldn't sign content that didn't exist. + +## Multi-Party Signatures + +### Parallel Signatures + +Multiple parties independently signing the same content: + +``` +{ + Digest(contract) +} [ + 'signed': { + Signature [ + 'signer': XID(alice) + 'xades:CommitmentType': "approval" + ] + } ['signed': Signature] + 'signed': { + Signature [ + 'signer': XID(bob) + 'xades:CommitmentType': "approval" + ] + } ['signed': Signature] +] +``` + +### Counter-Signatures + +A party signing over another's signed content: + +``` +{ + { + Digest(contract) + } [ + 'signed': { + Signature ['signer': XID(alice)] + } ['signed': Signature] + ] +} [ + 'signed': { + Signature [ + 'signer': XID(bob) + 'xades:CommitmentType': "witness" + ] + } ['signed': Signature] +] +``` + +Bob's signature covers Alice's complete signed envelope. + +## Terminology + +**Assertion**: Envelope term for a predicate-object pair. **Attestation**: The act of declaring facts. Signers *attest*; attestations are expressed as *assertions*. + +**Signing Event**: A key producing a signature over content. + +**Signing Event Assertions**: Assertions on a Signature subject — who signed, representing whom, in what capacity, for what purpose. + +## Known Value Assignments + +Proposed for the Reserved range (256-999) per BCR-2023-002. + +### 300: `signer` + +Links a signature to a document identifying the signer. + +``` +Signature [ + 'signer': XID(alice) +] +``` + +A signature proves a key signed; `signer` links to identity. Required because some schemes (EdDSA, BBS+, Longfellow) don't embed or allow recovery of the public key. + +Within the Gordian ecosystem (XIDs, Clubs, GSTP), references an XID or Club. Gordian Envelope also supports URIs and DIDs. + +### 301: `signedOnBehalfOf` + +Optional. Identifies who the signer represents. + +``` +Signature [ + 'signer': XID(alice) + 'signedOnBehalfOf': XID(acme-corp) +] +``` + +Only include when acting for another party. This is a claim — verification requires checking delegation authority (see BCR-2026-006). + +## Referenced Standards + +### xades:ClaimedRole + +From ETSI TS 101 903. The capacity in which the signer acts. Self-asserted. + +``` +Signature [ + 'signer': XID(alice) + 'xades:ClaimedRole': "CEO" +] +``` + +### xades:CommitmentType + +From ETSI TS 101 903. The purpose of the signature. + +``` +Signature [ + 'signer': XID(alice) + 'xades:CommitmentType': "approval" +] +``` + +Common values: approval, acknowledgment, witness, receipt, origin. + +## Security Considerations + +Signing event assertions are claims by the signer. Relying parties must verify both signatures, confirm they use the same key, resolve the XID, and evaluate plausibility. + +For signature-with-assertions, different keys indicate tampering. For wrapped signing, different keys are expected. + +When `signer` is elided, signatures remain valid but identity is hidden. + +## References + +- [BCR-2023-002: Known Value Registry](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-002-known-value.md) +- [BCR-2024-009: Signatures with Metadata](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-009-signature-metadata.md) +- [ETSI TS 101 903: XAdES](https://www.etsi.org/deliver/etsi_ts/101900_101999/101903/01.04.02_60/ts_101903v010402p.pdf) +- [Gordian Envelope Specification](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-003-envelope.md) +- [BBS Signature Scheme](https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html) +- [Longfellow ZK Scheme](https://datatracker.ietf.org/doc/html/draft-google-cfrg-libzk-01) + +## Related BCRs + +- BCR-2026-005: General Assertion Predicates +- BCR-2026-006: Principal Authority Predicates + +--- + +## Appendix A: XAdES Commitment Type OIDs + +| Commitment Type | OID | +|-----------------|-----| +| Proof of origin | 1.2.840.113549.1.9.16.6.1 | +| Proof of receipt | 1.2.840.113549.1.9.16.6.2 | +| Proof of delivery | 1.2.840.113549.1.9.16.6.3 | +| Proof of sender | 1.2.840.113549.1.9.16.6.4 | +| Proof of approval | 1.2.840.113549.1.9.16.6.5 | +| Proof of creation | 1.2.840.113549.1.9.16.6.6 | + +--- + +*BCR-2026-004: Signing Event Assertions* +*Draft - February 4, 2026* diff --git a/papers/bcr-2026-011-anchor-predicates.md b/papers/bcr-2026-xxx-anchor-predicates.md similarity index 98% rename from papers/bcr-2026-011-anchor-predicates.md rename to papers/bcr-2026-xxx-anchor-predicates.md index 6262c00..c5f6fba 100644 --- a/papers/bcr-2026-011-anchor-predicates.md +++ b/papers/bcr-2026-xxx-anchor-predicates.md @@ -1,6 +1,6 @@ # Anchor Predicates -## BCR-2026-011 +## BCR-2026-XXX **© 2026 Blockchain Commons** @@ -308,7 +308,7 @@ Digest(update-anchor) [ | 22 | `validUntil` | Use for assertion expiry | | 86 | `Revoke` | XID key revocation (different from assertion supersession) | -### BCR-2026-005 (General Assertions) +### BCR-2026-XXX (General Assertions) | Predicate | Usage with Anchors | |-----------|-------------------| @@ -381,10 +381,10 @@ We invite feedback on how these specifications should interoperate. See also the ## Related BCRs -- **BCR-2026-005: General Assertion Predicates** — `revocationReason` for anchor revocations -- **BCR-2026-006: Principal Authority Predicates** — Authority relationships +- **BCR-2026-XXX: General Assertion Predicates** — `revocationReason` for anchor revocations +- **BCR-2026-XXX: Principal Authority Predicates** — Authority relationships --- -*BCR-2026-011: Anchor Predicates* +*BCR-2026-XXX: Anchor Predicates* *Draft - February 2, 2026*