Skip to content

Commit

Permalink
feat(rust/signed-doc): Reference implementation of the Catalyst signe…
Browse files Browse the repository at this point in the history
…d 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 <[email protected]>
  • Loading branch information
Mr-Leshiy and stevenj authored Dec 10, 2024
1 parent e5a2fd1 commit 424cc0a
Show file tree
Hide file tree
Showing 12 changed files with 737 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ chrono
cids
ciphertext
ciphertexts
Coap
codegen
codepoints
coti
Expand Down Expand Up @@ -89,6 +90,7 @@ fstat
fstatat
futimens
genhtml
genpkey
GETFL
getres
giantstep
Expand Down Expand Up @@ -169,6 +171,7 @@ openat
opentelemetry
outlen
Outparam
outpubkey
parameterises
permissioned
permissionless
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/semantic_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
rust/immutable-ledger
rust/vote-tx-v1
rust/vote-tx-v2
rust/signed-doc
rust/cbork
rust/hermes-ipfs
rust/rbac-registration
Expand Down
1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ members = [
"immutable-ledger",
"vote-tx-v1",
"vote-tx-v2",
"signed_doc",
"rbac-registration",
]

Expand Down
3 changes: 2 additions & 1 deletion rust/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ COPY_SRC:
catalyst-voting vote-tx-v1 vote-tx-v2 \
cbork cbork-abnf-parser cbork-cddl-parser \
hermes-ipfs \
signed_doc \
rbac-registration \
immutable-ledger .

Expand Down Expand Up @@ -55,7 +56,7 @@ build:
--args1="--libs=c509-certificate --libs=cardano-chain-follower --libs=hermes-ipfs" \
--args2="--libs=cbork-cddl-parser --libs=cbork-abnf-parser" \
--args3="--libs=catalyst-voting --libs=vote-tx-v1 --libs=vote-tx-v2" \
--args4="--bins=cbork/cbork --libs=rbac-registration" \
--args4="--bins=cbork/cbork --libs=rbac-registration --libs=signed_doc" \
--args5="--cov_report=$HOME/build/coverage-report.info" \
--output="release/[^\./]+" \
--junit="cat-libs.junit-report.xml" \
Expand Down
2 changes: 0 additions & 2 deletions rust/c509-certificate/src/signing.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! ED25519 public and private key implementation.
// cspell: words outpubkey genpkey

use std::{fmt::Display, path::Path, str::FromStr};

