|
| 1 | +<!-- cspell: words collabs --> |
| 2 | + |
| 3 | +# Catalyst signed document |
| 4 | + |
| 5 | +Catalyst signed document is [COSE] based document structure, |
| 6 | +particularly `COSE Signed Data Object` [COSE] type. |
| 7 | + |
| 8 | +## Structure |
| 9 | + |
| 10 | +This document structure is fully inherits an original [COSE] design and specifies the details |
| 11 | +of different [COSE] header's fields. |
| 12 | + |
| 13 | +### Protected header |
| 14 | + |
| 15 | +The [COSE] standard defines two types of headers: `protected` and `unprotected`. |
| 16 | +Catalyst signed document specifies the following `protected` header fields, |
| 17 | +which **must** be present (most of the fields originally defined by this |
| 18 | +[spec](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/signed_document_metadata/metadata/)): |
| 19 | + |
| 20 | +* `alg`: `EdDSA` |
| 21 | + (this parameter is used to indicate the algorithm used for the security processing, |
| 22 | + in this particular case `ed25119` signature algorithm is used). |
| 23 | +* `content type`: `application/json` |
| 24 | + (this parameter is used to indicate the content type of the payload data, |
| 25 | + in this particular case `JSON` format is used). |
| 26 | +* `content encoding` (CBOR type `text`): `br` CBOR type `text` |
| 27 | + (this parameter is used to indicate the content encodings algorithm of the payload data, |
| 28 | + in this particular case [brotli] compression data format is used). |
| 29 | +* `type`: CBOR encoded UUID. |
| 30 | +* `id`: CBOR encoded ULID. |
| 31 | +* `ver`: CBOR encoded ULID. |
| 32 | +* `ref`: CBOR encoded ULID or two elements array of ULIDs (optional). |
| 33 | +* `template`: CBOR encoded ULID or two elements array of ULIDs (optional). |
| 34 | +* `reply`: CBOR encoded ULID or two elements array of ULIDs (optional). |
| 35 | +* `section`: CBOR encoded string (optional). |
| 36 | +* `collabs`: CBOR encoded array of any CBOR types (optional). |
| 37 | + |
| 38 | +Precise CDDL definition |
| 39 | + |
| 40 | +```cddl |
| 41 | +; All encoders/decoders of this specification must follow deterministic cbor encoding rules |
| 42 | +; https://datatracker.ietf.org/doc/html/draft-ietf-cbor-cde-06 |
| 43 | +
|
| 44 | +protected_header = { |
| 45 | + 1 => -8, ; "alg": EdDSA |
| 46 | + 3 => 30, ; "content type": Json |
| 47 | + "content encoding" => "br", ; payload content encoding, brotli compression |
| 48 | + "type" => UUID, |
| 49 | + "id" => ULID, |
| 50 | + "ver" => ULID, |
| 51 | + ? "ref" => reference_type, |
| 52 | + ? "template" => reference_type, |
| 53 | + ? "reply" => reference_type, |
| 54 | + ? "section" => text, |
| 55 | + ? "collabs" => [+any], |
| 56 | +} |
| 57 | +
|
| 58 | +UUID = #6.37(bytes) |
| 59 | +ULID = #6.32780(bytes) |
| 60 | +reference_type = ULID / [ULID, ULID] ; either ULID or [ULID, ULID] |
| 61 | +``` |
| 62 | + |
| 63 | +### COSE payload |
| 64 | + |
| 65 | +The [COSE] signature payload, as mentioned earlier, |
| 66 | +the content type of the [COSE] signature payload is JSON, [brotli] compressed. |
| 67 | +Which stores an actual document data which should follow to some schema. |
| 68 | + |
| 69 | +### Signature protected header |
| 70 | + |
| 71 | +As it mentioned earlier, Catalyst signed document utilizes `COSE Signed Data Object` format, |
| 72 | +which allows to provide multi-signature functionality. |
| 73 | +In that regard, |
| 74 | +each Catalyst signed document [COSE] signature **must** include the following protected header field: |
| 75 | + |
| 76 | +`protected`: |
| 77 | + |
| 78 | +* `kid`: CBOR encoded `bytes` type. |
| 79 | + |
| 80 | +Precise CDDL definition |
| 81 | + |
| 82 | +```cddl |
| 83 | +; All encoders/decoders of this specification must follow deterministic cbor encoding rules |
| 84 | +; https://datatracker.ietf.org/doc/html/draft-ietf-cbor-cde-06 |
| 85 | +
|
| 86 | +signature_protected_header = { |
| 87 | + 4 => bytes ; "kid" |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +## Example |
| 92 | + |
| 93 | +Generate a `ed25519` private and public keys |
| 94 | + |
| 95 | +```shell |
| 96 | +openssl genpkey -algorithm=ED25519 -out=private.pem -outpubkey=public.pem |
| 97 | +``` |
| 98 | + |
| 99 | +Prepare non-signed document, |
| 100 | +`meta.json` file should follow the [`meta.schema.json`](./meta.schema.json). |
| 101 | + |
| 102 | +```shell |
| 103 | +cargo run -p signed_doc --example mk_signed_doc build |
| 104 | +signed_doc/doc.json signed_doc/schema.json signed_doc/doc.cose signed_doc/meta.json |
| 105 | +``` |
| 106 | + |
| 107 | +Sign document |
| 108 | + |
| 109 | +```shell |
| 110 | +cargo run -p signed_doc --example mk_signed_doc sign private.pem signed_doc/doc.cose kid_1 |
| 111 | +``` |
| 112 | + |
| 113 | +Verify document |
| 114 | + |
| 115 | +```shell |
| 116 | +cargo run -p signed_doc --example mk_signed_doc verify |
| 117 | +public.pem signed_doc/doc.cose signed_doc/schema.json |
| 118 | +``` |
| 119 | + |
| 120 | +Catalyst signed document CBOR bytes example |
| 121 | + |
| 122 | +```cbor |
| 123 | +845861A6012703183270636F6E74656E7420656E636F64696E676262726474797065D825500CE8AB3892584FBCA62E7F |
| 124 | +AA6E58318F626964D9800C500193929C1D227F1977FED19443841F0B63766572D9800C500193929C1D227F1977FED194 |
| 125 | +43841F0BA0584E1B6D00209C05762C9B4E1EAC3DCA9286B50888CBDE8E99A2EB532C3A0D83D6F6462707ECDFF7F9B74B |
| 126 | +8904098479CA4221337F7DB97FDA25AFCC10ECB75722C91A485AAC1158BA6F90619221066C828347A104446B696431A0 |
| 127 | +584090DF51433D97728ACF3851C5D3CA2908F76589EA925AF434C5619234E4B1BA7B12A124EA79503562B33214EBC730 |
| 128 | +C9837E1CA909BB8163D7904B09C3FD6A5B0B8347A104446B696432A05840AB318FEF3FF46E69E760540B0B44E9E8A51A |
| 129 | +84F23EC8A870ECDEBF9AD98EBB8212EBE5EA5FDBA87C98DF8DF259BE7873FE8B9EB54CC6558337B5C95D90CC3504 |
| 130 | +``` |
| 131 | + |
| 132 | +[COSE]: https://datatracker.ietf.org/doc/html/rfc9052 |
| 133 | +[brotli]: https://datatracker.ietf.org/doc/html/rfc7932 |
0 commit comments