A URI schema for attestations

There are a few competing designs.

Go for under-design

Recognising the danger of over-design, we first attempt to under-design, then go up from here, in order to not to over-design. First, the minimum-design approach.

The shortest secp384r1 signed attestation I can construct is about 281 bytes without contract (be a field of its own or integrated into an oid. (This post will be updated with secp256k1). This is how long it is:

attestation:MIIBFTCBnKADAgECAggsKZxbFu0FlTAKBggqhkjOPQQDAjB0MBAGByqGSM49AgEGBSuBBAAiA2AABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor-8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ_wkWV7Mt_qCPgCemB-vMwCQIBAQoBAQIBATAKBggqhkjOPQQDAgNoADBlAjEAiuZAiTfr6dUT2crUayTzsD2HRlga7LHfb_tWunBrxzjM6LGMTw_38Wd2DoPQHlGPAjA99iMoJkzGYIeTJpuyNR661vc80RzO-iU8phqBFVvzEg9s7mWKyYeo-QfgYpqMXEo=

It is 388 characters long. I haven't encoded contract address in it because there is uncertainty on how to do so (as a field or an object class). Also, users without an asn1 parser (or software capable to do so) will not know what's inside. (old-time cryptic links like news:3B48D5FC.3030004@sc.rr.com didn't work out well)

Side: the size can go down to 161 bytes if we leave out the SubjectPublicKeyInfo (118 bytes). Tore commented that the curve parameter is part of the public key, so I kept it.

The methods by which it could be shorter

  • Encode with PER instead of DER
  • Use secp256k1 instead of secp384r1 (reduction of 64 bytes)
  • Use compressed public key (reduction of 32 bytes roughly)
  • Condense the semantic information. e.g. drop out the public key (as it can be recovered)

First I'll put PER aside. It would reduce the length, but

  • It works on syntax level, does not cure the redundancy in the schema itself. e.g. both the public key and the signature is encoded (when the latter can be used to recover the former); AlgorithmIdentifier appeared 2 times and Subject repeated a part of (in the case of RDN, a subset of) the fields in the data object.
  • Would the reduction in the structural data allow an attacker to create some data that means A in the current schema, yet means B in an older contract that didn't get updated? It looks like something designed for speed rather than security. More on this with Tore.
  • The majority of data is the public key and signature. PER wouldn't put a dent on them.

Simplify semantics:

Let's observe the data itself. Here is the same data with Jason-encoding rule applied:

{
   "signedInfo":{
      "version":2,
      "serialNumber":3182246526754555285,
      "signature":[
         "1.2.840.10045.4.3.2"
      ],
      "subjectPublicKeyInfo":{
         "algorithm":[
            "1.2.840.10045.2.1",
            "1.3.132.0.34"
         ],
         "subjectPublicKey":{
            "value":"04456EA950C4A623369E5F288D17CB9622643FDC7A8E1DCC08B3A27124BA8E49B9041B479658AB2D95C8ED9E0835C827EB898C5358EB628AFEF05B0F6B315263413B89CDECECB68D19D33407DCBBC6067FC24595ECCB7FA823E009E981FAF3",
            "length":760
         }
      },
      "dataObject":{
         "match":1,
         "class":"lounge",
         "admission":1
      }
   },
   "signatureAlgorithm":[
      "1.2.840.10045.4.3.2"
   ],
   "signatureValue":{
      "value":"30650231008AE6408937EBE9D513D9CAD46B24F3B03D8746581AECB1DF6FFB56BA706BC738CCE8B18C4F0FF7F167760E83D01E518F02303DF62328264CC6608793269BB2351EBAD6F73CD11CCEFA253CA61A81155BF3120F6CEE658AC987A8F907E0629A8C5C4A",
      "length":824
   }
}

And reduce it by two rules:

  1. Not to mention anything that the schema has an explicit value for.
  2. Do the same for anything that the schema has a default value for (and the default value is used).
  3. If the schema has the type information, we don't need to explicitly set the type.

So the result might look like this:

attestation:0xD76b5c2A23ef78368d8E34288B5b65D616B746aE?match=1;class=lounge;admission=1;30650231008AE6408937EBE9D513D9CAD46B24F3B03D8746581AECB1DF6FFB56BA706BC738CCE8B18C4F0FF7F167760E83D01E518F02303DF62328264CC6608793269BB2351EBAD6F73CD11CCEFA253CA61A81155BF3120F6CEE658AC987A8F907E0629A8C5C4A

Still pretty long. If we use a shorter signature (secp256r1) and Base64 instead of hex, we get:

attestation:0xD76b5c2A23ef78368d8E34288B5b65D616B746aE?match=1;class=lounge;admission=1;MGUCMQCK5kCJN-vp1RPZytRrJPOwPYdGWBrssd9v-1a6cGvHOMzosYxPD_fxZ3YOg9AeUY8CMD32IygmTMZgh5Mmm7I1Hj71

It's possible now as a URI. We can re-encode it in http protocol just for the pleasure of systems that can't allow new URI types or haven't had a resolver of that type installed:

http:⁄⁄attestation.id⁄0xD76b5c2A23ef78368d8E34288B5b65D616B746aE?match=1;class=lounge;admission=1;MGUCMQCK5kCJN-vp1RPZytRrJPOwPYdGWBrssd9v-1a6cGvHOMzosYxPD_fxZ3YOg9AeUY8CMD32IygmTMZgh5Mmm7I1Hj71

Notice that the actions available to this attestation isn't encoded to the URI, therefore the user agent (wallet) has to make that up based on the TokenScript it has. We may extend it later for the capability to specify action. For now it look like over-design if we do.

This method, of course, can't handle complicated data object. For example:

{
   "year": 2020,
    "score" {
        "physics": {
            "project": 4.3,
            "test": 5
        }
        "art" : {
            "project": 4.3,
            "test": 5
        }
}

Let's assume that the schema rules that the subject of this data object is year=2020 and such was encoded in the subject of SignedInfo outside of the data object, then we have:

http:⁄⁄attestation.id⁄0xD76b5c2A23ef78368d8E34288B5b65D616B746aE/RPZytRrJPOwPYdGWBrssd9v-1a6cGvHOMzosYxPD?year=2020;MGUCMQCK5kCJN-vp1RPZytRrJPOwPYdGWBrssd9v-1a6cGvHOMzosYxPD_fxZ3YOg9AeUY8CMD32IygmTMZgh5Mmm7I1Hj71

Where the RPZytRrJPOwPYdGWBrssd9v-1a6cGvHOMzosYxPD section is the DER-encoded data-object and ?year=2020; is the subject. (there might be multiple key-value pairs as the construct of subject is Relative Distinguished Name)