keri

Key Event Receipt Infrastructure - the spec and implementation of the KERI protocol

View the Project on GitHub decentralized-identity/keri

Next Key Configuration Commitment

KERI’s rotation mechanism involves committing to the next Key Configuration while you rotate from the previous Configuration to the current Configuration. This commitment is a digest of the Configuration, such that the Public Keys in the Configuration are hidden. Finally, the Rotation event which changes these keys must be signed by the keys which were previously in the commitment and are now revealed in the event. This Pre-Rotation scheme is designed to:

Key Configuration Structure

The Key Configuration used to generate nxt consists of two elements:

Example:

{
    "sith": "2",
    "keys": [
        "BrHLayDN-mXKv62DAjFLX1_Y5yEUe0vA9YPe_ihiKYHE",
        "BujP_71bmWFVcvFmkE9uS8BTZ54GIstZ20nj_UloF8Rk",
        "B8T4xkb8En6o0Uo5ZImco1_08gT5zcYnXzizUPVNzicw"
    ]
}

In order to commit to the configuration, each of the elements must be combined in a cryptographic digest. The process for this is as follows:

  1. Choose a method D from the set of self-addressing derivation methods
  2. Encode the sith integer as a hex string (lower-case, no leading zeros or 0x)
  3. Encode all keys in their serialized prefix form
  4. Get sith_d from D(sith)
  5. For each key_n in keys, get key_n_d from D(key_n) to create the set of digests digests
  6. For sith_d and each element d in digests, get the raw bytes of the digest (without the derivation code) and XOR them all together to make xor_raw
  7. Serialize xor_raw to base64 URL safe form without padding and prepend the derivation code of D

In contrast to a simple concatenate-and-digest approach, the XOR method has two advantages:

Python Example

The following example shows the nxt creation process in Python:.

sith = 2
keys = ['BrHLayDN-mXKv62DAjFLX1_Y5yEUe0vA9YPe_ihiKYHE',
        'BujP_71bmWFVcvFmkE9uS8BTZ54GIstZ20nj_UloF8Rk',
        'B8T4xkb8En6o0Uo5ZImco1_08gT5zcYnXzizUPVNzicw']
            
# convert sith to hex string no leading zeros
sith = '2'

# Blake3_256 sith digest, fully qualified prefix form
sithdig = 'EgT6bcpFB5_OFr6Ci0N8-bDeJ5Cf_5K7vVmpWW8jy_j0'

# raw binary unqualified in string escaped form
sithdig == b"\x81>\x9br\x91A\xe7\xf3\x85\xaf\xa0\xa2\xd0\xdf>l7\x89\xe4'\xff\xe4\xae\xefVjV[\xc8\xf2\xfe="

# convert keys to digests
# fully qualified Base64 digests
keydigs == ['EmB26yMzroICh-opKNdkYyP000kwevU18WQI95JaJDjY',
         'EO4CXp8gs0yJg1fFhJLs5hH6neqJwhFEY7vrJEdPe87I',
         'ELWWZEyBpjrfM1UU0n31KIyIXllrCoLEOI5UHD9x7WxI']
         
# raw binary (unqualifed) digests in string escaped form
keydigs =[b'\x98\x1d\xba\xc8\xcc\xeb\xa0\x80\xa1\xfa\x8aJ5\xd9\x18\xc8\xfd4\xd2L\x1e\xbdM|Y\x02=\xe4\x96\x89\x0e6',
                       b';\x80\x97\xa7\xc8,\xd3"`\xd5\xf1a$\xbb9\x84~\xa7z\xa2p\x84Q\x18\xee\xfa\xc9\x11\xd3\xde\xf3\xb2',
                       b'-e\x99\x13 i\x8e\xb7\xcc\xd5E4\x9f}J#"\x17\x96Z\xc2\xa0\xb1\x0e#\x95\x07\x0f\xdc{[\x12']

# now combine with XOR the raw versions of all four digests, sith plus three keys. In python must first convert to integers in order to use XOR = ^

raw = sithdig ^ keydig[0] ^ keydig[1] ^ keydig[2]

# now convert raw to fully qualified with derivation code for the digest algorithm
# in this case Blake3_256

nxt = 'E' + base64(raw)

assert nxt = 'ED8YvDrXvGuaIVZ69XsBVA5YN2pNTfQOFwgeloVHeWKs'