├── .gitignore ├── scope.md ├── license.md ├── README.md ├── notices.md ├── specifications ├── README.md ├── nonce.md ├── wacc.md ├── multisig.md ├── varuint.md ├── vlad.md ├── multikey.md └── provenance-logs.md ├── contributing.md ├── code_of_conduct.md ├── governance.md └── community_specification_license.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /scope.md: -------------------------------------------------------------------------------- 1 | # Scope 2 | 3 | This repository contains the specifications for... 4 | 5 | * Provenance log 6 | * Web assembly cryptographic construct VM API (WACC) 7 | * Multicodec data objects 8 | * Multikey 9 | * Multisig 10 | * Nonce 11 | * Very long-lived addresses (vlads) 12 | * Vlad Mapping Service (VMS) 13 | * Threshold signature messages 14 | 15 | Any changes of Scope are not retroactive. 16 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | # Licenses 2 | 3 | ## Specification License 4 | 5 | Specifications in the repository are subject to the **Community Specification 6 | License 1.0** available at [https://github.com/CommunitySpecification/1.0][0]. 7 | 8 | ## Source Code License 9 | 10 | If source code is included in this repository, or for sample or reference code 11 | included in the specification itself, that code is subject to the Apache 12 | License 2.0 unless otherwise designated. In the case of any conflict or 13 | confusion within this specification repository between the Community 14 | Specification License and the Apache License 2.0 or other designated license, 15 | the terms of the Community Specification License shall apply. 16 | 17 | If source code is included in this repository, or for sample or reference code 18 | included in the specification itself, that code is subject to the Apache 19 | License 2.0 unless otherwise marked. 20 | 21 | In the case of any conflict or confusion within this specification repository 22 | between the Community Specification License and the designated source code 23 | license, the terms of the Community Specification License shall apply. 24 | 25 | [0]: https://github.com/CommunitySpecification/1.0 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Community Specification 1.0](https://img.shields.io/badge/Community_Specification-1.0-blue?style=flat-square)][0] 2 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][1] 3 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][2] 4 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][3] 5 | 6 | # Provenance Specifications 7 | 8 | This repository contains the specifications for cryptographic provenance 9 | primitives used in constructing fully decentralized solutions for PKI, secure 10 | software supply chain, IP management, content authenticity, and identity. 11 | 12 | ## Specifications 13 | 14 | * [Provenance Logs][PLOGS] 15 | * [Wasm Cryptographic Constructs API][WACC] 16 | * Multicodec data objects 17 | * [Multikey][4] 18 | * [Multisig][5] 19 | * [Nonce][6] 20 | * [Very Long-lived Addresses (VLADs)][7] 21 | 22 | [0]: https://github.com/cryptidtech/provenance-specifications/blob/main/community_specification_license.md 23 | [1]: https://cryptid.tech 24 | [2]: https://github.com/cryptidtech/provenance-specifications/ 25 | [3]: https://github.com/multiformats/multiformats 26 | [4]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multikey.md 27 | [5]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multisig.md 28 | [6]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/nonce.md 29 | [7]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/vlad.md 30 | [PLOGS]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/provenance-logs.md 31 | [WACC]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/wacc.md 32 | -------------------------------------------------------------------------------- /notices.md: -------------------------------------------------------------------------------- 1 | # Notices 2 | 3 | ## Code of Conduct 4 | 5 | Contact for Code of Conduct issues or inquires: 6 | 7 | * Dave Huseby, dwh@linuxprogrammer.org 8 | * Mike Lodder, redmike7@gmail.com 9 | 10 | ## License Acceptance 11 | 12 | Per Community Specification License 1.0 Section 2.1.3.3, Licensees may indicate 13 | their acceptance of the Community Specification License by issuing a pull 14 | request to the Specification’s repository’s Notice.md file, including the 15 | Licensee’s name, authorized individuals' names, and repository system 16 | identifier (e.g. GitHub ID), and specification version. 17 | 18 | A Licensee may consent to accepting the current Community Specification License 19 | version or any future version of the Community Specification License by 20 | indicating "or later" after their specification version. 21 | 22 | --------------------------------------------------------------------------------- 23 | 24 | Licensee’s name: 25 | 26 | Authorized individual and system identifier: 27 | 28 | Specification version: 29 | 30 | --------------------------------------------------------------------------------- 31 | 32 | ## Withdrawals 33 | 34 | Name of party withdrawing: 35 | 36 | Date of withdrawal: 37 | 38 | --------------------------------------------------------------------------------- 39 | 40 | ## Exclusions 41 | 42 | This section includes any Exclusion Notices made against a Draft Deliverable or 43 | Approved Deliverable as set forth in the Community Specification Development 44 | License. Each Exclusion Notice must include the following information: 45 | 46 | - Name of party making the Exclusion Notice: 47 | 48 | - Name of patent owner: 49 | 50 | - Specification: 51 | 52 | - Version number: 53 | 54 | **For issued patents and published patent applications:** 55 | 56 | (i) patent number(s) or title and application number(s), as the case may be: 57 | 58 | (ii) identification of the specific part(s) of the Specification whose implementation makes the excluded claim a Necessary Claim. 59 | 60 | **For unpublished patent applications must provide either:** 61 | 62 | (i) the text of the filed application; or 63 | 64 | (ii) identification of the specific part(s) of the Specification whose implementation makes the excluded claim a Necessary Claim. 65 | 66 | ----------------------------------------------------------------------------------------- 67 | -------------------------------------------------------------------------------- /specifications/README.md: -------------------------------------------------------------------------------- 1 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][CRYPTID] 2 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][PROVENANCE] 3 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][MULTIFORMATS] 4 | [![](https://img.shields.io/badge/License-Functional_Source_1.1-red)][FSL] 5 | ![](https://github.com/cryptidtech/wacc/actions/workflows/rust.yml/badge.svg) 6 | 7 | # Web Assembly Cryptographic Constructs (WACC) VM 8 | 9 | This Rust crate is an implementation of the [WACC VM specification][SPEC] that 10 | is a part of the [provenance specifications][PROVENANCE]. It extends a standard 11 | web assembly VM with the set of data manipulation and cryptographic operations 12 | found in the WACC VM specification. Please see the specification Appendix for a 13 | full discussion of the motivation and design principles behind the this 14 | implementation. 15 | 16 | ## Purpose 17 | 18 | In general, the WACC VM is designed to be a way to describe data validation 19 | scripts similar to the way Bitcoin scripts work when validating a Bitcoin 20 | transaction. WACC VM scripts operate on fields in a virtual key-value store 21 | with strings as keys. No data is manipulated directly by the WACC scripts, they 22 | simply push and pop keys to the virtual stack and then execute cryptographic 23 | operations on the values associated with the keys on the stack and then do 24 | logic tests on the results. 25 | 26 | WACC VM scripts are designed to be very simple to write. The `examples/` folder 27 | contains examples of Rust code compiled as WACC VM scripts as well as web 28 | assembly text (wast) versions of scripts. Just like Bitcoin script, WACC VM 29 | scripts are designed to be executed in pairs with an "unlock" script executing 30 | before the "lock" script. The "unlock" script places key values on the virtual 31 | stack, setting up the data necessary for the "lock" script to execute the 32 | cryptographic operations. The goal is to be able to verify updates to the 33 | key-value store state. 34 | 35 | ## Use Cases 36 | 37 | ### Provenance Logs 38 | 39 | The primary use for WACC VM scripts is to provide control over who can append 40 | events to a [provenance log][PLOG]. The scripting is necessary because 41 | provenance logs enforce a proof "precedence" whereby verification proofs of one 42 | kind take precendence over proofs of other kinds. This creates the capabilities 43 | necessary to build useful decentralized identity, intellectual property 44 | management, and general data provenance solutions on top. 45 | 46 | [CRYPTID]: https://cryptid.tech/ 47 | [PROVENANCE]: https://github.com/cryptidtech/provenance-specifications/ 48 | [MULTIFORMATS]: https://github.com/multiformats/multiformats/ 49 | [FSL]: https://github.com/cryptidtech/provenance-log/blob/main/LICENSE.md 50 | [SPEC]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/wacc.md 51 | [PLOG]: https://github.com/cryptidtech/provenance-log/ 52 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Community Specification Contribution Policy 1.0 2 | 3 | This document provides the contribution policy for specifications and other 4 | documents developed using the Community Specification process in a repository 5 | (each a “Working Group”). Additional or alternate contribution policies may be 6 | adopted and documented by the Working Group. 7 | 8 | ## 1. Contribution Guidelines. 9 | 10 | This Working Group accepts contributions via pull requests. The following 11 | section outlines the process for merging contributions to the specification 12 | 13 | **1.1. Issues.** Issues are used as the primary method for tracking anything 14 | to do with this specification Working Group. 15 | 16 | **1.1.1. Issue Types.** There are three types of issues (each with their 17 | own corresponding label): 18 | 19 | **1.1.1.1. Discussion.** These are support or functionality inquiries that we 20 | want to have a record of for future reference. Depending on the discussion, 21 | these can turn into "Spec Change" issues. 22 | 23 | **1.1.1.2. Proposal.** Used for items that propose a new ideas or 24 | functionality that require a larger discussion. This allows for feedback from 25 | others before a specification change is actually written. All issues that are 26 | proposals should both have a label and an issue title of "Proposal: [the rest 27 | of the title]." A proposal can become a "Spec Change" and does not require a 28 | milestone. 29 | 30 | **1.1.1.3. Spec Change:** These track specific spec changes and ideas until 31 | they are complete. They can evolve from "Proposal" and "Discussion" items, or 32 | can be submitted individually depending on the size. Each spec change should be 33 | placed into a milestone. 34 | 35 | ## 2. Issue Lifecycle. 36 | 37 | The issue lifecycle is mainly driven by the Maintainer. All issue types follow 38 | the same general lifecycle. Differences are noted below. 39 | 40 | **2.1. Issue Creation.** 41 | 42 | **2.2. Triage.** 43 | 44 | o The Editor in charge of triaging will apply the proper labels for the 45 | issue. This includes labels for priority, type, and metadata. 46 | 47 | o (If needed) Clean up the title to succinctly and clearly state the issue. 48 | Also ensure that proposals are prefaced with "Proposal". 49 | 50 | **2.3. Discussion.** 51 | 52 | o "Spec Change" issues should be connected to the pull request that resolves 53 | it. 54 | 55 | o Whoever is working on a "Spec Change" issue should either assign the issue 56 | to themselves or make a comment in the issue saying that they are taking it. 57 | 58 | o "Proposal" and "Discussion" issues should stay open until resolved. 59 | 60 | **2.4. Issue Closure.** 61 | 62 | ## 3. How to Contribute a Patch. 63 | 64 | The Working Group uses pull requests to track changes. To submit a change to 65 | the specification: 66 | 67 | **3.1 Fork the Repo, modify the Specification to Address the Issue.** 68 | 69 | **3.2. Submit a Pull Request.** 70 | 71 | ## 4. Pull Request Workflow. 72 | 73 | The next section contains more information on the workflow followed for Pull 74 | Requests. 75 | 76 | **4.1. Pull Request Creation.** 77 | 78 | o We welcome pull requests that are currently in progress. They are a great 79 | way to keep track of important work that is in-flight, but useful for others to 80 | see. If a pull request is a work in progress, it should be prefaced with "WIP: 81 | [title]". You should also add the wip label Once the pull request is ready for 82 | review, remove "WIP" from the title and label. 83 | 84 | o It is preferred, but not required, to have a pull request tied to a 85 | specific issue. There can be circumstances where if it is a quick fix then an 86 | issue might be overkill. The details provided in the pull request description 87 | would suffice in this case. 88 | 89 | **4.2. Triage** 90 | 91 | o The Editor in charge of triaging will apply the proper labels for the 92 | issue. This should include at least a size label, a milestone, and awaiting 93 | review once all labels are applied. 94 | 95 | **4.3. Reviewing/Discussion.** 96 | 97 | o All reviews will be completed using the review tool. 98 | 99 | o A "Comment" review should be used when there are questions about the spec 100 | that should be answered, but that don't involve spec changes. This type of 101 | review does not count as approval. 102 | 103 | o A "Changes Requested" review indicates that changes to the spec need to be 104 | made before they will be merged. 105 | 106 | o Reviewers should update labels as needed (such as needs rebase). 107 | 108 | o When a review is approved, the reviewer should add LGTM as a comment. 109 | 110 | o Final approval is required by a designated Editor. Merging is blocked 111 | without this final approval. Editors will factor reviews from all other 112 | reviewers into their approval process. 113 | 114 | **4.4. Responsive.** Pull request owner should try to be responsive to 115 | comments by answering questions or changing text. Once all comments have been 116 | addressed, the pull request is ready to be merged. 117 | 118 | **4.5. Merge or Close.** 119 | 120 | o A pull request should stay open until a Maintainer has marked the pull 121 | request as approved. 122 | 123 | o Pull requests can be closed by the author without merging. 124 | 125 | o Pull requests may be closed by a Maintainer if the decision is made that it 126 | is not going to be merged. 127 | -------------------------------------------------------------------------------- /code_of_conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for 49 | moderation decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail 56 | address, posting via an official social media account, or acting as an 57 | appointed representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement as set forth in 63 | the repository's Notice.md file. All complaints will be reviewed and 64 | investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series of 86 | actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or permanent 93 | ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within the 113 | project community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][0], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder][1]. 123 | 124 | For answers to common questions about this code of conduct, see the [FAQ][2]. 125 | Translations are available [here][3]. 126 | 127 | [0]: https://www.contributor-covenant.org 128 | [1]: https://github.com/mozilla/diversity 129 | [2]: https://www.contributor-covenant.org/faq 130 | [3]: https://www.contributor-covenant.org/translations 131 | -------------------------------------------------------------------------------- /specifications/nonce.md: -------------------------------------------------------------------------------- 1 | # Nonce Specification 2 | **Version: 0.0.1** \ 3 | **Status: Pre-draft** \ 4 | © 2024 Cryptid Technologies, Inc. 5 | 6 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][0] 7 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][1] 8 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][2] 9 | 10 | This specification is subject to the [Community Specification License 1.0][3]. 11 | 12 | ## Contents 13 | 1. [Foreword](#foreword) 14 | 2. [Introduction](#introduction) 15 | 1. [Current Status](#current-status) 16 | 2. [Normative References](#normative-references) 17 | 3. [Terms and Definitions](#terms-and-definitions) 18 | 3. [Specification](#specification) 19 | 4. [Examples](#examples) 20 | 1. [A Nonce with Random Data](#a-nonce-with-random-data) 21 | 2. [A Nonce with Multisig Data](#a-nonce-with-multisig-data) 22 | 23 | ## [Foreword](#foreword) 24 | 25 | Attention is drawn to the possibility that some of the elements of this 26 | document may be the subject of patent rights. No party shall not be held 27 | responsible for identifying any or all such patent rights. 28 | 29 | Any trade name used in this document is information given for the convenience 30 | of users and does not constitute an endorsement. 31 | 32 | This document was prepared by Cryptid Technologies, Inc. 33 | 34 | Known patent licensing exclusions are available in the specification’s 35 | repository’s Notices.md file. 36 | 37 | Any feedback or questions on this document should be directed to 38 | [specifications repository][1]. 39 | 40 | THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly 41 | disclaim any warranties (express, implied, or otherwise), including implied 42 | warranties of merchantability, non-infringement, fitness for a particular 43 | purpose, or title, related to the materials. The entire risk as to 44 | implementing or otherwise using the materials is assumed by the implementer and 45 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 46 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 47 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 48 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 49 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 50 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 | 52 | ## [Introduction](#introduction) 53 | 54 | This specification outlines how to encode a nonce value (i.e. Number used ONCE) 55 | in a multiformats compatible way. Nonces are commonly used in a variety of 56 | cryptographic operations. 57 | 58 | ### [Current Status](#current-status) 59 | 60 | This version of the Nonce specification defines a minimal multiformats 61 | compatible encoding. It meets the needs of all use cases so far, however feel 62 | free to file an issue if you have a use case this does not cover. 63 | 64 | ### [Normative References](#normative-references) 65 | 66 | This document refers to `varuint` encoded values throughout. The normative 67 | reference for which can be found in the [multiformats unsigned-varint 68 | specification][4]. 69 | 70 | This document also refers to `sigils` the identify a codec or data type. The 71 | normative reference for the list of sigils can be found in the [multiformats 72 | multicodecs table][5]. 73 | 74 | ### [Terms and Definitions](#terms-and-definitions) 75 | 76 | **Varuint** 77 | : An unsigned integer variable encoded in a variable number bytes. 78 | 79 | **Sigil** 80 | : A constant value that maps to a codec or data type. 81 | 82 | ## [Specification](#specification) 83 | 84 | The following diagram shows the overall structure of a Nonce. A Nonce is 85 | identified by the `0x123b` sigil followed by a `varbytes` encoded array of 86 | octets. The sigil is encoded as a varuint `0xbb24`. 87 | 88 | ``` 89 | nonce sigil 90 | | 91 | v 92 | 0xbb24 93 | ^ 94 | | 95 | nonce octets 96 | 97 | ::= N(OCTET) 98 | ^ ^ 99 | / \ 100 | count of variable number 101 | octets of octets 102 | ``` 103 | The Nonce format is designed in such a way that tools only need support for 104 | `varuint` and `varbytes` processing to know exactly how many octets are in the 105 | Nonce object so that it can skip over it if needed. 106 | 107 | ## [Examples](#examples) 108 | 109 | ### [A Nonce with Random Data](#a-nonce-with-random-data) 110 | 111 | This example shows how a Nonce containing random data is encoded: 112 | 113 | ``` 114 | bb 24 -- varuint, nonce sigil 115 | 20 -- varuint, length of nonce data 116 | [32 octets] -- 32 octets of random data 117 | ``` 118 | 119 | ### [A Nonce with Multisig Data](#a-nonce-with-multisig-data) 120 | 121 | This example shows how a Nonce containing an EdDSA [Multisig][6]—as used in some 122 | [VLADs][7]—is encoded: 123 | 124 | ``` 125 | bb 24 -- varuint, nonce sigil (0x123b) 126 | 49 -- varuint, length of nonce data 127 | [ -- 73 octets of the Multisig 128 | b9 24 -- varuint, Multisig sigil (0x1239) 129 | 83 a6 c0 06 -- varuint, EdDSA multisig codec (0xd01303) 130 | [66 octets] -- 66 octets of Multisig data 131 | ] 132 | ``` 133 | 134 | In this example the data inside of the Nonce is a Multisig. The Multisig 135 | consists of 73 octets that begins with the `0xb924` Multisig sigil followed by 136 | the `0x83a6c006` EdDSA multisig codec signifying that this is an EdDSA signature. The 137 | remaining 66 octets are the Multisig message and attributes of the signature. 138 | 139 | [0]: https://cryptid.tech 140 | [1]: https://github.com/cryptidtech/provenance-specifications/ 141 | [2]: https://github.com/multiformats/multiformats 142 | [3]: https://github.com/CommunitySpecification/1.0 143 | [4]: https://github.com/multiformats/unsigned-varint/blob/master/README.md 144 | [5]: https://github.com/multiformats/multicodecs/blob/master/table.csv 145 | [6]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multisig.md 146 | [7]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/vlad.md 147 | -------------------------------------------------------------------------------- /specifications/wacc.md: -------------------------------------------------------------------------------- 1 | # Wasm Cryptographic Constructs (WACC) VM API Specification 2 | **Version: 0.0.1** \ 3 | **Status: Pre-draft** \ 4 | © 2024 Cryptid Technologies, Inc. 5 | 6 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][0] 7 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][1] 8 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][2] 9 | 10 | This specification is subject to the [Community Specification License 1.0][3] 11 | 12 | ## Contents 13 | 1. [Foreword](#foreword) 14 | 2. [Introduction](#introduction) 15 | 1. [Current Status](#current-status) 16 | 2. [Normative References](#normative-references) 17 | 3. [Terms and Definitions](#terms-and-definitions) 18 | 3. [Specification](#specification) 19 | 4. [Examples](#examples) 20 | 1. [WACC Logging](#wacc-logging) 21 | 2. [WACC Signature Verification](#wacc-signature-verification) 22 | 3. [WACC Locking Signature Verification](#wacc-locking-signature-verification) 23 | 4. [WACC Unlock Script](#wacc-unlock-script) 24 | 25 | ## [Foreword](#foreword) 26 | 27 | Attention is drawn to the possibility that some of the elements of this 28 | document may be the subject of patent rights. No party shall not be held 29 | responsible for identifying any or all such patent rights. 30 | 31 | Any trade name used in this document is information given for the convenience 32 | of users and does not constitute an endorsement. 33 | 34 | This document was prepared by Cryptid Technologies, Inc. 35 | 36 | Known patent licensing exclusions are available in the specification’s 37 | repository’s Notices.md file. 38 | 39 | Any feedback or questions on this document should be directed to 40 | [specifications repository][1]. 41 | 42 | THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly 43 | disclaim any warranties (express, implied, or otherwise), including implied 44 | warranties of merchantability, non-infringement, fitness for a particular 45 | purpose, or title, related to the materials. The entire risk as to 46 | implementing or otherwise using the materials is assumed by the implementer and 47 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 48 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 49 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 50 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 51 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 52 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 | 54 | ## [Introduction](#introduction) 55 | 56 | This specification describes the API specification for Wasm VM implementations 57 | designed for executing cryptographic operations such as data validation and 58 | proof verification. It takes its inspiration from the [Bitcoin script 59 | specification][4] in that there is an argument stack and the scripts execute 60 | cryptographic functions that operate on the stack. 61 | 62 | ### [Current Status](#current-status) 63 | 64 | The WACC API is fully defined by this specification and meets all of the needs 65 | of the current set of use cases. If there are new functions needed to meet new 66 | use cases please file a proposal as an issue in this repository. 67 | 68 | ### [Normative References](#normative-references) 69 | 70 | This document refers to `nonce` values. The normative reference for which can 71 | be found in the [multiformats nonce specification][5] 72 | 73 | This document refers to `multisig` encoded digital signatures. The normative 74 | reference for which can be found in the [multiformats multisig 75 | specification][6]. 76 | 77 | This document refers to `multikey` encoded cryptography keys. The normative 78 | reference for which can be found in the [multiformats multikey 79 | specification][7]. 80 | 81 | ### [Terms and Definitions](#terms-and-definitions) 82 | 83 | **Unlock** 84 | : The script that is executed to unlock an operation. Unlock operations 85 | push values onto the WACC VM stack that are satisfy conditions by the lock script. 86 | 87 | **Lock** 88 | : The script that is executed to lock an operation. Lock operations 89 | verify values pushed onto the WACC VM stack by the unlock script. 90 | If these values do not satisfy the conditions the operation is not allowed. 91 | 92 | ## [Specification](#specification) 93 | 94 | ## [Examples](#examples) 95 | 96 | WACC VM is a simple stack-based virtual machine that executes cryptographic 97 | operations in a push - pop manner. Push operations are the unlock script values. 98 | Pop operations are the lock script conditions that must be satisfied using the pushed 99 | values. 100 | 101 | ### [WACC Logging](#wacc-logging) 102 | 103 | This example shows how to use the WACC API that provides a logging function to log messages 104 | 105 | [Rust](https://github.com/cryptidtech/wacc/blob/main/examples/log/src/lib.rs) 106 | 107 | ### [WACC Signature Verification](#wacc-signature-verification) 108 | 109 | This example shows how to use the WACC API to verify a signature first 110 | 111 | [Rust](https://github.com/cryptidtech/wacc/blob/main/examples/signature_first/src/lib.rs) 112 | 113 | ### [WACC Locking Signature Verification](#wacc-locking-signature-verification) 114 | 115 | This example shows how to use the WACC API to verify a signature using a lock script 116 | 117 | [Rust](https://github.com/cryptidtech/wacc/blob/main/examples/signature_lock/src/lib.rs) 118 | 119 | ### [WACC Unlock Script](#wacc-unlock-script) 120 | 121 | This example shows how to use the WACC API to use the unlock script 122 | 123 | [Rust](https://github.com/cryptidtech/wacc/blob/main/examples/unlock/src/lib.rs) 124 | 125 | 126 | [0]: https://cryptid.tech 127 | [1]: https://github.com/cryptidtech/provenance-specifications/ 128 | [2]: https://github.com/multiformats/multiformats 129 | [3]: https://github.com/CommunitySpecification/1.0 130 | [4]: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki 131 | [5]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/nonce.md 132 | [6]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multisig.md 133 | [7]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multikey.md 134 | -------------------------------------------------------------------------------- /governance.md: -------------------------------------------------------------------------------- 1 | # Community Specification Governance Policy 1.0 2 | 3 | This document provides the governance policy for specifications and other 4 | documents developed using the Community Specification process in a repository 5 | (each a “Working Group”). Each Working Group and must adhere to the 6 | requirements in this document. 7 | 8 | ## 1. Roles. 9 | 10 | Each Working Group may include the following roles. Additional roles may be 11 | adopted and documented by the Working Group. 12 | 13 | **1.1. Maintainer.** “Maintainers” are responsible for organizing activities 14 | around developing, maintaining, and updating the specification(s) developed by 15 | the Working Group. Maintainers are also responsible for determining consensus 16 | and coordinating appeals. Each Working Group will designate one or more 17 | Maintainer for that Working Group. A Working Group may select a new or 18 | additional Maintainer(s) upon Approval of the Working Group Participants. 19 | 20 | **1.2. Editor.** “Editors” are responsible for ensuring that the contents of 21 | the document accurately reflect the decisions that have been made by the group, 22 | and that the specification adheres to formatting and content guidelines. Each 23 | Working Group will designate an Editor for that Working Group. A Working Group 24 | may select a new Editor upon Approval of the Working Group Participants. 25 | 26 | **1.3. Participants.** “Participants” are those that have made Contributions 27 | to the Working Group subject to the Community Specification License. 28 | 29 | ## 2. Decision Making. 30 | 31 | **2.1. Consensus-Based Decision Making.** Working Groups make decisions 32 | through a consensus process (“Approval” or “Approved”). While the agreement of 33 | all Participants is preferred, it is not required for consensus. Rather, the 34 | Maintainer will determine consensus based on their good faith consideration of 35 | a number of factors, including the dominant view of the Working Group 36 | Participants and nature of support and objections. The Maintainer will 37 | document evidence of consensus in accordance with these requirements. 38 | 39 | **2.2. Appeal Process.** Decisions may be appealed be via a pull request or 40 | an issue, and that appeal will be considered by the Maintainer in good faith, 41 | who will respond in writing within a reasonable time. 42 | 43 | ## 3. Ways of Working. 44 | 45 | Inspired by [ANSI’s Essential Requirements for Due Process][0], Community 46 | Specification Working Groups must adhere to consensus-based due process 47 | requirements. These requirements apply to activities related to the 48 | development of consensus for approval, revision, reaffirmation, and withdrawal 49 | of Community Specifications. Due process means that any person (organization, 50 | company, government agency, individual, etc.) with a direct and material 51 | interest has a right to participate by: a) expressing a position and its basis, 52 | b) having that position considered, and c) having the right to appeal. Due 53 | process allows for equity and fair play. The following constitute the minimum 54 | acceptable due process requirements for the development of consensus. 55 | 56 | **3.1. Openness.** Participation shall be open to all persons who are 57 | directly and materially affected by the activity in question. There shall be no 58 | undue financial barriers to participation. Voting membership on the consensus 59 | body shall not be conditional upon membership in any organization, nor 60 | unreasonably restricted on the basis of technical qualifications or other such 61 | requirements. Membership in a Working Group’s parent organization, if any, may 62 | be required. 63 | 64 | **3.2. Lack of Dominance.** The development process shall not be dominated by 65 | any single interest category, individual or organization. Dominance means a 66 | position or exercise of dominant authority, leadership, or influence by reason 67 | of superior leverage, strength, or representation to the exclusion of fair and 68 | equitable consideration of other viewpoints. 69 | 70 | **3.3. Balance.** The development process should have a balance of interests. 71 | Participants from diverse interest categories shall be sought with the 72 | objective of achieving balance. 73 | 74 | **3.4. Coordination and Harmonization.** Good faith efforts shall be made to 75 | resolve potential conflicts between and among deliverables developed under this 76 | Working Group and existing industry standards. 77 | 78 | **3.5. Consideration of Views and Objections.** Prompt consideration shall be 79 | given to the written views and objections of all Participants. 80 | 81 | **3.6. Written procedures.** This governance document and other materials 82 | documenting the Community Specification development process shall be available 83 | to any interested person. 84 | 85 | ## 4. Specification Development Process. 86 | 87 | **4.1. Pre-Draft.** Any Participant may submit a proposed initial draft 88 | document as a candidate Draft Specification of that Working Group. The 89 | Maintainer will designate each submission as a “Pre-Draft” document. 90 | 91 | **4.2. Draft.** Each Pre-Draft document of a Working Group must first be 92 | Approved to become a” Draft Specification”. Once the Working Group approves a 93 | document as a Draft Specification, the Draft Specification becomes the basis 94 | for all going forward work on that specification. 95 | 96 | **4.3. Working Group Approval.** Once a Working Group believes it has 97 | achieved the objectives for its specification as described in the Scope, it 98 | will Approve that Draft Specification and progress it to “Approved 99 | Specification” status. 100 | 101 | **4.4. Publication and Submission.** Upon the designation of a Draft 102 | Specification as an Approved Specification, the Maintainer will publish the 103 | Approved Specification in a manner agreed upon by the Working Group 104 | Participants (i.e., Working Group Participant only location, publicly available 105 | location, Working Group maintained website, Working Group member website, 106 | etc.). The publication of an Approved Specification in a publicly accessible 107 | manner must include the terms under which the Approved Specification is being 108 | made available under. 109 | 110 | **4.5. Submissions to Standards Bodies.** No Draft Specification or Approved 111 | Specification may be submitted to another standards development organization 112 | without Working group Approval. Upon reaching Approval, the Maintainer will 113 | coordinate the submission of the applicable Draft Specification or Approved 114 | Specification to another standards development organization. Working Group 115 | Participants that developed that Draft Specification or Approved Specification 116 | agree to grant the copyright rights necessary to make those submissions. 117 | 118 | ## 5. Non-Confidential, Restricted Disclosure. 119 | 120 | Information disclosed in connection with any Working Group activity, including 121 | but not limited to meetings, Contributions, and submissions, is not 122 | confidential, regardless of any markings or statements to the contrary. 123 | Notwithstanding the foregoing, if the Working Group is collaborating via a 124 | private repository, the Participants will not make any public disclosures of 125 | that information contained in that private repository without the Approval of 126 | the Working Group. 127 | 128 | [0]: https://share.ansi.org/Shared%20Documents/Standards%20Activities/American%20National%20Standards/Procedures,%20Guides,%20and%20Forms/2020_ANSI_Essential_Requirements.pdf 129 | -------------------------------------------------------------------------------- /specifications/multisig.md: -------------------------------------------------------------------------------- 1 | # Multisig Specification 2 | **Version: 0.0.1** \ 3 | **Status: Pre-draft** \ 4 | © 2024 Cryptid Technologies, Inc. 5 | 6 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][0] 7 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][1] 8 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][2] 9 | 10 | This specification is subject to the [Community Specification License 1.0][3]. 11 | 12 | ## Contents 13 | 1. [Foreword](#foreword) 14 | 2. [Introduction](#introduction) 15 | 1. [Current Status](#current-status) 16 | 2. [Normative References](#normative-references) 17 | 3. [Terms and Definitions](#terms-and-definitions) 18 | 3. [Specification](#specification) 19 | 1. [Signature Message](#signature-message) 20 | 2. [Attributes](#attributes) 21 | 4. [Examples](#examples) 22 | 1. [An EdDSA Multisig](#an-eddsa-multisig) 23 | 2. [A BLS12-381 G1 Multisig Share](#a-bls12-381-g1-multisig-share) 24 | 25 | ## [Foreword](#foreword) 26 | 27 | Attention is drawn to the possibility that some of the elements of this 28 | document may be the subject of patent rights. No party shall not be held 29 | responsible for identifying any or all such patent rights. 30 | 31 | Any trade name used in this document is information given for the convenience 32 | of users and does not constitute an endorsement. 33 | 34 | This document was prepared by Cryptid Technologies, Inc. 35 | 36 | Known patent licensing exclusions are available in the specification’s 37 | repository’s Notices.md file. 38 | 39 | Any feedback or questions on this document should be directed to 40 | [specifications repository][1]. 41 | 42 | THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly 43 | disclaim any warranties (express, implied, or otherwise), including implied 44 | warranties of merchantability, non-infringement, fitness for a particular 45 | purpose, or title, related to the materials. The entire risk as to 46 | implementing or otherwise using the materials is assumed by the implementer and 47 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 48 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 49 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 50 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 51 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 52 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 | 54 | ## [Introduction](#introduction) 55 | 56 | This specification outlines how to encode arbitrary digital signatures data in 57 | a codec-agnostic way while also supporting codec-specific attribute read-write 58 | and codec-specific cryptographic operations. Digital signatures are created 59 | from Multikey values and data to be signed. 60 | 61 | ### [Current Status](#current-status) 62 | 63 | This version of the Multisig specification 64 | 65 | ### [Normative References](#normative-references) 66 | 67 | This document refers to `varuint` encoded values throughout. The normative 68 | reference for which can be found in the [multiformats unsigned-varint 69 | specification][4]. 70 | 71 | This document also refers to `sigils` the identify a codec or data type. The 72 | normative reference for the list of sigils can be found in the [multiformats 73 | multicodecs table][5]. 74 | 75 | ### [Terms and Definitions](#terms-and-definitions) 76 | 77 | **Varuint** 78 | : An unsigned integer variable encoded in a variable number bytes. 79 | 80 | **Sigil** 81 | : A constant value that maps to a codec or data type. 82 | 83 | **Attributes** 84 | : Each Multisig object consists of a set of attributes identified by a 85 | name/numerical value with an associated binary value. This is how the Multikey 86 | supports all the different codec-specific data and use cases. 87 | 88 | ## [Specification](#specification) 89 | 90 | The following diagram explains the overall structure of a Multisig. A Multisig 91 | is identified by the `0x1239` sigil followed by a key codec sigil, message, and 92 | a variable number of codec-specific attributes. The sigil is encoded as a 93 | varuint `0xb924`. 94 | 95 | ``` 96 | signing codec sigil signature attributes 97 | | | 98 | v v 99 | 0xb924 100 | ^ ^ 101 | | | 102 | multisig optional combined 103 | sigil signature message 104 | 105 | ::= 106 | 107 | variable number of attributes 108 | | 109 | ______________________ 110 | / \ 111 | ::= N(, ) 112 | ^ ^ ^ 113 | / / | 114 | count of attribute attribute 115 | attributes identifier value 116 | 117 | 118 | ::= N(OCTET) 119 | ^ ^ 120 | / \ 121 | count of variable number 122 | octets of octets 123 | ``` 124 | 125 | The Multisig format allows tools that don't recognize the signing codec--or any 126 | of this format other than varuint and varbytes--to know how many octets are in 127 | the Multisig data object and skip over it. This format is also designed to 128 | support any kind of digital signature, even signatures with multiple signature 129 | payloads such as threshold signatures. This also supports building combined 130 | signatures that contain the signed data in the `message` part of the signature. 131 | 132 | ### [Signature Message](#signature-message) 133 | 134 | In a Multisig object, the message is optional. When present, the Multisig is 135 | called a "combined" signature. When it isn't present, this is a "detached" 136 | signature. Either way the message that is signed, as well as the verifying 137 | Multikey, are required to verify the validity of a Multisig signature. 138 | 139 | ### [Attributes](#attributes) 140 | 141 | **SigData (0x00)** 142 | : The signature data. 143 | 144 | **PayloadEncoding (0x01)** 145 | : The sigil specifying the encoding of the signed message. 146 | 147 | **Scheme (0x02)** 148 | : The threshold signing scheme. 149 | 150 | **Threshold (0x03)** 151 | : The minumum number of signature shares required to reconstruct the signature. 152 | 153 | **Limit (0x04)** 154 | : The total number of shares for a threshold signature. 155 | 156 | **ShareIdentifier (0x05)** 157 | : The identifier for the signature share. 158 | 159 | **ThresholdData (0x06)** 160 | : Codec-speicific threshold signature data. This is typically used to 161 | accumulate threshold signature shares. 162 | 163 | **AlgorithmName (0x07)** 164 | : An arbitrary string name for the algorithm. This is optional and is intended 165 | to support arbitrary and/or non-standard signature types. Some implementations 166 | may set this attribute for standard algorithm signatures but do not rely upon 167 | that. Interpretation of the algorithm name is application specific. 168 | 169 | ## [Examples](#examples) 170 | 171 | ### [An EdDSA Multisig](#an-eddsa-multisig) 172 | 173 | This example shows how a Multisig stores an EdDSA digital signature: 174 | 175 | ``` 176 | b9 24 -- varuint, Multisig sigil (0x1239) 177 | 83 a6 c0 06 -- varuint, EdDSA multisig codec (0xd01303) 178 | 00 -- varuint, message length (0), detached signature 179 | 01 -- varuint, number of attributes 180 | 00 -- varuint, AttrId::SigData 181 | 40 -- varuint, attribute length (64 octets) 182 | [64 octets] -- signature data 183 | ``` 184 | 185 | ### [A BLS12-381 G1 Multisig Share](#a-bls12-381-g1-multisig-share) 186 | 187 | This examples shows how a Multsig with a BLS12-381 G1 signature share is 188 | encoded: 189 | 190 | ``` 191 | b9 24 -- varuint, Multisig sigil (0x1239) 192 | 84 a6 c0 06 -- varuint, Bls12381G1SigShare sigil (0xd01304) 193 | 00 -- varuint, message length (0), detached signature 194 | 05 -- varuint, number of attributes 195 | 00 -- varuint, AttrId::SigData 196 | 30 -- varuint, attribute length (48 octets) 197 | [48 octets] -- signature data 198 | 02 -- varuint, AttrId::Scheme 199 | 01 -- varuint, attribute length 200 | [02] -- varuint, Bls proof-of-possession 201 | 03 -- varuint, AttrId::Threshold 202 | 01 -- varuint, attribute length 203 | [03] -- varuint, 3 shares needed to reconstruct the signature 204 | 04 -- varuint, AttrId::Limit 205 | 01 -- varuint, length of attribute 206 | [04] -- varuint, 4 shares total 207 | 05 -- varuint, AttrId::ShareIdentifier 208 | 01 -- varuint, length of attribute 209 | [01] -- varuint, share number 1 210 | ``` 211 | 212 | [0]: https://cryptid.tech 213 | [1]: https://github.com/cryptidtech/provenance-specifications/ 214 | [2]: https://github.com/multiformats/multiformats 215 | [3]: https://github.com/CommunitySpecification/1.0 216 | [4]: https://github.com/multiformats/unsigned-varint 217 | [5]: https://github.com/multiformats/multicodecs/blob/master/table.csv 218 | -------------------------------------------------------------------------------- /specifications/varuint.md: -------------------------------------------------------------------------------- 1 | # Varuint Specification 2 | **Version: 0.0.1** \ 3 | **Status: Pre-draft** \ 4 | © 2024 Cryptid Technologies, Inc. 5 | 6 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][0] 7 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][1] 8 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][2] 9 | 10 | This specification is subject to the [Community Specification License 1.0][3]. 11 | 12 | ## Contents 13 | 1. [Foreword](#foreword) 14 | 2. [Introduction](#introduction) 15 | 1. [Current Status](#current-status) 16 | 2. [Normative References](#normative-references) 17 | 3. [Terms and Definitions](#terms-and-definitions) 18 | 3. [Specification](#specification) 19 | 1. [Encoding Algorithm](#encoding-algorithm) 20 | 2. [Decoding Algorithm](#decoding-algorithm) 21 | 3. [Minimal Encoding Requirement](#minimal-encoding-requirement) 22 | 4. [Examples](#examples) 23 | 1. [Single-Byte Values](#single-byte-values) 24 | 2. [Multi-Byte Values](#multi-byte-values) 25 | 3. [Sigil Encodings](#sigil-encodings) 26 | 27 | ## [Foreword](#foreword) 28 | 29 | Attention is drawn to the possibility that some of the elements of this 30 | document may be the subject of patent rights. No party shall not be held 31 | responsible for identifying any or all such patent rights. 32 | 33 | Any trade name used in this document is information given for the convenience 34 | of users and does not constitute an endorsement. 35 | 36 | This document was prepared by Cryptid Technologies, Inc. 37 | 38 | Known patent licensing exclusions are available in the specification's 39 | repository's Notices.md file. 40 | 41 | Any feedback or questions on this document should be directed to 42 | [specifications repository][1]. 43 | 44 | THESE MATERIALS ARE PROVIDED "AS IS." The Contributors and Licensees expressly 45 | disclaim any warranties (express, implied, or otherwise), including implied 46 | warranties of merchantability, non-infringement, fitness for a particular 47 | purpose, or title, related to the materials. The entire risk as to 48 | implementing or otherwise using the materials is assumed by the implementer and 49 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 50 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 51 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 52 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 53 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 54 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 | 56 | ## [Introduction](#introduction) 57 | 58 | This specification describes the encoding of unsigned integers as variable- 59 | length byte sequences (varuint) used throughout the multiformats ecosystem. 60 | Varuint encoding provides space-efficient serialization for small numbers while 61 | supporting arbitrarily large values. 62 | 63 | ### [Current Status](#current-status) 64 | 65 | This version of the Varuint specification documents the encoding format used in 66 | all multiformats specifications. It is derived from the [multiformats unsigned- 67 | varint specification][4] and provides a normative reference for all provenance 68 | specifications that use varuint encoding. 69 | 70 | ### [Normative References](#normative-references) 71 | 72 | This specification is based on the [multiformats unsigned-varint 73 | specification][4], which is itself based on unsigned LEB128 (Little Endian Base 74 | 128) encoding with additional restrictions for security and consistency. 75 | 76 | This document also refers to `sigils` that identify a codec or data type. The 77 | normative reference for the list of sigils can be found in the [multiformats 78 | multicodecs table][5]. 79 | 80 | ### [Terms and Definitions](#terms-and-definitions) 81 | 82 | **Varuint** 83 | : An unsigned integer encoded in a variable number of bytes using the encoding 84 | specified in this document. 85 | 86 | **Sigil** 87 | : A constant value that maps to a codec or data type, encoded as a varuint. 88 | 89 | **Continuation Bit** 90 | : The most significant bit (MSB) of each byte in a varuint encoding. When set 91 | to 1, it indicates that additional bytes follow. When set to 0, it indicates 92 | the current byte is the final byte. 93 | 94 | **LEB128** 95 | : Little Endian Base 128, a variable-length encoding for unsigned integers. 96 | 97 | ## [Specification](#specification) 98 | 99 | Varuint encoding serializes unsigned integers in a space-efficient manner by 100 | encoding 7 bits of data per byte, with the 8th bit (MSB) serving as a 101 | continuation indicator. 102 | 103 | ### [Encoding Algorithm](#encoding-algorithm) 104 | 105 | To encode an unsigned integer as a varuint: 106 | 107 | 1. Start with the least significant 7 bits of the integer 108 | 2. If the remaining value (after removing those 7 bits) is non-zero: 109 | - Set the MSB (bit 7) of the current byte to 1 (continuation bit) 110 | - Proceed to encode the next 7 bits 111 | 3. If the remaining value is zero: 112 | - Set the MSB (bit 7) of the current byte to 0 (termination bit) 113 | - Complete the encoding 114 | 115 | The encoding proceeds from least significant to most significant bits, with 116 | each byte containing 7 bits of data and 1 continuation bit. 117 | 118 | ### [Decoding Algorithm](#decoding-algorithm) 119 | 120 | To decode a varuint: 121 | 122 | 1. Read bytes sequentially 123 | 2. For each byte: 124 | - Extract the lower 7 bits as data 125 | - Check the MSB: 126 | - If MSB is 1, continue reading the next byte 127 | - If MSB is 0, this is the final byte 128 | 3. Reconstruct the integer by combining the 7-bit segments: 129 | - First byte contributes bits 0-6 130 | - Second byte contributes bits 7-13 (multiply by 128) 131 | - Third byte contributes bits 14-20 (multiply by 16384) 132 | - And so on... 133 | 134 | ### [Minimal Encoding Requirement](#minimal-encoding-requirement) 135 | 136 | Varuint encodings MUST be minimal. This means: 137 | 138 | 1. **No leading zeros**: The encoding must use the minimum number of bytes 139 | required to represent the value 140 | 2. **Only zero encodes as 0x00**: The value 0 is the only value that can be 141 | encoded as a single byte 0x00 142 | 3. **Rejection of non-minimal encodings**: Decoders MUST reject varuints with 143 | unnecessary leading zero bytes. For example, encoding the value 1 as 144 | `0x81 0x00` is invalid and must be rejected 145 | 146 | This requirement ensures canonical encoding and prevents potential security 147 | vulnerabilities related to alternative encodings of the same value. 148 | 149 | **Maximum Size**: Implementations MUST restrict varuints to a maximum of 9 150 | bytes (63 bits) to prevent denial-of-service attacks involving arbitrarily 151 | large encoded integers. 152 | 153 | ## [Examples](#examples) 154 | 155 | ### [Single-Byte Values](#single-byte-values) 156 | 157 | Values from 0 to 127 can be encoded in a single byte: 158 | 159 | ``` 160 | Value 0 (0x00): 161 | 00000000 => 0x00 162 | MSB=0 (final byte), data bits = 0000000 163 | 164 | Value 1 (0x01): 165 | 00000001 => 0x01 166 | MSB=0 (final byte), data bits = 0000001 167 | 168 | Value 127 (0x7f): 169 | 01111111 => 0x7f 170 | MSB=0 (final byte), data bits = 1111111 171 | Maximum single-byte value 172 | ``` 173 | 174 | ### [Multi-Byte Values](#multi-byte-values) 175 | 176 | Values 128 and above require multiple bytes: 177 | 178 | ``` 179 | Value 128 (0x80): 180 | 10000000 00000001 => 0x80 0x01 181 | Byte 0: MSB=1 (continuation), data = 0000000 (0) 182 | Byte 1: MSB=0 (final), data = 0000001 (1) 183 | Reconstruction: 0 + (1 × 128) = 128 184 | 185 | Value 255 (0xff): 186 | 11111111 00000001 => 0xff 0x01 187 | Byte 0: MSB=1 (continuation), data = 1111111 (127) 188 | Byte 1: MSB=0 (final), data = 0000001 (1) 189 | Reconstruction: 127 + (1 × 128) = 255 190 | 191 | Value 300 (0x012c): 192 | 10101100 00000010 => 0xac 0x02 193 | Byte 0: MSB=1 (continuation), data = 0101100 (44) 194 | Byte 1: MSB=0 (final), data = 0000010 (2) 195 | Reconstruction: 44 + (2 × 128) = 300 196 | 197 | Value 16384 (0x4000): 198 | 10000000 10000000 00000001 => 0x80 0x80 0x01 199 | Byte 0: MSB=1, data = 0000000 (0) 200 | Byte 1: MSB=1, data = 0000000 (0) 201 | Byte 2: MSB=0, data = 0000001 (1) 202 | Reconstruction: 0 + (0 × 128) + (1 × 16384) = 16384 203 | ``` 204 | 205 | ### [Sigil Encodings](#sigil-encodings) 206 | 207 | The following table shows how common sigils used in multiformats specifications 208 | are encoded as varuints: 209 | 210 | ``` 211 | Sigil Value Sigil Name Varuint Encoding 212 | ----------- --------------- ---------------- 213 | 0xed EdDSA 0xed 214 | 0x123a Multikey 0xba 0x24 215 | 0x123b Nonce 0xbb 0x24 216 | 0x1239 Multisig 0xb9 0x24 217 | 0x1207 VLAD 0x87 0x24 218 | 0x1300 Ed25519 priv key 0x80 0x26 219 | 0x1301 secp256k1 pub key 0x81 0x26 220 | 0xd01304 Bls12381G1SigShare 0x84 0xa6 0xc0 0x06 221 | 222 | Example: Encoding sigil 0x123b (Nonce = 4667 decimal): 223 | 4667 = 0x123b 224 | Step 1: 4667 mod 128 = 59 (0x3b), 4667 ÷ 128 = 36 225 | Byte 0: 10111011 = 0xbb (MSB=1, data=59) 226 | Step 2: 36 mod 128 = 36 (0x24), 36 ÷ 128 = 0 227 | Byte 1: 00100100 = 0x24 (MSB=0, data=36) 228 | Result: 0xbb 0x24 229 | ``` 230 | 231 | [0]: https://cryptid.tech 232 | [1]: https://github.com/cryptidtech/provenance-specifications/ 233 | [2]: https://github.com/multiformats/multiformats 234 | [3]: https://github.com/CommunitySpecification/1.0 235 | [4]: https://github.com/multiformats/unsigned-varint/blob/master/README.md 236 | [5]: https://github.com/multiformats/multicodecs/blob/master/table.csv 237 | -------------------------------------------------------------------------------- /specifications/vlad.md: -------------------------------------------------------------------------------- 1 | # Very Long-Lived Address (VLAD) Specification 2 | **Version: 0.0.1** \ 3 | **Status: Pre-draft** \ 4 | © 2024 Cryptid Technologies, Inc. 5 | 6 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][0] 7 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][1] 8 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][2] 9 | 10 | This specification is subject to the [Community Specification License 1.0][3] 11 | 12 | ## Contents 13 | 1. [Foreword](#foreword) 14 | 2. [Introduction](#introduction) 15 | 1. [Current Status](#current-status) 16 | 2. [Normative References](#normative-references) 17 | 3. [Terms and Definitions](#terms-and-definitions) 18 | 3. [Specification](#specification) 19 | 4. [Annex](#annex) 20 | 1. [Do Not Use Public Keys as Identifiers](#do-not-use-public-keys-as-identifiers) 21 | 2. [A Better Identifier](#a-better-identifier) 22 | 3. [VLAD Creation](#vlad-creation) 23 | 24 | ## [Foreword](#foreword) 25 | 26 | Attention is drawn to the possibility that some of the elements of this 27 | document may be the subject of patent rights. No party shall not be held 28 | responsible for identifying any or all such patent rights. 29 | 30 | Any trade name used in this document is information given for the convenience 31 | of users and does not constitute an endorsement. 32 | 33 | This document was prepared by Cryptid Technologies, Inc. 34 | 35 | Known patent licensing exclusions are available in the specification’s 36 | repository’s Notices.md file. 37 | 38 | Any feedback or questions on this document should be directed to 39 | [specifications repository][1]. 40 | 41 | THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly 42 | disclaim any warranties (express, implied, or otherwise), including implied 43 | warranties of merchantability, non-infringement, fitness for a particular 44 | purpose, or title, related to the materials. The entire risk as to 45 | implementing or otherwise using the materials is assumed by the implementer and 46 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 47 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 48 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 49 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 50 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 51 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 | 53 | ## [Introduction](#introduction) 54 | 55 | This specification outlines how to encode a very long-lived address (VLAD) in a 56 | multiformat compatible way. 57 | 58 | ### [Current Status](#current-status) 59 | 60 | VLADs are fully defined by this specification and meet all of the needs of the 61 | current set of use cases. 62 | 63 | ### [Normative References](#normative-references) 64 | 65 | This document refers to `varuint` encoded values throughout. The normative 66 | reference for which can be found in the [multiformats unsigned-varint 67 | specification][4]. 68 | 69 | This document refers to `sigils` the identify a codec or data type. The 70 | normative reference for the list of sigils can be found in the [multiformats 71 | multicodecs table][5]. 72 | 73 | This document refers to `CID` content identifiers. The normative reference for 74 | which can be found in the [multiformats cid specification][6] 75 | 76 | This document refers to `nonce` values. The normative reference for which can 77 | be found in the [multiformats nonce specification][7] 78 | 79 | This document refers to `multisig` encoded digital signatures. The normative 80 | reference for which can be found in the [multiformats multisig 81 | specification][8]. 82 | 83 | ### [Terms and Definitions](#terms-and-definitions) 84 | 85 | **Varuint** 86 | : An unsigned integer variable encoded in a variable number bytes. 87 | 88 | **Sigil** 89 | : A constant value that maps to a codec or data type. 90 | 91 | ## [Specification](#specification) 92 | 93 | The following diagram shows the overall structure of a VLAD. A VLAD 94 | is identified by the `0x1207` sigil followed by a `nonce` and a `cid`. The 95 | sigil is encoded as a varuint (`0x8724`). 96 | 97 | ``` 98 | vlad sigil cid value 99 | | / 100 | v v 101 | 0x8724 102 | ^ 103 | | 104 | nonce value 105 | ``` 106 | 107 | In some cases, the `varbytes` in the `nonce` are a `multisig` encoded digital 108 | signature over the `cid` value in the VLAD. The following diagram illustrates a 109 | signed VLAD. 110 | 111 | ``` 112 | vlad sigil cid value 113 | | / 114 | v v 115 | 0x8724 116 | ^ 117 | | 118 | nonce value 119 | 120 | ::= 0xbb24 121 | ^ 122 | / 123 | nonce sigil 124 | 125 | ::= 126 | ^ ^ 127 | / | 128 | count of variable number 129 | octets of multisig octets 130 | ``` 131 | 132 | ## [Annex](#annex) 133 | 134 | ### [Do Not Use Public Keys as Identifiers](#do-not-use-public-key-as-identifiers) 135 | 136 | One of the greatest failings of the current web-of-trust is the use of public 137 | keys as identifiers. Public key pairs are subject to attack and compromise in a 138 | number of ways necessitating regular rotation and occassional recovery to 139 | ensure a high degree of security and resiliency. Using public keys as 140 | identifiers means that whenever a key is rotated or revoked, any external 141 | references using the public key identifier becomes broken. It is this fragility 142 | that has prevented a global web-of-trust from being an emergent property of our 143 | socially networked lives. 144 | 145 | Why do we use public keys as identifiers? The answer is that they are a compact 146 | and convenient value with two primary properties: 147 | 148 | 1. Public keys have enough entropy that they can be used as identifiers for 149 | a very large number of things. Enough so that there could be a public key 150 | identifying every atom in the known universe and you wouldn't have used 151 | event a quarter of the available numbers. 152 | 2. A public key is a cryptographic commitment to a validation function (e.g. 153 | public key digital signature) that can be used to verify other data and 154 | bind ownership of that other data to the controller of the public key pair. 155 | 156 | It is plain to see that public keys solve the problem of cryptographically 157 | enforced proof-of-control while also being great random identifiers. However 158 | their vulnerability to attack and compromise makes them bad identifers for 159 | distributed systems that require loose coupling and resiliency over large spans 160 | of time. Key rotation is good security hygiene. It is also the primary reason 161 | why the web-of-trust isn't anti-fragile. 162 | 163 | ### [A Better Identifer](#a-better-identifier) 164 | 165 | Given the two primary properties of public keys listed above, it is conceivable 166 | that another type of identifer can be constructed with those same properties 167 | while also lacking the vulnerabilities and limitations to durability over time. 168 | All we have to do is construct a tuple identifer from a large random value-- 169 | commonly called a `nonce`--and a cryptographic commitment to a validation 170 | function. By combinding content addressable storage and WASM as universally 171 | executable code, any WASM code that validates data using cryptography may be 172 | hashed to create a content address that is both an immutable identifier for 173 | retrieving the WASM code and also a cryptographic verification method to ensure 174 | that the WASM code has not been modified and retains its original form down to 175 | the bit. 176 | 177 | Combining the nonce and the content address (e.g. `cid`) of a WASM validation 178 | function gives us an identifier that is both unique and a cryptographic 179 | commitment to a validation function; the same set of primary properties as 180 | public keys. However this new identifer is not based off of key material and is 181 | not subject to compromise. Any change in the WASM code is detectable and 182 | produces a different identifier. Any change in the nonce also creates a 183 | different identifier. The only way for one of these new identifiers to remain 184 | relevant over time is to remain unchanged. 185 | 186 | This new identifer is called a "Verifiable Long-lived ADdresses" or "VLAD". The 187 | security of the VLAD can be further enhanced by replacing the 256-bit nonce 188 | value with a digital signature--preferably an ECDSA/EdDSA signature for 189 | compactness--over the WASM content address. The resulting signature has the 190 | same amount of entropy as a random nonce but has the added benefit of allowing 191 | the creator of the VLAD to prove they created it. More on this later when we 192 | discuss VLADs as identifiers for provenance logs. 193 | 194 | To reduce the tight binding and fragility of VLADs, they are encoded using the 195 | multiformats standard. A VLAD therefore begins with the multicodec sigil 196 | identifying the data as a VLAD (e.g. `0x1207`) followed by two multiformat 197 | encoded values, a nonce (e.g. `0x123b`) or a multisig (e.g. `0x1239`) followed 198 | by a content addres CID (e.g. `0x01` v1, `0x02` v2, or `0x03` v3). 199 | 200 | ### [VLAD Creation](#vlad-creation) 201 | 202 | 1. Select the WASM validation function they would like to use for validating 203 | PUT operations in the global DHT for updating the mutable forward pointer. 204 | There is likely to be a small well-known set of WASM validation functions 205 | used. The CID of the chosen WASM is the value used in provenance log 206 | creation. 207 | 2. Generate an ephemeral cryptographic public key pair. 208 | 3. Digitally sign the CID of the WASM code to create the random value for the 209 | VLAD. 210 | 4. Encode the digital signature in the multisig multiformat, concatenate the 211 | CID to the multisig and add the VLAD sigil to the front to create a 212 | multiformat encoded VLAD value. 213 | 214 | [0]: https://cryptid.tech 215 | [1]: https://github.com/cryptidtech/provenance-specifications/ 216 | [2]: https://github.com/multiformats/multiformats 217 | [3]: https://github.com/CommunitySpecification/1.0 218 | [4]: https://github.com/multiformats/unsigned-varint/blob/master/README.md 219 | [5]: https://github.com/multiformats/multicodecs/blob/master/table.csv 220 | [6]: https://github.com/multiformats/cid/blob/master/README.md 221 | [7]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/nonce.md 222 | [8]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multisig.md 223 | -------------------------------------------------------------------------------- /specifications/multikey.md: -------------------------------------------------------------------------------- 1 | # Multikey Specification 2 | **Version: 0.0.1** \ 3 | **Status: Pre-draft** \ 4 | © 2024 Cryptid Technologies, Inc. 5 | 6 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][CRYPTID] 7 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][PROVSPEC] 8 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][MULTIFORMATS] 9 | 10 | This specification is subject to the [Community Specification License 1.0][COMMUNITYSPEC]. 11 | 12 | ## Contents 13 | 1. [Foreword](#foreword) 14 | 2. [Introduction](#introduction) 15 | 1. [Current Status](#current-status) 16 | 2. [Normative References](#normative-references) 17 | 3. [Terms and Definitions](#terms-and-definitions) 18 | 3. [Specification](#specification) 19 | 1. [Key Comment](#key-comment) 20 | 2. [Attributes](#attributes) 21 | 3. [Secret Keys](#secret-keys) 22 | 4. [Examples](#examples) 23 | 1. [An Encrypted EdDSA Secret Key](#an-encrypted-eddsa-secret-key) 24 | 2. [An Es256K Public Key](#an-es256k-public-key) 25 | 26 | ## [Foreword](#foreword) 27 | 28 | Attention is drawn to the possibility that some of the elements of this 29 | document may be the subject of patent rights. No party shall not be held 30 | responsible for identifying any or all such patent rights. 31 | 32 | Any trade name used in this document is information given for the convenience 33 | of users and does not constitute an endorsement. 34 | 35 | This document was prepared by Cryptid Technologies, Inc. 36 | 37 | Known patent licensing exclusions are available in the specification’s 38 | repository’s Notices.md file. 39 | 40 | Any feedback or questions on this document should be directed to 41 | [specifications repository][PROVSPEC]. 42 | 43 | THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly 44 | disclaim any warranties (express, implied, or otherwise), including implied 45 | warranties of merchantability, non-infringement, fitness for a particular 46 | purpose, or title, related to the materials. The entire risk as to 47 | implementing or otherwise using the materials is assumed by the implementer and 48 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 49 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 50 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 51 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 52 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 53 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 | 55 | ## [Introduction](#introduction) 56 | 57 | This specification outlines how to encode arbitrary cryptographic key material 58 | in a codec-agnostic way while also supporting codec-specific attribute read- 59 | write and codec-specific cryptographic operations (e.g. encrypt, decrypt, key 60 | generation, key splitting, digital signature signing and verification). The 61 | serialization format is suitable for network messages as well as storage in 62 | block devices. 63 | 64 | ### [Current Status](#current-status) 65 | 66 | This version of the Multikey specification defines attributes to support 67 | unencrypted public keys and both encrypted and unencrypted secret keys. The 68 | attributes also support storing the encrypted key cipher and key derivation 69 | functions so that the encryption key can be recreated from a secret. There are 70 | also attributes used to support threshold signing key splitting and 71 | recombining. 72 | 73 | ### [Normative References](#normative-references) 74 | 75 | This document refers to `varuint` encoded values throughout. The normative 76 | reference for which can be found in the [multiformats unsigned-varint 77 | specification][MULTIFORMATSREADME]. 78 | 79 | This document also refers to `sigils` the identify a codec or data type. The 80 | normative reference for the list of sigils can be found in the [multiformats 81 | multicodecs table][MULTIFORMATSTABLE]. 82 | 83 | ### [Terms and Definitions](#terms-and-definitions) 84 | 85 | **Varuint** 86 | : An unsigned integer variable encoded in a variable number bytes. 87 | 88 | **Sigil** 89 | : A constant value that maps to a codec or data type. 90 | 91 | **Comment** 92 | : A Multikey object contains a string that describes the key. This is 93 | application specific. 94 | 95 | **Attributes** 96 | : Each Multikey object consists of a set of attributes identified by a 97 | name/numerical value with an associated binary value. This is how the Multikey 98 | supports all the different codec-specific data and use cases. 99 | 100 | ## [Specification](#specification) 101 | 102 | The following diagram shows the overall structure of a Multikey. A Multikey 103 | is identified by the `0x123a` sigil followed by a codec sigil, comment, and a 104 | variable number of codec-specific attributes. The multikey sigil is encoded as 105 | a varuint `0xba24`. 106 | 107 | ``` 108 | multikey 109 | sigil key comment 110 | | | 111 | v v 112 | 0xba24 113 | ^ ^ 114 | | | 115 | key codec sigil key attributes 116 | 117 | 118 | ::= 119 | 120 | variable number of attributes 121 | | 122 | ______________________ 123 | / \ 124 | ::= N(, ) 125 | ^ ^ ^ 126 | / / | 127 | count of attribute attribute 128 | attributes identifier value 129 | 130 | 131 | ::= N(OCTET) 132 | ^ ^ 133 | / \ 134 | count of variable number 135 | octets of octets 136 | ``` 137 | 138 | The Multikey format is designed to support any kind of arbitrarily complex key 139 | data in such a way that tools are able to know exactly how many octets are in 140 | the Multikey object so that it can skip over it if they don't support the key 141 | codec. 142 | 143 | ### [Key Comment](#key-comment) 144 | 145 | By convention, every key has a comment that is easy to extract from the 146 | Multikey data structure by any tool, even if they do not support a specific key 147 | codec. 148 | 149 | ### [Attributes](#attributes) 150 | 151 | Each multikey consists of a set of attributes that are codec-specific and only 152 | meaningful through codec-specific "views" on the attribute table. Currently the 153 | list of defined attributes supports all of the use cases identified so far. The 154 | design of the attribute store leaves room for new attributes in the future. 155 | Please file an issue if you have a use case that requires a new attribute type. 156 | 157 | **KeyIsEncryptied (0x00)** 158 | : The value is a single boolean byte flag; true if the key data is encrypted. 159 | 160 | **KeyData (0x01)** 161 | : The value is the key data. 162 | 163 | **CipherCodec (0x02)** 164 | : The codec sigil specifying the encryption cipher used to encrypt the key data. 165 | 166 | **CipherKeyLen (0x03)** 167 | : The number of octets in the key encryption key. 168 | 169 | **CipherNonce (0x04)** 170 | : The nonce value for the key encryption cipher. 171 | 172 | **KdfCodec (0x05)** 173 | : The codec sigil specifying the key encryption key derivation function. 174 | 175 | **KdfSalt (0x06)** 176 | : The salt value used in the key encryption key derivation function. 177 | 178 | **KdfRounds (0x07)** 179 | : The number of rounds used in the key encryption key derivation function. 180 | 181 | **Threshold (0x08)** 182 | : The number of threshold signature key shares needed to recreate the key. 183 | 184 | **Limit (0x09)** 185 | : The total number of shares in the split threshold singature key. 186 | 187 | **ShareIdentifier (0x0a)** 188 | : The identifer for a given threshold key share. 189 | 190 | **ThresholdData (0x0b)** 191 | : Threshold signing codec-specific data. This is typically use to store the 192 | accumulated key shares while gathring enough shares to recreate the key. 193 | 194 | **AlgorithmName (0x0c)** 195 | : An arbitrary string name for the algorithm. This is optional and is intended 196 | to support arbitrary and/or non-standard key types. Some implementations may 197 | set this attribute for standard algorithm keys but do not rely upon that. 198 | Interpretation of the algorithm name is application specific. 199 | 200 | **KeyType (0x0d)** 201 | : An arbitrary numeric key type attribute. This is optional and is intended to 202 | support arbitrary and/or non-standard key types. Some implementations may set 203 | this attribute for standard algorithm keys but do not rely upon that. 204 | Interpretation of the key type is application specific. 205 | 206 | ### [Secret Keys](#secret-keys) 207 | 208 | Secret keys are sensitive and should always be kept encrypted when at rest. 209 | The attributes in the Multikey specify whether the key is encrypted and which 210 | encryption method was used as well as the key derivation method and parameters. 211 | 212 | This applies to both symmetric keys as well as the secret key part of a public 213 | key pair. 214 | 215 | ## [Examples](#examples) 216 | 217 | ### [An Encrypted EdDSA Secret Key](#an-encrypted-eddsa-secret-key) 218 | 219 | This example shows how a Multikey stores an EdDSA private key encrypted using 220 | the ChaCha20-Poly1305 AEAD symmetric encryption algorithm using a key derived 221 | using the Bcrypt PBKDF function with 10 rounds and a 32-byte salt value: 222 | 223 | ``` 224 | ba 24 -- varuint, multikey sigil (0x123a) 225 | 80 26 -- varuint, Ed25519 private key codec (0x1300) 226 | 08 -- varuint, length of comment 227 | "test key" -- 8 octets of UTF-8 comment data 228 | 08 -- varuint, 8 attributes 229 | 00 -- varuint, AttrId::KeyIsEncrypted 230 | 01 -- varuint, attribute length 231 | 01 -- true, it is encrypted! 232 | 01 -- varuint, AttrId::KeyData 233 | 30 -- varuint, attribute length (48 octets) 234 | [48 octets] -- ciphertext 235 | 02 -- varuint, AttrId::CipherCodec 236 | 03 -- varuint, attribute length 237 | 80 c0 02 -- varuint, ChaCha20-Poly1305 codec (0xa000) 238 | 03 -- varuint, AttrId::CipherKeyLen 239 | 01 -- varuint, attribute length 240 | 20 -- 32 byte key length 241 | 04 -- varuint, AttrId::CipherNonce 242 | 08 -- varuint, attribute length 243 | [8 octets] -- nonce 244 | 05 -- varuint, AttrId::KdfCodec 245 | 03 -- varuint, attribute length 246 | 8d a0 03 -- varuint, Bcrypt KDF codec 247 | 06 -- varuint, AttrId::KdfSalt 248 | 20 -- varuint, attribute length (32 octets) 249 | [32 octets] -- salt 250 | 07 -- varuint, AttrId::KdfRounds 251 | 01 -- varuint, attribute length 252 | 0a -- varuint, 10 kdf rounds 253 | ``` 254 | 255 | In this example the encoding starts off with the multikey sigil (`0xba24`) 256 | followed by the varuint codec value for an EdDSA private key (`0x8026`). 257 | Following that there is the key comment encoded as varbytes with a varuint 258 | length value followed by that number of octets of UTF-8 string data; in this 259 | case `"test key"`. The rest of the encoded Multikey is the list of attributes. 260 | All attributes are optional. Each attribute has an attribute ID followed by the 261 | varuint encoded length of the attribute data followed by the octets of 262 | attribute data. In this case of an encrypted EdDSA secret key, there are 263 | attributes for the flag showing it is encrypted, the encrypted key bytes, the 264 | encryption codec, the encryption key length, the nonce length, the nonce data, 265 | the kdf codec, the kdf salt length, the kdf salt, and the kdf rounds. 266 | 267 | ### [An Es256K Public Key](#an-es256k-public-key) 268 | 269 | This example shows how a Multikey encodes an Es256K public key. 270 | 271 | ``` 272 | ba 24 -- varuint, multikey sigil (0x123a) 273 | 81 26 -- varuint, secp256k1 public key codec (0x1301) 274 | 08 -- varuint, length of comment 275 | "test key" -- 8 octets of UTF-8 comment data 276 | 01 -- varuint, 1 attribute 277 | 01 -- varuint, AttrId::KeyData 278 | 21 -- varuint, attribute length (33 octets) 279 | [33 octets] -- key data 280 | ``` 281 | 282 | In this example the encoding starts off with the multikey sigil (`0xba24`) 283 | followed by the varuint encoded codec value for an secp256k1 public key 284 | (`0x8126`). Following that is 8 octets of UTF-8 comment data and the varuint 285 | encoded number of attributes in the attributes table. In this case there is 286 | only one attrbute, the key data itself which is encoded as the varuint 287 | encoded `KeyData` attribute ID, followed by the varuint encoded attribute 288 | length (33 octets), and the 33 octets of key data. 289 | 290 | [CRYPTID]: https://cryptid.tech/ 291 | [PROVSPEC]: https://github.com/cryptidtech/provenance-specifications/ 292 | [MULTIFORMATS]: https://github.com/multiformats/multiformats/ 293 | [COMMUNITYSPEC]: https://github.com/CommunitySpecification/1.0 294 | [MULTIFORMATSREADME]: https://github.com/multiformats/unsigned-varint/blob/master/README.md 295 | [MULTIFORMATSTABLE]: https://github.com/multiformats/multicodecs/blob/master/table.csv 296 | -------------------------------------------------------------------------------- /community_specification_license.md: -------------------------------------------------------------------------------- 1 | # Community Specification License 1.0 2 | 3 | **The Purpose of this License.** This License sets forth the terms under which 4 | 1) Contributor will participate in and contribute to the development of 5 | specifications, standards, best practices, guidelines, and other similar 6 | materials under this Working Group, and 2) how the materials developed under 7 | this License may be used. It is not intended for source code. Capitalized 8 | terms are defined in the License’s last section. 9 | 10 | **1. Copyright.** 11 | 12 | **1.1. Copyright License.** Contributor grants everyone a non-sublicensable, 13 | perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable 14 | (except as expressly stated in this License) copyright license, without any 15 | obligation for accounting, to reproduce, prepare derivative works of, publicly 16 | display, publicly perform, and distribute any materials it submits to the full 17 | extent of its copyright interest in those materials. Contributor also 18 | acknowledges that the Working Group may exercise copyright rights in the 19 | Specification, including the rights to submit the Specification to another 20 | standards organization. 21 | 22 | **1.2. Copyright Attribution.** As a condition, anyone exercising this 23 | copyright license must include attribution to the Working Group in any 24 | derivative work based on materials developed by the Working Group. That 25 | attribution must include, at minimum, the material’s name, version number, and 26 | source from where the materials were retrieved. Attribution is not required 27 | for implementations of the Specification. 28 | 29 | **2. Patents.** 30 | 31 | **2.1. Patent License.** 32 | 33 | **2.1.1. As a Result of Contributions.** 34 | 35 | **2.1.1.1. As a Result of Contributions to Draft Specifications.** 36 | Contributor grants Licensee a non-sublicensable, perpetual, worldwide, 37 | non-exclusive, no-charge, royalty-free, irrevocable (except as expressly stated 38 | in this License) license to its Necessary Claims in 1) Contributor’s 39 | Contributions and 2) to the Draft Specification that is within Scope as of the 40 | date of that Contribution, in both cases for Licensee’s Implementation of the 41 | Draft Specification, except for those patent claims excluded by Contributor 42 | under Section 3. 43 | 44 | **2.1.1.2. For Approved Specifications.** Contributor grants Licensee a 45 | non-sublicensable, perpetual, worldwide, non-exclusive, no-charge, 46 | royalty-free, irrevocable (except as expressly stated in this License) license 47 | to its Necessary Claims included the Approved Specification that are within 48 | Scope for Licensee’s Implementation of the Approved Specification, except for 49 | those patent claims excluded by Contributor under Section 3. 50 | 51 | **2.1.2. Patent Grant from Licensee.** Licensee grants each other Licensee 52 | a non-sublicensable, perpetual, worldwide, non-exclusive, no-charge, 53 | royalty-free, irrevocable (except as expressly stated in this License) license 54 | to its Necessary Claims for its Implementation, except for those patent claims 55 | excluded under Section 3. 56 | 57 | **2.1.3. Licensee Acceptance.** The patent grants set forth in Section 2.1 58 | extend only to Licensees that have indicated their agreement to this License as 59 | follows: 60 | 61 | **2.1.3.1. Source Code Distributions.** For distribution in source code, by 62 | including this License in the root directory of the source code with the 63 | Implementation; 64 | 65 | **2.1.3.2. Non-Source Code Distributions.** For distribution in any form 66 | other than source code, by including this License in the documentation, legal 67 | notices, via notice in the software, and/or other written materials provided 68 | with the Implementation; or 69 | 70 | **2.1.3.3. Via Notices.md.** By issuing pull request or commit to the 71 | Specification’s repository’s Notices.md file by the Implementer’s authorized 72 | representative, including the Implementer’s name, authorized individual and 73 | system identifier, and Specification version. 74 | 75 | **2.1.4. Defensive Termination.** If any Licensee files or maintains a 76 | claim in a court asserting that a Necessary Claim is infringed by an 77 | Implementation, any licenses granted under this License to the Licensee are 78 | immediately terminated unless 1) that claim is directly in response to a claim 79 | against Licensee regarding an Implementation, or 2) that claim was brought to 80 | enforce the terms of this License, including intervention in a third-party 81 | action by a Licensee. 82 | 83 | **2.1.5. Additional Conditions.** This License is not an assurance (i) that 84 | any of Contributor’s copyrights or issued patent claims cover an Implementation 85 | of the Specification or are enforceable or (ii) that an Implementation of the 86 | Specification would not infringe intellectual property rights of any third 87 | party. 88 | 89 | **2.2. Patent Licensing Commitment.** In addition to the rights granted in 90 | Section 2.1, Contributor agrees to grant everyone a no charge, royalty-free 91 | license on reasonable and non-discriminatory terms to Contributor’s Necessary 92 | Claims that are within Scope for: 1) Implementations of a Draft Specification, 93 | where such license applies only to those Necessary Claims infringed by 94 | implementing Contributor's Contribution(s) included in that Draft 95 | Specification, and 2) Implementations of the Approved Specification. 96 | 97 | This patent licensing commitment does not apply to those claims subject to 98 | Contributor’s Exclusion Notice under Section 3. 99 | 100 | **2.3. Effect of Withdrawal.** Contributor may withdraw from the Working 101 | Group by issuing a pull request or commit providing notice of withdrawal to the 102 | Working Group repository’s Notices.md file. All of Contributor’s existing 103 | commitments and obligations with respect to the Working Group up to the date of 104 | that withdrawal notice will remain in effect, but no new obligations will be 105 | incurred. 106 | 107 | **2.4. Binding Encumbrance.** This License is binding on any future owner, 108 | assignee, or party who has been given the right to enforce any Necessary Claims 109 | against third parties. 110 | 111 | **3. Patent Exclusion.** 112 | 113 | **3.1. As a Result of Contributions.** Contributor may exclude Necessary 114 | Claims from its licensing commitments incurred under Section 2.1.1 by issuing 115 | an Exclusion Notice within 45 days of the date of that Contribution. 116 | Contributor may not issue an Exclusion Notice for any material that has been 117 | included in a Draft Deliverable for more than 45 days prior to the date of that 118 | Contribution. 119 | 120 | **3.2. As a Result of a Draft Specification Becoming an Approved 121 | Specification.** Prior to the adoption of a Draft Specification as an Approved 122 | Specification, Contributor may exclude Necessary Claims from its licensing 123 | commitments under this Agreement by issuing an Exclusion Notice. Contributor 124 | may not issue an Exclusion Notice for patents that were eligible to have been 125 | excluded pursuant to Section 3.1. 126 | 127 | **4. Source Code License.** Any source code developed by the Working Group 128 | is solely subject the source code license included in the Working Group’s 129 | repository for that code. If no source code license is included, the source 130 | code will be subject to the MIT License. 131 | 132 | **5. No Other Rights.** Except as specifically set forth in this License, 133 | no other express or implied patent, trademark, copyright, or other rights are 134 | granted under this License, including by implication, waiver, or estoppel. 135 | 136 | **6. Antitrust Compliance.** Contributor acknowledge that it may compete 137 | with other participants in various lines of business and that it is therefore 138 | imperative that they and their respective representatives act in a manner that 139 | does not violate any applicable antitrust laws and regulations. This License 140 | does not restrict any Contributor from engaging in similar specification 141 | development projects. Each Contributor may design, develop, manufacture, 142 | acquire or market competitive deliverables, products, and services, and conduct 143 | its business, in whatever way it chooses. No Contributor is obligated to 144 | announce or market any products or services. Without limiting the generality 145 | of the foregoing, the Contributors agree not to have any discussion relating to 146 | any product pricing, methods or channels of product distribution, division of 147 | markets, allocation of customers or any other topic that should not be 148 | discussed among competitors under the auspices of the Working Group. 149 | 150 | **7. Non-Circumvention.** Contributor agrees that it will not intentionally 151 | take or willfully assist any third party to take any action for the purpose of 152 | circumventing any obligations under this License. 153 | 154 | **8. Representations, Warranties and Disclaimers.** 155 | 156 | **8.1. Representations, Warranties and Disclaimers.** Contributor and 157 | Licensee represents and warrants that 1) it is legally entitled to grant the 158 | rights set forth in this License and 2) it will not intentionally include any 159 | third party materials in any Contribution unless those materials are available 160 | under terms that do not conflict with this License. IN ALL OTHER RESPECTS ITS 161 | CONTRIBUTIONS ARE PROVIDED "AS IS." The entire risk as to implementing or 162 | otherwise using the Contribution or the Specification is assumed by the 163 | implementer and user. Except as stated herein, CONTRIBUTOR AND LICENSEE 164 | EXPRESSLY DISCLAIM ANY WARRANTIES (EXPRESS, IMPLIED, OR OTHERWISE), INCLUDING 165 | IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, FITNESS FOR A 166 | PARTICULAR PURPOSE, CONDITIONS OF QUALITY, OR TITLE, RELATED TO THE 167 | CONTRIBUTION OR THE SPECIFICATION. IN NO EVENT WILL ANY PARTY BE LIABLE TO ANY 168 | OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 169 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 170 | WITH RESPECT TO THIS AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT 171 | (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR NOT THE OTHER PARTY HAS 172 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Any obligations regarding the 173 | transfer, successors in interest, or assignment of Necessary Claims will be 174 | satisfied if Contributor or Licensee notifies the transferee or assignee of any 175 | patent that it knows contains Necessary Claims or necessary claims under this 176 | License. Nothing in this License requires Contributor to undertake a patent 177 | search. If Contributor is 1) employed by or acting on behalf of an employer, 2) 178 | is making a Contribution under the direction or control of a third party, or 3) 179 | is making the Contribution as a consultant, contractor, or under another 180 | similar relationship with a third party, Contributor represents that they have 181 | been authorized by that party to enter into this License on its behalf. 182 | 183 | **8.2. Distribution Disclaimer.** Any distributions of technical information 184 | to third parties must include a notice materially similar to the following: 185 | “THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly 186 | disclaim any warranties (express, implied, or otherwise), including implied 187 | warranties of merchantability, non-infringement, fitness for a particular 188 | purpose, or title, related to the materials. The entire risk as to 189 | implementing or otherwise using the materials is assumed by the implementer and 190 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 191 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 192 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 193 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 194 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 195 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” 196 | 197 | **9. Definitions.** 198 | 199 | **9.1. Affiliate.** “Affiliate” means an entity that directly or indirectly 200 | Controls, is Controlled by, or is under common Control of that party. 201 | 202 | **9.2. Approved Specification.** “Approved Specification” means the final 203 | version and contents of any Draft Specification designated as an Approved 204 | Specification as set forth in the accompanying Governance.md file. 205 | 206 | **9.3. Contribution.** “Contribution” means any original work of authorship, 207 | including any modifications or additions to an existing work, that Contributor 208 | submits for inclusion in a Draft Specification, which is included in a Draft 209 | Specification or Approved Specification. 210 | 211 | **9.4. Contributor.** “Contributor” means any person or entity that has 212 | indicated its acceptance of the License 1) by making a Contribution to the 213 | Specification, or 2) by entering into the Community Specification Contributor 214 | License Agreement for the Specification. Contributor includes its Affiliates, 215 | assigns, agents, and successors in interest. 216 | 217 | **9.5. Control.** “Control” means direct or indirect control of more than 50% 218 | of the voting power to elect directors of that corporation, or for any other 219 | entity, the power to direct management of such entity. 220 | 221 | **9.6. Draft Specification.** “Draft Specification” means all versions of the 222 | material (except an Approved Specification) developed by this Working Group for 223 | the purpose of creating, commenting on, revising, updating, modifying, or 224 | adding to any document that is to be considered for inclusion in the Approved 225 | Specification. 226 | 227 | **9.7. Exclusion Notice.** “Exclusion Notice” means a written notice made by 228 | making a pull request or commit to the repository’s Notices.md file that 229 | identifies patents that Contributor is excluding from its patent licensing 230 | commitments under this License. The Exclusion Notice for issued patents and 231 | published applications must include the Draft Specification’s name, patent 232 | number(s) or title and application number(s), as the case may be, for each of 233 | the issued patent(s) or pending patent application(s) that the Contributor is 234 | excluding from the royalty-free licensing commitment set forth in this License. 235 | If an issued patent or pending patent application that may contain Necessary 236 | Claims is not set forth in the Exclusion Notice, those Necessary Claims shall 237 | continue to be subject to the licensing commitments under this License. The 238 | Exclusion Notice for unpublished patent applications must provide either: (i) 239 | the text of the filed application; or (ii) identification of the specific 240 | part(s) of the Draft Specification whose implementation makes the excluded 241 | claim a Necessary Claim. If (ii) is chosen, the effect of the exclusion will 242 | be limited to the identified part(s) of the Draft Specification. 243 | 244 | **9.8. Implementation.** “Implementation” means making, using, selling, 245 | offering for sale, importing or distributing any implementation of the 246 | Specification 1) only to the extent it implements the Specification and 2) so 247 | long as all required portions of the Specification are implemented. 248 | 249 | **9.9. License.** “License” means this Community Specification License. 250 | 251 | **9.10. Licensee.** “Licensee” means any person or entity that has indicated 252 | its acceptance of the License as set forth in Section 2.1.3. Licensee includes 253 | its Affiliates, assigns, agents, and successors in interest. 254 | 255 | **9.11. Necessary Claims.** “Necessary Claims” are those patent claims, if 256 | any, that a party owns or controls, including those claims later acquired, that 257 | are necessary to implement the required portions (including the required 258 | elements of optional portions) of the Specification that are described in 259 | detail and not merely referenced in the Specification. 260 | 261 | **9.12. Specification.** “Specification” means a Draft Specification or 262 | Approved Specification included in the Working Group’s repository subject to 263 | this License, and the version of the Specification implemented by the Licensee. 264 | 265 | **9.13. Scope.** “Scope” has the meaning as set forth in the accompanying 266 | Scope.md file included in this Specification’s repository. Changes to Scope do 267 | not apply retroactively. If no Scope is provided, each Contributor’s Necessary 268 | Claims are limited to that Contributor’s Contributions. 269 | 270 | **9.14. Working Group.** “Working Group” means this project to develop 271 | specifications, standards, best practices, guidelines, and other similar 272 | materials under this License. 273 | 274 | *The text of this Community Specification License is Copyright 2020 Joint 275 | Development Foundation and is licensed under the Creative Commons Attribution 276 | 4.0 International License available at 277 | https://creativecommons.org/licenses/by/4.0/.* 278 | 279 | SPDX-License-Identifier: CC-BY-4.0 280 | -------------------------------------------------------------------------------- /specifications/provenance-logs.md: -------------------------------------------------------------------------------- 1 | # Provenance Logs Specification 2 | **Version: 0.0.1** \ 3 | **Status: Pre-draft** \ 4 | © 2024 Cryptid Technologies, Inc. 5 | 6 | [![](https://img.shields.io/badge/made%20by-Cryptid%20Technologies-gold.svg?style=flat-square)][0] 7 | [![](https://img.shields.io/badge/project-provenance-purple.svg?style=flat-square)][1] 8 | [![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)][2] 9 | 10 | This specification is subject to the [Community Specification License 1.0][3] 11 | 12 | ## Contents 13 | 1. [Foreword](#foreword) 14 | 2. [Introduction](#introduction) 15 | 1. [Current Status](#current-status) 16 | 2. [Normative References](#normative-references) 17 | 3. [Terms and Definitions](#terms-and-definitions) 18 | 3. [Specification](#specification) 19 | 1. [Features](#features) 20 | 2. [Entry](#entry) 21 | 3. [Virtual Name Space](#virtual-name-space) 22 | 4. [Hierarchical Keys](#hierarchical-keys) 23 | 5. [Values](#provenance-values) 24 | 6. [Mutation Operations](#mutation-operations) 25 | 7. [Unlock and Lock Scripts](#unlock-and-lock-scripts) 26 | 1. [Validating a Proposed Entry](#validating-a-proposed-entry) 27 | 2. [Unlock and Lock Script Functions](#unlock-and-lock-script-functions) 28 | 8. [Forking Provenance Logs](#forking-provenance-logs) 29 | 1. [Example Forking Using Delegation](#example-forking-using-delegation) 30 | 31 | ## [Foreword](#foreword) 32 | 33 | Attention is drawn to the possibility that some of the elements of this 34 | document may be the subject of patent rights. No party shall not be held 35 | responsible for identifying any or all such patent rights. 36 | 37 | Any trade name used in this document is information given for the convenience 38 | of users and does not constitute an endorsement. 39 | 40 | This document was prepared by Cryptid Technologies, Inc. 41 | 42 | Known patent licensing exclusions are available in the specification’s 43 | repository’s Notices.md file. 44 | 45 | Any feedback or questions on this document should be directed to 46 | [specifications repository][1]. 47 | 48 | THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly 49 | disclaim any warranties (express, implied, or otherwise), including implied 50 | warranties of merchantability, non-infringement, fitness for a particular 51 | purpose, or title, related to the materials. The entire risk as to 52 | implementing or otherwise using the materials is assumed by the implementer and 53 | user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER 54 | PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR 55 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND 56 | WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON 57 | BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR 58 | NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 | 60 | ## [Introduction](#introduction) 61 | 62 | This specification describes the specification for a hash-linked data structure 63 | that is a cryptographically verifiable provenance log. 64 | Provenance logs are constructed as a singly-linked list of entries that contain 65 | an arbitrarily long, ordered list of mutable operations to a virtual key-value 66 | store as well as a set of cryptographic puzzles that must be solved by the next entry in the list for it to remain valid. 67 | This design ensures delegatable, recoverable and revocable write control over the log. 68 | 69 | ### [Current Status](#current-status) 70 | 71 | Provenance Logs are fully defined by this specification and meets all of the needs 72 | of the current set of use cases. If there are new functions needed to meet new 73 | use cases please file a proposal as an issue in this repository. 74 | 75 | ### [Normative References](#normative-references) 76 | 77 | This document refers to `nonce` values. The normative reference for which can 78 | be found in the [multiformats nonce specification][5] 79 | 80 | This document refers to `multisig` encoded digital signatures. The normative 81 | reference for which can be found in the [multiformats multisig 82 | specification][6]. 83 | 84 | This document refers to `multikey` encoded cryptography keys. The normative 85 | reference for which can be found in the [multiformats multikey 86 | specification][7]. 87 | 88 | This document refers to the `wacc` VM API. The normative reference for which can 89 | be found in the [wacc_api_specification][8]. 90 | 91 | This document refers to `vlad`s. The normative reference for which can be found 92 | in the [vlad specification][9]. 93 | 94 | This document refers to `cid`s. The normative reference for which can be found 95 | in the [ipfs_content_identifier specification][https://docs.ipfs.tech/concepts/content-addressing/]. 96 | 97 | ### [Terms and Definitions](#terms-and-definitions) 98 | 99 | **DAG** 100 | : A directed acyclic graph. 101 | 102 | **LipmaaLinks** 103 | : A cryptographically secure hash of some older 104 | entry in the log, chosen such that there are 105 | short paths between any pair of entries. 106 | 107 | **CBOR** 108 | : Concise Binary Object Representation that is a self-describing 109 | binary data serialization format. 110 | 111 | **Noop** 112 | : No operation 113 | 114 | **Seqno** 115 | : A sequence number represented as a positive integer. 116 | 117 | ## [Specification](#specification) 118 | 119 | ### [Features](#features) 120 | Provenance Logs support the following list of features: 121 | 122 | * Sequence numbering for detecting forks and erasures. 123 | * [Lipmaa][LIPMAA] links for O(log N) path lengths between any two entries in a 124 | log. 125 | * Forking capability to create child logs with back links to the parent log 126 | forming a DAG of logs. 127 | * Stable, non-key-material identifier to scope/namespace each branch in the 128 | DAG of logs. 129 | * [WACC VM][8] verification script for the next entry is stored inline or 130 | externally in a content-addressable storage. 131 | * Serialization to/from DAG-CBOR for automated retrieval of the entire log. 132 | 133 | ### [Entry](#entry) 134 | 135 | Each entry contains the entry's version, the VLAD identifier, 136 | the CID for the previous entry, the CID of the lipmaa predecessor, 137 | the entry's sequence number, the list of mutation operations, the lock 138 | scripts for validating the next entry, the unlock script used for validating 139 | this entry and the proof data for validating this entry. 140 | 141 | ### [Virtual Name Space](#virtual-name-space) 142 | 143 | Provenance logs are a sequence of entries that each contain an ordered list 144 | of mutation operations applied to a virtual key-value pair store. There are 145 | three different possible operations: `update`, `delete`, and `noop`. `update` 146 | creates/modifies the value associated with a key-path. `delete` 147 | removes a key-value pair. `noop` does nothing, but does 148 | "touch" the associated key-path and is important for the lock script execution 149 | system. As each entry in the log is verified and processed, the mutations 150 | contained within are applied to the virtual key-value pair storage. These pairs 151 | have no intrinsic meaning. It is expected that they will have meaning in the 152 | context of the [WACC VM][8] lock and unlock scripts as well as in the 153 | context of applications consuming the logs. 154 | 155 | ### [Hierarchical Keys](#hierarchical-keys) 156 | 157 | The keys in the virtual key-value pair system are [UTF-8](https://www.w3schools.com/charsets/ref_html_utf8.asp) strings of printable 158 | characters and are hierarchical in nature. They work similarly to file paths in 159 | Linux in that they use the forward slash `/` character as the separator. All 160 | keys must begin with the `/` character. Multiple `/` characters together are 161 | invalid. Key-paths that end with a `/` are called branch key-paths and 162 | key-paths that do not are called leaf key-paths. It is correct to mentally 163 | think of branches like filesystem folders and leaves like files inside folders. 164 | A branch can contain other branches and/or leaves. 165 | 166 | ### [Values](#provenance-values) 167 | 168 | The values in the key-value pair store are self describing and can take one of 169 | three values: *nil*, *str*, or *data*. *nil* is an empty value. *str* 170 | is a UTF-8 text string. *data* is a binary blob. 171 | 172 | ### [Mutation Operations](#mutation-operations) 173 | 174 | Let's assume the first entry in a provenance log includes the following 175 | mutation ops: 176 | 177 | ```json 178 | "ops": [ 179 | { "noop": [ "/" ] }, 180 | { "update": [ "/name", { "str": [ "foo" ] } ] }, 181 | { "update": [ "/move", { "str": [ "zig" ] } ] }, 182 | { "delete": [ "/zig" ] }, 183 | ] 184 | ``` 185 | 186 | After validating the first entry and applying its mutations, the virtual 187 | key-value store contains the following: 188 | 189 | ```json 190 | { 191 | "/name": "foo", 192 | "/move": "zig", 193 | } 194 | ``` 195 | 196 | Then, assume the second entry contains the following mutation ops: 197 | 198 | ```json 199 | "ops": [ 200 | { "update": [ "/name", { "str": [ "bar" ] } ] }, 201 | { "delete": [ "/answer" ] }, 202 | { "update": [ "/move", { "str": [ "zig" ] } ] }, 203 | ] 204 | ``` 205 | 206 | After validating the second entry and applying its mutations, the virtual 207 | key-value store contains the following: 208 | 209 | ```json 210 | { 211 | "/name": "bar", 212 | "/move": "zig" 213 | } 214 | ``` 215 | 216 | ## [Unlock and Lock Scripts](#unlock-and-lock-scripts) 217 | 218 | Each entry contains a list of lock scripts and a single unlock script. The set 219 | of lock scripts define the conditions which must be met by the next entry in 220 | the log for it to be valid. The unlock script is the solution to one of the 221 | lock scripts in the previous entry. All scripts are wasm code that 222 | executes inside a [WACC VM][8]. When a script is executed, it is expected 223 | to reference data in a key-value store when executing. Along with the virtual 224 | key-value store built up from the op (operations) in each event, the scripts may also 225 | reference the fields in the event they are a part of (e.g. vlad, seqno, etc). 226 | Scripts can only be unlocked using data associated with their corresponding event. 227 | Lock scripts may reference all data in the key-value 228 | store as well as the data in the entry which it is a part of. 229 | 230 | ### [Validating a Proposed Entry](#validating-a-proposed-entry) 231 | 232 | It is critical to the security of the log that the validation of each entry be 233 | done following a very specific order of operations: 234 | 235 | 1. Create two empty key-value stores. 236 | 2. Load the proposed entry fields (e.g. seqno, vlad, proof, etc) into one 237 | key-value store to establish the proposed state. DO NOT apply the `ops` 238 | mutations from the proposed entry. 239 | 3. Load the unlock script from the proposed entry and execute it to initialize 240 | the stack to be used in the lock script execution. 241 | 4. Apply the mutations for each entry in the log, from the foot (first) to the 242 | head (last), to the other key-value store to establish the current state of 243 | the log for the lock script execution. 244 | 5. Execute each lock script from the current entry in root to leaf order. For 245 | each lock script, clone stack from step 2 and clone the key-value pair store 246 | from step 3 and execute it. 247 | 6. Check the top value on the return stack for a SUCCESS value, all other 248 | values indicate a failure. 249 | 250 | ### [Unlock and Lock Script Functions](#unlock-and-lock-script-functions) 251 | 252 | The following functions are available for use in lock and unlock scripts: 253 | 254 | **push()** 255 | : Pushes the value associated with the key-path onto the parameter stack. 256 | 257 | **pop()** 258 | : Pops the top value off of the parameter stack. 259 | 260 | **branch()** 261 | : Concatenates the branch key-path with the provided key-path to create a 262 | key-path argument for other functions. When used in lock scripts, the branch 263 | key-path is the key-path the lock script is associated with. When used in 264 | unlock scripts, the branch key-path is always `/`. This function fails if 265 | used in a lock script associated with a leaf. 266 | 267 | **check_eq()** 268 | : Compares the value associated with the key-path with the value on top of the 269 | parameter stack; increments the check counter if it fails. Pops one parameter 270 | off of the parameter stack if it succeeds. 271 | 272 | **check_preimage()** 273 | : Compares the hash associated with the key-path with the hash of the value on 274 | top of the parameter stack; increments the check counter if it fails. Pops 275 | one parameter off of the parameter stack if it succeeds. This function 276 | understands the [Multihash][10] format and is able to generate and 277 | verify preimages using any hash function it supports. 278 | 279 | **check_signature()** 280 | : Verifies the digital signature and message on the parameter stack using the 281 | public key associated with the key-path; increments the check counter if it 282 | fails. Pops two parameters off of the parameter stack if it succeeds. This 283 | function understands the [Multikey][7] and [Multisig][6] 284 | formats and is able to verify any digital signature they support. 285 | 286 | ### [Unlock Scripts](#unlock-scripts) 287 | 288 | Unlock scripts are code that compiles to wasm and executed in the [WACC 289 | VM][8]. For historical reasons, each unlock script is a wasm module with a 290 | single exported function called "for_great_justice". 291 | 292 | The unlock script in a proposed new entry references the proof and the other 293 | entry values to provide a solution to one of the lock scripts in the current 294 | head entry of the provenance log. By convention, when an unlock script executes 295 | the key-value store has the following keys populated with the data from the 296 | proposed entry like so: 297 | 298 | ``` 299 | ─┬─"/" 300 | ╰─┬─ "entry/" 301 | ╰─┬─ "version" 302 | ├─ "vlad" 303 | ├─ "prev" 304 | ├─ "lipmaa" 305 | ├─ "seqno" 306 | ├─ "ops" 307 | ├─ "locks" 308 | ├─ "unlock" 309 | ╰─ "proof" 310 | ``` 311 | 312 | An example unlock script for satisfying a `check_signature` lock script looks 313 | like: 314 | 315 | ```rust 316 | #[no_mangle] 317 | pub fn for_great_justice() { 318 | // push the serialized Entry as the message 319 | push("/entry/"); 320 | 321 | // push the proof data 322 | push("/entry/proof"); 323 | } 324 | ``` 325 | 326 | or in web assembly text: 327 | 328 | ```wat 329 | (module 330 | ;; the imported _check_signature function 331 | (import "wacc" "_push" (func $push (param i32 i32) (result i32))) 332 | 333 | ;; the exported "for_great_justice" function to call 334 | (func $main (export "for_great_justice") (param) (result i32) 335 | ;; push("/entry/") 336 | i32.const 0 337 | i32.const 7 338 | call $push 339 | 340 | ;; push("/entry/proof") 341 | i32.const 7 342 | i32.const 12 343 | call $push 344 | 345 | return 346 | ) 347 | 348 | ;; define the memory to store the string constants in 349 | (memory (export "memory") 1) 350 | 351 | ;; string constant to pass to check_signature 352 | (data (i32.const 0) "/entry/") 353 | (data (i32.const 7) "/entry/proof") 354 | ) 355 | ``` 356 | 357 | In the example given above, the unlock script pushes the value associated with 358 | the `"/entry/"` key-path which is the compact serialized form of the proposed 359 | entry with a NULL `"/entry/proof"` value. In essence, the value associated with 360 | `"/entry/"` is the serialized entry object that was digitally signed; it is the 361 | message associated with the digital signature associated with the 362 | `"/entry/proof"` key-path. NOTE: this assumes a detached signature but it is 363 | also possible to use a combined signature that contains the signed data, 364 | eliminating the need to push the `"/entry/"` value however this unnecessarily 365 | duplicates data. 366 | 367 | ### [Lock Scripts](#lock-scripts) 368 | 369 | Lock scripts are code that compiles to wasm and executed in the [WACC 370 | VM][8]. For historical reasons, each lock script is a wasm module with 371 | a single exported function called "move_every_zig". 372 | 373 | Every entry has a list of key-paths and the associated lock scripts that are 374 | used to validate events with mutations to those parts of the key-value pair 375 | store. Below is an example of what the list of lock scripts looks like: 376 | 377 | ```json 378 | "locks": [ 379 | [ "/", "" ], 380 | [ "/delegated/mike/", ""], 381 | [ "/delegated/walker/", ""], 382 | [ "/delegated/dave/", ""], 383 | ] 384 | ``` 385 | 386 | The [WACC VM][8] execution environment exposes a number of cryptographic 387 | functions to lock and unlock scripts outlined above. To ensure maximum safety, 388 | no lock script has direct access to any of the data in events or the key-value 389 | pair store. Instead, the functions take key-paths as references to data as the 390 | parameters to functions. You've already seen in the examples above how the 391 | `push` function takes a key-path as its argument and the associated value is 392 | pushed onto the parameter stack. 393 | 394 | Each lock script has a key-path that it governs and there may be multiple lock 395 | scripts for each key-path that get executed in the order in which they are 396 | listed in the log event's lock scripts list. If a branch contains 397 | branches/leaves that do not have a lock script associated with them then the 398 | parent branch lock script also governs them and validates any subsequent events 399 | that mutate those parts of the key-value store. 400 | 401 | When a lock script is executed the "context" key-path that is available to the 402 | `branch` function is the longest common key-path in the set of mutation `op` 403 | values in the proposed event. 404 | 405 | #### Calculating the Context Key-Path 406 | 407 | As an example let us assume the proposed event has the following `op` entries: 408 | 409 | ```json 410 | "ops": [ 411 | { "update": [ "/forks/001/foo", { "str": [ "bar" ] } ] }, 412 | { "update": [ "/forks/001/move", { "str": [ "zig" ] } ] }, 413 | ] 414 | ``` 415 | 416 | The "context" key-path is the longest common *branch* key-path in the set of 417 | `op` key-paths. In the example above, the longest common branch key-path is 418 | `"/forks/001/"` so in any lock script that runs to validate this entry, the 419 | `branch` function would concatenate `"/forks/001/"` with the key-path passed 420 | in. For instance, a call to `branch("foo")` would result in the construction of 421 | the `"/forks/001/foo"` key-path. 422 | 423 | Now, let us assume the set of mutation `op` values in the proposed event is 424 | the following: 425 | 426 | ```json 427 | "ops": [ 428 | { "update": [ "/forks/001/foo", { "str": [ "bar" ] } ] }, 429 | { "noop": [ "/forks/" ] }, 430 | { "update": [ "/forks/001/move", { "str": [ "zig" ] } ] }, 431 | ] 432 | ``` 433 | 434 | The longest common branch key-path is `"/forks/"` because of the `noop` 435 | mutation value. This demonstrates the use of the `noop` to "scope" the context 436 | of the proposed events and affect the context key-path for the lock script 437 | execution. NOTE: the `noop` operation is only useful for making the context 438 | key-path closer to the root `"/"` key-path and cannot make it longer. This 439 | effectively elevates the level of proof required to make the proposed event 440 | valid assuming that the closer to the root key-path the context gets, the 441 | closer to the owner—and thus less delegated—the proof capabilities get. 442 | 443 | #### [Lock Script Execution Order](#lock-script-execution-order) 444 | 445 | Here is another example to clarify which lock scripts get executed and in 446 | which order. Assume you have a key-path structure like the following: 447 | 448 | ``` 449 | ─┬─ "/" 450 | ╰─┬─ "tpubkey" 451 | ├─ "pubkey" 452 | ├─ "hash" 453 | ╰─┬─ "delegated/" 454 | ├─┬─ "mike/" 455 | │ ╰─── "endpoint" 456 | ├─┬─ "walker/" 457 | │ ╰─── "peerid" 458 | ╰─┬─ "dave/" 459 | ╰─── "endpoint" 460 | ``` 461 | 462 | And also assume the current entry has the following list of lock scripts 463 | associated with each key-path: 464 | 465 | ```json 466 | [ 467 | [ "/", "" ], 468 | [ "/delegated/mike/", ""], 469 | [ "/delegated/walker/", ""], 470 | [ "/delegated/dave/", ""], 471 | ] 472 | ``` 473 | 474 | If a proposed entry only contains an `op` to `update("/foo")` then the only 475 | lock script that gets executed is the one associated with the `"/"` key-path 476 | because `"/foo"` is in the `"/"` branch. The context key-path in that case is 477 | just `"/"` because that is the longest common key-path in the `op` set. 478 | 479 | If the proposed entry only contains an `op` to 480 | `update("/delegated/mike/endpoint")` then the lock script for `"/"` runs, and if 481 | it fails then the lock script for `"/delegated/mike/"` runs because 482 | `"/delegated/mike/endpoint"` is in the `"/delegated/mike/"` branch. In both cases 483 | the context key-path is `"/delegated/mike/"` since that is the longest common 484 | branch key-path in the `op` set. 485 | 486 | Lock scripts associated with branches closer to the root branch execute first 487 | and if they succeed, no further lock scripts are executed. This allows lock 488 | scripts closer to the root branch to override the lock scripts closer to the 489 | leaves; as it should be. If the provenance log owner wishes to override an 490 | update made to a delegated branch/leaf, their proof takes precedence as long as 491 | it causes a lock script closer to the root branch to succeed. So in this 492 | example, the proposed next entry with proof that satisfies the `"/"` branch 493 | lock script will take precedence over a proposed next entry with a proof that 494 | only satisfies the `"/delegated/mike/"` lock script. 495 | 496 | #### [Example Lock Script](#example-lock-script) 497 | 498 | Assume that applying the mutation ops from foot (i.e. first event) to head 499 | (i.e. most recent) creates the following key-value store state: 500 | 501 | ``` 502 | ─┬─ "/" 503 | ╰─── "pubkey" 504 | ``` 505 | 506 | A lock script may reference the value of the public key like so: 507 | 508 | ```rust 509 | #[no_mangle] 510 | pub fn move_every_zig() -> bool { 511 | // check the signature using the data on the stack and the pubkey 512 | check_signature("/pubkey") 513 | } 514 | ``` 515 | 516 | or in web assembly text: 517 | 518 | ```wat 519 | (module 520 | ;; the imported _check_signature function 521 | (import "wacc" "_check_signature" (func $check_signature (param i32 i32) (result i32))) 522 | 523 | ;; the exported "move_every_zig" function to call 524 | (func $main (export "move_every_zig") (param) (result i32) 525 | i32.const 0 526 | i32.const 7 527 | call $check_signature 528 | return 529 | ) 530 | 531 | ;; define the memory to store the string constants in 532 | (memory (export "memory") 1) 533 | 534 | ;; string constant to pass to check_signature 535 | (data (i32.const 0) "/pubkey") 536 | ) 537 | ``` 538 | 539 | Since lock scripts are associated with a key-path which specifies when/if it is 540 | executed, the above lock script will always reference the public key associated 541 | with the `"/pubkey"` key-path regardless of which key-path it is associated 542 | with because it uses an absolute key-path. The above lock script could also be 543 | rewritten to the following: 544 | 545 | ```rust 546 | #[no_mangle] 547 | pub fn move_every_zig() -> bool { 548 | // check the signature using the pubkey in the branch context 549 | check_signature(branch("pubkey")) 550 | } 551 | ``` 552 | 553 | This lock script could be associated with the `"/"` key-path or any other 554 | key-path such as `"/foo/"`. In the latter case, the call to `check_signature` 555 | would be passed the key-path `/foo/pubkey`. This is handy for use in delegation 556 | which is explained further down in this document. 557 | 558 | The lock script above executes the `check_signature` function passing it the 559 | key-path referencing the public key to use. The function first peeks at the 560 | value on top of the stack to see if there is a [Multisig][6] encoded 561 | digital signature on the top of the stack and checks that it is the same kind 562 | of signature as the public key. If those match, then the function expects the 563 | stack to have the digital signature on top with the message just below that. It 564 | checks the signature, and if it is valid, it pops both the signature and 565 | message off of the parameter stack and it pushes the `SUCCESS` marker onto the 566 | return stack. 567 | 568 | Lock scripts may themselves have multiple checks that are combined with logical 569 | "and" and "or" operations. In those cases, precedence is established by the 570 | "check counter". The check counter starts at zero and is incremented every time 571 | a `check_*` function is called and fails. When two competing proposed entries 572 | satisfy the same lock script, the one with the _lowest_ check counter value 573 | takes precedence. 574 | 575 | Below is an example of the use of "and" and "or" predicates to construct a lock 576 | script that enforces the proposed entry proof is either a valid threshold 577 | signature or pubkey signature or preimage proof. 578 | 579 | ```rust 580 | #[no_mangle] 581 | pub fn move_every_zig() -> bool { 582 | // then check a possible threshold sig... 583 | check_signature("/tpubkey") || // check_count++ 584 | // then check a possible pubkey sig... 585 | check_signature("/pubkey") || // check_count++ 586 | // then the pre-image proof... 587 | check_preimage("/hash") 588 | } 589 | ``` 590 | 591 | Here, there are three `check_*` function calls. To enforce precedence in the 592 | checks, every time a `check_*` function is executed and it fails the check 593 | counter is incremented in the WACC VM. If the lock script succeeds, the check 594 | counter value is pushed onto the stack as the payload of the 595 | `SUCCESS(check_counter)` marker. 596 | 597 | Because logical operations in Rust short circuit, in the example lock script 598 | above, the only time the `check_preimage` function will execute is if the 599 | `check_signature("/pubkey")` fails. The only time the 600 | `check_signature("/pubkey")` function will execute is if the 601 | `check_signature("/tpubkey")` function fails. If either `check_signature` 602 | functions fail, their only side effect is to increment the check counter. Then 603 | if the `check_preimage` succeeds, the marker left on the stack will be 604 | `SUCCESS(2)`. If the `check_signature("/pubkey")` succeeds, the marker left on 605 | the stack will be `SUCCESS(1)`. If the `check_signature("/tpubkey")` succeeds, 606 | the marker left on the stack will be `SUCCESS(0)`. If there are two competing 607 | entries and one provides a valid signature and the other provides a valid 608 | preimage, the one with the valid signature takes precedence over the one with 609 | the valid preimage because the check counter is lower for the entry with the 610 | valid signature. 611 | 612 | In the case where competing entries satisfy the same lock script with the same 613 | check count, the entry with the context key-path closest to the `"/"` branch 614 | takes precedence. The solution for resolving a tie is for entry creators to 615 | generate proof with a lower check count or proof that satisfies a lock script 616 | with higher precedence. Single clause lock scripts are a bad idea for this 617 | reason; they leave the door open for unresolvable ties in precedence. 618 | 619 | #### [Delegation](#delegation) 620 | 621 | The lock script mechanism is designed to support delegation. By adding lock 622 | scripts associated with branches/leaves that can be satisfied by proofs 623 | generated by 3rd parties, the owner of a log is delegating the management of 624 | those branches/leaves to those people/services. The precedence and check 625 | counter mechanism is designed to resolve any conflicts between competing 626 | entries, giving a hierarchy of who can override whom when updating a log. 627 | 628 | In the example from above, let us assume we have the following: 629 | 630 | ``` 631 | ─┬─ "/" 632 | ╰─┬─ "tpubkey" 633 | ├─ "pubkey" 634 | ├─ "hash" 635 | ╰─┬─ "delegated/" 636 | ├─┬─ "mike/" 637 | │ ├─── "pubkey" 638 | │ ╰─── "endpoint" 639 | ╰─┬─ "walker/" 640 | ├─── "pubkey" 641 | ╰─── "peerid" 642 | 643 | ``` 644 | 645 | And also assume the current entry has the following list of lock scripts 646 | associated with each key-path: 647 | 648 | ```json 649 | [ 650 | [ "/", "" ], 651 | [ "/delegated/", ""], 652 | ] 653 | ``` 654 | 655 | Taking advantage of the `branch` function, we only need a single lock script to 656 | govern all of the `"/delegated/"` branch: 657 | 658 | ```rust 659 | #[no_mangle] 660 | fn lock() -> bool { 661 | check_signature(branch("pubkey")) 662 | } 663 | ``` 664 | 665 | If Mike wished to update the value associated with the 666 | `"/delegated/mike/endpoint"`, he would create a new Entry with a single `op`: 667 | 668 | ```json 669 | "ops": [ 670 | { "update": [ "/delegated/mike/endpoint", { "str": [ "https://cryptid.tech" ] } ] }, 671 | ] 672 | ``` 673 | 674 | When validating his proposed entry for my log, first the `"/"` lock script 675 | would run with the branch context of `"/"` and it would fail because Mike does 676 | not possess the capability of creating proof (e.g. a digital signature) over 677 | his entry that validates with the `"/"` lock script. After that fails, the lock 678 | script for the `"/delegated/"` branch executes with the `"/delegated/mike/"` 679 | branch context. If Mike's proposed entry is digitally signed with the secret 680 | key that is associated with the public key value stored under 681 | `"/delegated/mike/pubkey"` then the entry validates and is accepted. 682 | 683 | If Walker wanted to update the value associated with 684 | `"/delegated/walker/peerid"` then he would also create a new proposed event and 685 | digitally sign it with the key pair associated with the public key stored under 686 | `"/delegate/walker/pubkey"` and the same `"/delegated/"` lock script works for 687 | him because the context branch for validating his event is 688 | `"/delegated/walker/"`. 689 | 690 | #### [Forced recovery using precedence](#forced-recovery-using-precedence) 691 | 692 | The purpose of the precedence is to create lock scripts with the hardest to 693 | hack and most secure checks as the top precedences with less secure checks 694 | having lower precedence. Today, the most secure kind of check is a threshold 695 | signature generated through the cooperation of multiple independent 696 | people/services using a quantum-resistant one-time signature schemes such as a 697 | threshold Lamport signature. If the lock scripts have a threshold check that 698 | takes precedence over a public key signature that in turn takes precedence over 699 | a preimage check, then if a password (i.e. preimage) is compromised and the 700 | attacker creates a new entry using a preimage proof, the rightful owner of the 701 | log can then create a competing entry with the same sequence number using a 702 | signature proof. The log "protocol" demands that the higher precedence entry 703 | to be chosen as the next valid entry and not the one created by the attacker 704 | who guessed your password. 705 | 706 | Most importantly, if a public key pair is compromised and an attacker attempts 707 | a takeover by creating an entry using a signature proof, the rightful owner can 708 | then contact their friends—or a threshold recovery service—and have them create 709 | a threshold signature over a new entry that takes precedence over the 710 | attacker's entry. The new entry with the threshold signature can then contain a 711 | key rotation and key revocation mutation for the virtual key-value store 712 | marking the compromised key as revoked as well as establishing a new valid 713 | public keypair all without breaking the chain of trust in the log. 714 | 715 | You can think of this recovery scenario as a digital "social recovery" where 716 | your friends collaborate to generate the threshold signature to recover your 717 | control over your log. This can be applied in a number of real-world scenarios 718 | such as board control over a corporation's identity log, heirs collaborating 719 | with the deceased's counsel to take over the deceased's logs, or even parents 720 | co-signing with their minor children to update the children's log for some 721 | reason. 722 | 723 | One especially useful application is empowering maintainers of a Git repository 724 | with full identity and access management (IAM) capabilities. By requiring that 725 | the `"/"` branch lock script have a `check_signature("/maintainers")` threshold 726 | signature check as the highest precedence, then the threshold group associated 727 | with the "maintainers" threshold public key has full control over every 728 | key-value pair in the provenance log. Maintainers can force rotate to a new 729 | signing key for a contributor to recover to a known-good key. They can also 730 | force rotate a contributor's signing key to NULL and remove their ability to 731 | contribute to the repository. They can delegate branches and leaves in 732 | contributors' provenance logs to enable a repository-wide service to update the 733 | contributors' logs as needed. In short, a design like this gives the 734 | maintainers of the repository full control over the IAM for contributors to the 735 | repository all without a centralized server/service such as Github or Gitlab. 736 | 737 | ## [Forking Provenance Logs](#forking-provenance-logs) 738 | 739 | It is possible to fork provenance logs by into any number of child logs. Child 740 | logs always start with an entry that has a sequence number of `0` and a prev 741 | CID that points at the entry in the parent log from which the child log is 742 | forked. The lock script in the parent log entry is used as the lock script to 743 | validate the first entry in the child log. By convention, along with the prev 744 | CID pointing to the parent, the first entry in the child log must also contain 745 | a mutation `op` that updates the VLAD of the parent to the `"/parent/"` 746 | key-path. The parent VLAD is useful for when the parent log moves from one 747 | content addressable storage to another. As long as a VLAD to CID mapping record 748 | exists somewhere, then the CID can be resolved to the correct entry in the 749 | parent log. 750 | 751 | ### [Example Forking Using Delegation](#example-forking-using-delegation) 752 | 753 | Typically, the parent log maintains information about its child forks under the 754 | `"/forks/"` branch. Using the delegation and branch mechanisms, it is trivial 755 | to manage forking using a separate lock script assigned to the `"/forks/"` 756 | key-path: 757 | 758 | ```rust 759 | #[no_mangle] 760 | pub fn move_every_zig() -> bool { 761 | // forking the parent be done by whomever can sign with "/forks/pubkey" 762 | check_signature(branch("pubkey")) || 763 | 764 | // check the validity of the first entry of the child log 765 | (check_eq(branch("vlad")) && check_signature(branch("pubkey"))) 766 | } 767 | ``` 768 | 769 | The process of forking a provenance log takes two steps. The first step is 770 | recording the information about the child log in the parent log and the 771 | second step is publishing the child log. By convention, each child log's 772 | information is stored under its own branch under `"/forks/"`. The child's 773 | branch name is arbitrary but, again by convention, under its branch there is a 774 | `"vlad"` leaf with the child's VLAD, a `"pubkey"` leaf with the child's first 775 | advertised pubkey that was also used to sign its first entry and the CID in its 776 | VLAD. 777 | 778 | When creating a child log fork, we create a new entry in the parent log with 779 | the following mutation `op` values: 780 | 781 | ```json 782 | "ops": [ 783 | { "noop": [ "/forks/" ] }, 784 | { "update": [ "/forks/child1/vlad", { "bin": [ ] } ] }, 785 | { "update": [ "/forks/child1/pubkey", { "bin": [ ] } ] }, 786 | ] 787 | ``` 788 | 789 | This new entry is signed using the key pair associated with `"/forks/pubkey"`. 790 | The `noop` mutation is used to set the context key-path to `"/forks/"` by 791 | including it the `op` mutation set of key-paths. It is the longest common 792 | key-path and thus becomes the context key-path for the `branch` function when 793 | running it to validate the new event in the parent log. 794 | 795 | When the lock script associated with `"/forks/"` executes, the first 796 | `check_signature` call passes and the lock script exits with `SUCCESS(0)` on 797 | the return stack. 798 | 799 | Then the first entry of the child log is created with the child VLAD as its 800 | VLAD, the prev CID set to the CID of the parent event we just created. It must 801 | include an `op` mutation to record the parent VLAD in the 802 | `"/forks/child1/parent"` leaf of the child's key-value store: 803 | 804 | ```json 805 | "ops": [ 806 | { "update": [ "/forks/child1/parent", { "bin": [ ] } ] }, 807 | { "update": [ "/forks/child1/pubkey", { "bin": [ ] } ] }, 808 | ] 809 | ``` 810 | 811 | The additional `"/forks/child1/pubkey"` in the child log records the signing 812 | key in the child in such a way that it doesn't disrupt the delegation and 813 | forking lock script execution but allows for the child log to have its own 814 | lock scripts and validate the next entry in the log. The only rule is that the 815 | child's initial entry can only have `op` mutations under the `"/forks/child1/"` 816 | key-path to ensure that the lock script from the parent executes correctly and 817 | validates the child's first entry. 818 | 819 | The unlock script of the first entry in the child log must be like the 820 | following: 821 | 822 | ```rust 823 | #[no_mangle] 824 | pub fn unlock() { 825 | // push the entry values 826 | push("/entry/"); 827 | 828 | // push the signature created using the /forks/child1/pubkey keypair 829 | push("/entry/proof"); 830 | 831 | // push the vlad 832 | push("/entry/vlad"); 833 | } 834 | ``` 835 | 836 | When validating the first entry in the first child log, the unlock script 837 | pushes the serialized entry, the ephemeral signature over the entry as well as 838 | the log's VLAD value. This puts the parameter stack into the following state: 839 | 840 | ``` 841 | ┌──────────────────┐ 842 | top → │ <"/entry/vlad"> │ ← child vlad 843 | ├──────────────────┤ 844 | │ <"/entry/proof"> │ ← digital signature 845 | ├──────────────────┤ 846 | │ <"/entry/"> │ ← signed message 847 | ├──────────────────┤ 848 | │ ┆ │ 849 | ┆ ┆ 850 | ``` 851 | 852 | The first entry of the child log must be signed using the key pair associated 853 | with the pubkey recorded in the parent log under the `"/forks/child1/pubkey"` 854 | leaf. When the first entry is validated, the lock script from the parent 855 | associated with the parent's `"/forks/"` key-path will execute because the 856 | first entry in the child log only mutates key-paths under `"/forks/"`. The 857 | context path this time will be `"/forks/child1/"` since that is the longest 858 | common branch key-path in the `op` mutation set in the child's first entry. 859 | 860 | When the parent log entry's lock script executes, the following steps are 861 | executed: 862 | 863 | 1. The `check_signature(branch("pubkey"))` fails because it sees a VLAD on top 864 | of the stack and not a signature. 865 | 2. The `check_eq(branch("vlad"))` succeeds because the `<"/forks/child1/vlad">` 866 | value in the parent matches the "VLAD" value pushed on the stack by the 867 | child unlock script. It pops the VLAD parameter off of the parameter stack. 868 | 3. The `check_signature(branch("pubkey"))` succeeds because the 869 | `<"/forks/child1/pubkey">` public key in the parent validates the signature 870 | `<"/entry/proof">` and message `<"/entry/">` values pushed on the stack by the 871 | child unlock script. It pops both off of the parameter stack. 872 | 4. A `SUCCESS(1)` marker is pushed onto the results stack because the initial 873 | `check_signature` function failed, incrementing the check counter once. 874 | 875 | The initial entry in the child log should also set up it's own lock scripts 876 | for governing its key-value store. The data recorded under the 877 | `"/forks/child1/"` branch in the child's key-value store can be used with lock 878 | scripts in the child to validate the second entry in the child provenance log 879 | which can then remove the `"/forks/child1/"` branch if so desired. 880 | 881 | [0]: https://cryptid.tech 882 | [1]: https://github.com/cryptidtech/provenance-specifications/ 883 | [2]: https://github.com/multiformats/multiformats 884 | [3]: https://github.com/CommunitySpecification/1.0 885 | [4]: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki 886 | [5]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/nonce.md 887 | [6]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multisig.md 888 | [7]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/multikey.md 889 | [8]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/wacc.md 890 | [9]: https://github.com/cryptidtech/provenance-specifications/blob/main/specifications/vlad.md 891 | [10]: https://github.com/cryptidtech/multihash.git 892 | 893 | [LIPMAA]: https://github.com/AljoschaMeyer/bamboo/blob/master/README.md#links-and-entry-verification --------------------------------------------------------------------------------