Skip to content

Commit 424cc0a

Browse files
Mr-Leshiystevenj
andauthored
feat(rust/signed-doc): Reference implementation of the Catalyst signed documents with the design doc (#98)
* add new signed_doc rust crate * add document loading and validating * wip * add verification functionality * fix * add README.md * add new metadata argument * wip * update README.md * update document * add missing validation * update README.md * fix spelling and mk lints * cleanup code * add CDDL definitions * fix * fix * fix * fix --------- Co-authored-by: Steven Johnson <stevenj@users.noreply.github.com>
1 parent e5a2fd1 commit 424cc0a

File tree

12 files changed

+737
-7
lines changed

12 files changed

+737
-7
lines changed

.config/dictionaries/project.dic

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ chrono
3939
cids
4040
ciphertext
4141
ciphertexts
42+
Coap
4243
codegen
4344
codepoints
4445
coti
@@ -89,6 +90,7 @@ fstat
8990
fstatat
9091
futimens
9192
genhtml
93+
genpkey
9294
GETFL
9395
getres
9496
giantstep
@@ -169,6 +171,7 @@ openat
169171
opentelemetry
170172
outlen
171173
Outparam
174+
outpubkey
172175
parameterises
173176
permissioned
174177
permissionless

.github/workflows/semantic_pull_request.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
rust/immutable-ledger
2323
rust/vote-tx-v1
2424
rust/vote-tx-v2
25+
rust/signed-doc
2526
rust/cbork
2627
rust/hermes-ipfs
2728
rust/rbac-registration

rust/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ members = [
1212
"immutable-ledger",
1313
"vote-tx-v1",
1414
"vote-tx-v2",
15+
"signed_doc",
1516
"rbac-registration",
1617
]
1718

rust/Earthfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ COPY_SRC:
1313
catalyst-voting vote-tx-v1 vote-tx-v2 \
1414
cbork cbork-abnf-parser cbork-cddl-parser \
1515
hermes-ipfs \
16+
signed_doc \
1617
rbac-registration \
1718
immutable-ledger .
1819

@@ -55,7 +56,7 @@ build:
5556
--args1="--libs=c509-certificate --libs=cardano-chain-follower --libs=hermes-ipfs" \
5657
--args2="--libs=cbork-cddl-parser --libs=cbork-abnf-parser" \
5758
--args3="--libs=catalyst-voting --libs=vote-tx-v1 --libs=vote-tx-v2" \
58-
--args4="--bins=cbork/cbork --libs=rbac-registration" \
59+
--args4="--bins=cbork/cbork --libs=rbac-registration --libs=signed_doc" \
5960
--args5="--cov_report=$HOME/build/coverage-report.info" \
6061
--output="release/[^\./]+" \
6162
--junit="cat-libs.junit-report.xml" \

rust/c509-certificate/src/signing.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//! ED25519 public and private key implementation.
22
3-
// cspell: words outpubkey genpkey
4-
53
use std::{fmt::Display, path::Path, str::FromStr};
64

75
use ed25519_dalek::{

rust/signed_doc/Cargo.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "signed_doc"
3+
version = "0.1.0"
4+
edition.workspace = true
5+
authors.workspace = true
6+
homepage.workspace = true
7+
repository.workspace = true
8+
license.workspace = true
9+
10+
[lints]
11+
workspace = true
12+
13+
[dependencies]
14+
15+
[dev-dependencies]
16+
clap = { version = "4.5.19", features = ["derive", "env"] }
17+
anyhow = "1.0.89"
18+
serde = { version = "1.0.210", features = ["derive"] }
19+
serde_json = "1.0"
20+
jsonschema = "0.18.0"
21+
coset = "0.3.7"
22+
brotli = "7.0.0"
23+
ed25519-dalek = { version = "2.1.1", features = ["pem"] }
24+
uuid = { version = "1.10.0", features = ["v4", "serde"] }
25+
ulid = { version = "1.1.3", features = ["serde"] }

rust/signed_doc/README.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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

Comments
 (0)