ChainAgnostic / varsig

The cryptographic signature multifomat

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Capturing signature string identifiers

Gozala opened this issue · comments

I'm pulling this thread #6 (comment) out of the PR so otherwise it gets buried under various threads in the PR.

Currently spec defines varsig format as follows

<multiformat 0x34><multiformat content_multicodec><varint multihash><varint key_multicodec><bytes raw_signature>

Problem is that there are at least 3 parameters representation, hashing algorithm, key algorithm (can be more when representation itself is parametrized) but not all combinations have name that software could render in cases where it is needed e.g. UI interface, header of the JWT token.

Please note that it is not a problem for commonly used combinations as they tend to have names like EdDSA, RS256 or others defined in this table https://github.com/ucan-wg/ucan-ipld/#25-signature

However it is a problem if I wan to use some exotic combination. It would require patching for the linked spec and all the relevant implementations. I think we should strive to be more flexible which is possible, in fact it had been speced and implemented as such using nonstandard-signatures. In nutshell we said if it's not in the list of known combinations, you should add one more segment to the multiformat which is UTF8 encoded identifier for it.

There had been some debate around how useful this is. It seems unclear in what circumstances code would care about the algorithm identifier while not actually doing signing or verification, because in those instances you'd expect to know it anyway.

Concrete example is dag-ucan implementation, it does not provide any signing / verification. Instead when issuing new UCANs expects you to pass an issuer that implements Signer interface which is basically a sign functions returning a Varsig. Because any issued UCAN can be encoded as either IPLD block or a JWT one needs to derive alg header filed which currently uses encoded UTF8 string for non-standard signatures.

We could alternatively require that signer have some field or method that would return signature identifier.

However while this could be addressed things are even trickier when you've got already encoded UCAN IPLD which you wish to now format as JWT, because IPLD model has no field for the signature identifier, instead identifier was embedded inside the varsig itself (unless it's standard combination with a well known identifier). Embedding over separate field was chosen because it seemed likely that there would be other similar use cases, where program needs to represent data in different format or perhaps provide some insight (inspector like view) which similarly will have no way to describe it.

With above context I think we have several options to move forward:

  1. Add optional last segment for the UTF8 encoded name identifier of the signature

    • Which could be omitted in known combinations (ones explicitly listed in the spec).
    • Be required in less common combinations (ones not listed in the spec). If omitted it's up to implementation to refuse or identify it whatever way it makes sense. E.g. JWT encoder MAY fail or put some name generate from the signature parameters.

    This would provide smooth adoption path where new kind of signatures can start out by embedding names while they're been standardized and drop it once they gain large enough adoption.

  2. Define some algorithm for deriving name identifiers from parameters perhaps VS${...params}

  3. Do nothing and live with the fact that living on the bleeding edge can be painful.

I personally think that 1st option, provides best tradeoffs because:

  1. There is no overhead for standardized combinations and they basically look the same as spec-ed now.
  2. Non standard combinations can provide a reasonable experience at expense of increased signature sizes, which they can also decide to opt-out of by omitting identifier.

    In more concrete terms, dag-ipld could take arbitrary UCAN-IPLD and format it as valid JWT, without having to be made aware of non-standard signature.

  3. In most cases identifier for such signature would be encoded in somehow anyway, we just define a standard place for it