Browse Source

describ how object signing could work..

main
John-Mark Gurney 3 years ago
parent
commit
bf5cc16ece
1 changed files with 107 additions and 0 deletions
  1. +107
    -0
      OBJSIG.md

+ 107
- 0
OBJSIG.md View File

@@ -0,0 +1,107 @@
Object Signing
==============

Signing objects is very important. But the other issue is authenticating
that the signed object is valid. One issue that is if a key is
compromised, it can be used to sign statements that objects in the past
are valid. One way to address this situation is to sign the current
Merkle DAG that contains all the "produced" objects by that author. The
tree structure of a Merkle DAG with selective split locations allow the
tree to add additional objects w/o recalculating the entire tree.

This also allows rolling keys more simply, as the new key starts signing
the new root, and once verification of the new key has been done, the
objects are now authenticated again. When this happens, no old keys
need be kept, and it's encouraged to remove the old keys and only keep
one, the current key, for each identity.

As this spec is geared toward JSON encoding, but

Objects:
Identity
- uuid: UUIDv4
- updated: Date that this object was last updated
- name: Common name of this identity.
- email (optional)
- info
- tree_hash: Hash of the root of the object tree
- public_key: A publicKey object as specified in [JSF]
- sig: The signature of the object, a signaturecore as defined by [JSF].

name: Note that it is recommended to ensure that this is unique among
all the identities imported/trusted, and that work is done to present
look alike names. Giving an option to rename an Identity locally is
highly recommended to make it easier for the user.
info: General information text about this identity.
tree_hash: The multihash of the root of the object tree.
sig: Note that keyId and publicKey should not be included, as the public
key used to verify the signature MUST be the publick_key as specified
by the public_key property of the Identity object.

ValidIdentity
- identity: UUIDv4 of the identity.
- identity_pubkey: The publicKey object, per [JSF], of the Identity object
being asserted.
- assertee: UUIDv4 of the identity asserting the validity.
- assertee_pubkey: The publicKey object, per [JSF], of the Identity object
being asserted.
- sig: Signature of the assertion, a signateurecore by [JSF].

It is yet to be decided if the ValidIdentity object will be used.

The tree_hash is a [multihash]. The data refered will be a JSON [JCS]
encoded object or array. If it is an array, then each element of the
array will be a multihash refering to an object that validated by the
tree. The array MUST on contain unique multihashes, that is the array
is the equivalent of a set. The array MUST be sorted, so that a binary
search may be used over the array to find if a multihash is present or
not. If the data is an object, it will contain a key to help locate
the object, with the value being another multihash, refering to either
an object or array again. In all cases, the order of objects MUST be:
tree_hash -> [ object -> ]* array -> authenticated object. If objects
are used, the keys SHALL be based upon the last modified date of the
object. The first level MUST be year, then month, then day, then hour,
then minute, then second, then milisecond, then microsecond. If the
encoded array is longer than 256KiB, it MUST be broken up, and a new
level of objects MUST be added.

Note that the contents of the multihash are NOT distributed w/ the
Identity object. The entire tree may be very large, and a complete
tree is NOT needed to verify a subset of the tree. It is expected that
the parts will be hosted via IPFS, or another mechanism allowing the
retrival of the data.

Questions:
- Should ranges be supported for keys? That is, days could be `05-13`.
Advantages, easier to split nodes. Actually, better will be to use
a proper B-tree style structure, where there's a left node, and then
each key has all the values between it and the next node.
- Use Base64URL or Base32? JSF uses Base64URL though.
- Should hard limits be enforced on the array length?
- IPFS has a 1MiB block size limit, and it looks like UnixFS uses a
default block size of 256KiB, so something similar should be used.
Maybe recommend even smaller, say 8KiB?
- What should block garbage collection be? That is when a block is
no longer in the tree, how long should it be "available" for? This
partly depends upon how often the Identity object is published, that
is, only push a complete tree when an Identity hash is "published" or
fetched publicly.
- When distributing a set, use the IPFS CAR format? or something else?
- Should the merkle tree objects be a proper object themselves? That
is have their own UUID? If anything, this is more like a UUIDv5 type
thing where the object would have a UUIDv5, BUT why use that when
hashing the object directly gives the same results? Advantage, the
objects can be passed as normal, everyday objects, disadvantage is
that there will be more overhead, and cannot use IPFS directly for
serving the blocks.

Answered:
- Should a [Rabin fingerprint] be used? Other option is to create a
n-tree. No, as this needs to be an append (in time) friendly
structure, where inserting hashes into a sorted list will be random,
causing lots of blocks to be created and unable to be cached.

[Rabin fingerprint]: https://en.wikipedia.org/wiki/Rabin_fingerprint
[multihash]: https://multiformats.io/multihash/
[JCS]: https://tools.ietf.org/html/rfc8785
[JSF]: https://cyberphone.github.io/doc/security/jsf.html

Loading…
Cancel
Save