Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signature payload format v1 #175

Merged
merged 15 commits into from
Nov 19, 2024
Prev Previous commit
Next Next commit
start updating the spec
Geal committed Nov 11, 2024
commit 043674bac8554c592e1ff1aa63c26dd24277e09d
52 changes: 48 additions & 4 deletions SPECIFICATIONS.md
Original file line number Diff line number Diff line change
@@ -692,6 +692,7 @@ message SignedBlock {
required PublicKey nextKey = 2;
required bytes signature = 3;
optional ExternalSignature externalSignature = 4;
optional uint32 version = 5;
}

message ExternalSignature {
@@ -722,7 +723,8 @@ for signature verification.

Each block contains a serialized byte array of the Datalog data (`block`),
the next public key (`nextKey`) and the signature of that block and key
by the previous key.
by the previous key. The `version` field indicates the version of the signature
payload format.

The `proof` field contains either the private key corresponding to the
public key in the last block (attenuable tokens) or a signature of the last
@@ -780,13 +782,52 @@ corresponding to the last public key, to sign a new block and attenuate the
token, or a signature of the last block by the last private key, to seal the
token.

#### Signed payload generation

The data covered by the signature algorithm depends on the `version` field of
the `SignedBlock` message. If the field is absent, it defaults to version 0.

##### Version 0 (deprecated)

To sign the block at index `n`, we would have:
- `data_n`: the serialized Datalog
- `pk_n+1`: the next public key
- `alg_n+1`: the little endian representation of the signature algorithm for `pk_n+1`
- `external_sig_n`: te optional external signature of the block
Geal marked this conversation as resolved.
Show resolved Hide resolved

if `external_sig_n` is present, the signed payload format, thereafter referred as "block signature payload v0", would be the concatenation of:
- `data_n`
- `external_sig_n`
- `pk_n+1`
- `alg_n+1`

otherwise, we would have:
- `data_n`
- `pk_n+1`
- `alg_n+1`

This format is deprecated and will be replaced by version 1 in the future.

the signed payload format for external signatures, thereafter referred as "external signature payload v0", would be the concatenation of:
- `data_n`
- `pk_n+1`
- `alg_n+1`

This format is not supported anymore and should be replaced by version 1.

##### Version 1

TODO

#### Signature (one block)

- `(pk_0, sk_0)` the root public and private Ed25519 keys
- `data_0` the serialized Datalog
- `(pk_1, sk_1)` the next key pair, generated at random
- `alg_1` the little endian representation of the signature algorithm fr `pk1, sk1` (see protobuf schema)
- `sig_0 = sign(sk_0, data_0 + alg_1 + pk_1)`
- the signed block version indicates the version of the signature payload format, either "block signature payload v0" or "block signature payload v1"
- `sig_0` is the signature of the signature payload by `sk_0`

The token will contain:

@@ -819,7 +860,9 @@ The token also contains `sk_n+1`.

The new block can optionally be signed by an external keypair `(epk, esk)` and carry an external signature `esig`.

We generate at random `(pk_n+2, sk_n+2)` and the signature `sig_n+1 = sign(sk_n+1, data_n+1 + esig? + alg_n+2 + pk_n+2)`. If the block is not signed by an external keypair, then `esig` is not part of the signed payload.
the signed block version indicates the version of the signature payload format, either "block signature payload v0" or "block signature payload v1".

We generate at random `(pk_n+2, sk_n+2)` and the signature `sig_n+1` is the signature of the signature payload by `sk_n+1`.

The token will contain:

@@ -845,8 +888,8 @@ Token {
Blocks generated by a trusted third party can carry an *extra* signature to provide a proof of their
origin. Same as regular signatures, they rely on Ed25519.

The external signature for block `n+1`, with `(external_pk, external_sk)` is `external_sig_n+1 = sign(external_sk, data_n+1 + alg_n+1 + pk_n+1)`.
It's quite similar to the regular signature, with a crucial difference: the public key appended to the block payload is the one _carried_ by block `n` (and which is used to verify block `n+1`).
The external signature for block `n+1`, with `(external_pk, external_sk)` is `external_sig_n+1`, the signature of the payload in format "external signature payload v1" by `external_sk`.
It is quite similar to the regular signature, with a crucial difference: the public key appended to the block payload is the one _carried_ by block `n` (and which is used to verify block `n+1`).
Geal marked this conversation as resolved.
Show resolved Hide resolved
This means that the authority block can't carry an external signature (that would be useless, since
the root key is not ephemeral and can be trusted directly).

@@ -1055,6 +1098,7 @@ To support this use-case, the protobuf schema defines two message types: `ThirdP
message ThirdPartyBlockRequest {
required PublicKey previousKey = 1;
repeated PublicKey publicKeys = 2;
required bytes previousSignature = 3;
}

message ThirdPartyBlockContents {