use ed25519_dalek::{
Expand Down
25 changes: 25 additions & 0 deletions rust/signed_doc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "signed_doc"
version = "0.1.0"
edition.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true

[lints]
workspace = true

[dependencies]

[dev-dependencies]
clap = { version = "4.5.19", features = ["derive", "env"] }
anyhow = "1.0.89"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0"
jsonschema = "0.18.0"
coset = "0.3.7"
brotli = "7.0.0"
ed25519-dalek = { version = "2.1.1", features = ["pem"] }
uuid = { version = "1.10.0", features = ["v4", "serde"] }
ulid = { version = "1.1.3", features = ["serde"] }
133 changes: 133 additions & 0 deletions rust/signed_doc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<!-- cspell: words collabs -->

# Catalyst signed document

Catalyst signed document is [COSE] based document structure,
particularly `COSE Signed Data Object` [COSE] type.

## Structure

This document structure is fully inherits an original [COSE] design and specifies the details
of different [COSE] header's fields.

### Protected header

The [COSE] standard defines two types of headers: `protected` and `unprotected`.
Catalyst signed document specifies the following `protected` header fields,
which **must** be present (most of the fields originally defined by this
[spec](https://input-output-hk.github.io/catalyst-voices/architecture/08_concepts/signed_document_metadata/metadata/)):

* `alg`: `EdDSA`
(this parameter is used to indicate the algorithm used for the security processing,
in this particular case `ed25119` signature algorithm is used).
* `content type`: `application/json`
(this parameter is used to indicate the content type of the payload data,
in this particular case `JSON` format is used).
* `content encoding` (CBOR type `text`): `br` CBOR type `text`
(this parameter is used to indicate the content encodings algorithm of the payload data,
in this particular case [brotli] compression data format is used).
* `type`: CBOR encoded UUID.
* `id`: CBOR encoded ULID.
* `ver`: CBOR encoded ULID.
* `ref`: CBOR encoded ULID or two elements array of ULIDs (optional).
* `template`: CBOR encoded ULID or two elements array of ULIDs (optional).
* `reply`: CBOR encoded ULID or two elements array of ULIDs (optional).
* `section`: CBOR encoded string (optional).
* `collabs`: CBOR encoded array of any CBOR types (optional).

Precise CDDL definition

```cddl
; All encoders/decoders of this specification must follow deterministic cbor encoding rules
; https://datatracker.ietf.org/doc/html/draft-ietf-cbor-cde-06
protected_header = {
1 => -8, ; "alg": EdDSA
3 => 30, ; "content type": Json
"content encoding" => "br", ; payload content encoding, brotli compression
"type" => UUID,
"id" => ULID,
"ver" => ULID,
? "ref" => reference_type,
? "template" => reference_type,
? "reply" => reference_type,
? "section" => text,
? "collabs" => [+any],
}
UUID = #6.37(bytes)
ULID = #6.32780(bytes)
reference_type = ULID / [ULID, ULID] ; either ULID or [ULID, ULID]
```

### COSE payload

The [COSE] signature payload, as mentioned earlier,
the content type of the [COSE] signature payload is JSON, [brotli] compressed.
Which stores an actual document data which should follow to some schema.

### Signature protected header

As it mentioned earlier, Catalyst signed document utilizes `COSE Signed Data Object` format,
which allows to provide multi-signature functionality.
In that regard,
each Catalyst signed document [COSE] signature **must** include the following protected header field:

`protected`:

* `kid`: CBOR encoded `bytes` type.

Precise CDDL definition

```cddl
; All encoders/decoders of this specification must follow deterministic cbor encoding rules
; https://datatracker.ietf.org/doc/html/draft-ietf-cbor-cde-06
signature_protected_header = {
4 => bytes ; "kid"
}
```

## Example

Generate a `ed25519` private and public keys

```shell
openssl genpkey -algorithm=ED25519 -out=private.pem -outpubkey=public.pem
```

Prepare non-signed document,
`meta.json` file should follow the [`meta.schema.json`](./meta.schema.json).

```shell
cargo run -p signed_doc --example mk_signed_doc build
signed_doc/doc.json signed_doc/schema.json signed_doc/doc.cose signed_doc/meta.json
```

Sign document

```shell
cargo run -p signed_doc --example mk_signed_doc sign private.pem signed_doc/doc.cose kid_1
```

Verify document

```shell
cargo run -p signed_doc --example mk_signed_doc verify
public.pem signed_doc/doc.cose signed_doc/schema.json
```

Catalyst signed document CBOR bytes example

```cbor
845861A6012703183270636F6E74656E7420656E636F64696E676262726474797065D825500CE8AB3892584FBCA62E7F
AA6E58318F626964D9800C500193929C1D227F1977FED19443841F0B63766572D9800C500193929C1D227F1977FED194
43841F0BA0584E1B6D00209C05762C9B4E1EAC3DCA9286B50888CBDE8E99A2EB532C3A0D83D6F6462707ECDFF7F9B74B
8904098479CA4221337F7DB97FDA25AFCC10ECB75722C91A485AAC1158BA6F90619221066C828347A104446B696431A0
584090DF51433D97728ACF3851C5D3CA2908F76589EA925AF434C5619234E4B1BA7B12A124EA79503562B33214EBC730
C9837E1CA909BB8163D7904B09C3FD6A5B0B8347A104446B696432A05840AB318FEF3FF46E69E760540B0B44E9E8A51A
84F23EC8A870ECDEBF9AD98EBB8212EBE5EA5FDBA87C98DF8DF259BE7873FE8B9EB54CC6558337B5C95D90CC3504
```

[COSE]: https://datatracker.ietf.org/doc/html/rfc9052
[brotli]: https://datatracker.ietf.org/doc/html/rfc7932
Loading

0 comments on commit 424cc0a

Please sign in to comment.