Samuel M Smith
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- tags: KERI email: sam@samuelsmith.org --- # KID0003 Event Serialization [![hackmd-github-sync-badge](https://hackmd.io/yd8X2Z5JRW2g9FI73h93xQ/badge)](https://hackmd.io/yd8X2Z5JRW2g9FI73h93xQ) ## Introduction (from WhitePaper Version 2.59:) In KERI, complete key events need to be serialized in order to create cryptographic signatures of each event. Complete events also need to be serialized in order to create cryptographic digests of each event. Complete events are propagated over the network in signed serialized form. Complete events also need to be de-serialized after network propagation such that the resultant de-serialization preserves the semantic structure of the data elements in the event. Because the cryptographic material in the events may be of variable length, a fixed field length serialization is not a viable approach. Consequently KERI must support variable length field serialization. Moreover serialization encodings that support arbitrary nested self-describing data structures provide future proofing to event composition. Notably, JSON, CBOR, and MsgPack are well known broadly supported serialization encodings that support arbitrary nested self-describing data structures. JSON is an ASCII text encoding that is human readable, albeit somewhat verbose, that is commonly used in web applications. On the other hand both CBOR and MsgPack are binary encodings that are much more compact. Supporting all three encodings (and possibly others) would satisfy a wide range of application, transport, and resource constaints. Importantly, because only the controller of the associated identifier prefix may compose KERI events, the ordering of elements in the event serialization may be determined solely by that controller. Other entities may sign the event serialization provided by the controller but do not need to provide a serialization of their own. In summary, the necessary constraint for complete event serialization is support for arbitrary data structures with variable length fields that are serializable and de-serializable in multiple formats. Reproducible ordering is not a necessary constraint. (For more rationale on serialization approach and JSON stringification, see [Commentary](KID0003Commentary.md)). ## Event Serialization Algorthm The ordering of elements in each mapping in each event element is specified (see below). This includes nested elements. Serialization using the standard JSON, CBOR, and MsgPack libraries follow a recursive depth first traversal of nested elements. The ordered serialization depends on order preserving fields in the associated mappings. (See the section below on order preserving stringify for JSON) Complete events are serialized/de-serialized from/to ordered mappings using the JSON, CBOR or MsgPack functions for serializing/deserializing. Each programming language may name the functions differently for serialization/de-serialization. In JavaScript they are JSON.stringify/JSON.parse. In Python they are json.dumps/json.loads. Likewise the CBOR and MsgPack libraries in each language may use different names for these functions. The JSON serialization is without white space. ## Event-Ordered Element Sets As of this writing KERI has 5 different types of key events with corresponding message dictionaries and unique message types or ilks, these are: Inception Event Rotation Event Interaction Event Delegated Inception Event Delegated Rotation Event In addition to the key event messages KERI has several other messages such as receipt and notification messages each with corresponding message dictionaries and unique message types or ilks, these are: Event Receipt Message, Nontransferable Signer Event Receipt Message, Transferable Signer Key State Notification Message with four variants Each event may have slightly different sets of elements. The events are expressed as an ordered mapping of (label, value) pairs. The values may include lists (arrays) of values or (label, value) pairs or nested ordered mappings of (label, value) pairs. An Interaction event in a delegated key event stream has the identical element set of an interaction event in a non-delegated key event stream. As a result the ordering from the non-delegated interaction event may be applied to the delegated interaction event. In the following specifications the element sets are expressed in JSON format. Both MsgPack and CBOR natively support JSON compatible field element values for the various data types as well as ascii field element labels. As a result a JSON constrained representation is sufficient to ensure interoperabilty. ### Element Labels |Label|Description|Notes| |---|---|---| |v| Version String| | |i| Identifier Prefix| | |s| Sequence Number| | |t| Message Type| | |te| Last received Event Message Type in Key State Notice | | |d| Event Digest (Seal or Receipt or Key State Notice) || |p| Prior Event Digest | | |kt| Keys Signing Threshold || |k| List of Signing Keys (ordered key set)| | |n| Next Key Set Commitment | | |wt| Witnessing Threshold || |w| List of Witnesses (ordered witness set) | | |wr| List of Witnesses to Remove (ordered witness set) | | |wa| List of Witnesses to Add (ordered witness set) | | |c| List of Configuration Traits/Modes | | |a| List of Anchors (seals) || |da| Delegator Anchor Seal in Delegated Event (Location Seal) | | |di| Delegator Identifier Prefix in Key State | | |rd| Merkle Tree Root Digest || |ee| Last Establishment Event Map in Key State| | |vn| Version Number ("major.minor") | exact scheme tbd | A label may have different values in different contexts but not different value *types*. ## Usages of Labels - Seals Seals are mappings. There are 4 types of seals and one event reference that functions as a seal. The event reference is the last establishment event in the key state message. So I include it here for completeness. Digest Merkle Root Digest Event Digest Event location Digest Last Event |Label|Description|Notes| |---|---|---| | i | identifier prefix of KEL for event | | | s | sequence number of event | | | t | message type of event | | | d | digest depends on context | | | p | prior event digest depends on context | | | rd | merkle tree root digest | | Digest Seal has only one element ```JSON { "d": "Eabcde..." } ``` Merkle Tree Root Digest Seal has only one element (hence is ambiguous wrt to digest seal ```json { "rd": "Eabcde..." } ``` Event Seal has 3 elements ```json { "i": "Ebietyi....", "s": "3", "d": "Eabcde..." } ``` Event location Seal has 4 elements ```json { "i": "Ebietyi....", "s": "3", "t": "ixn", "p": "Eabcde..." } ``` Deprecated Last Received Event Reference in KeyState has 3 elements ```json { "s": "2", "t": "ixn", "d": "E4u8kd..." } ``` Deprecated Last Establishment Event Reference in KeyState has 2 elements ```json { "s": "2", "d": "E4u8kd..." } ``` ## Usage of Labels - Messages ### Inception Event ```json { "v" : "KERI10JSON00011c_", "i" : "EZAoTNZH3ULvaU6Z-i0d8JJR2nmwyYAfSVPzhzS6b5CM", "s" : "0", "t" : "icp", "kt": "1", "k" : ["DaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM"], "n" : "EZ-i0d8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CM", "wt": "1", "w" : ["DTNZH3ULvaU6JR2nmwyYAfSVPzhzS6bZ-i0d8JZAo5CM"], "c" : ["EO"] } ``` ### Rotation Event (also delegating rotation) ```json { "v" : "KERI10JSON00011c_", "i" : "EZAoTNZH3ULvaU6Z-i0d8JJR2nmwyYAfSVPzhzS6b5CM", "s" : "1", "t" : "rot", "p" : "EULvaU6JR2nmwyZ-i0d8JZAoTNZH3YAfSVPzhzS6b5CM", "kt" : "1", "k" : ["DaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM"], "n" : "EYAfSVPzhzZ-i0d8JZAoTNZH3ULvaU6JR2nmwyS6b5CM", "wt": "1", "wa": ["DTNZH3ULvaU6JR2nmwyYAfSVPzhzS6bZ-i0d8JZAo5CM"], "wr": ["DH3ULvaU6JR2nmwyYAfSVPzhzS6bZ-i0d8TNZJZAo5CM"], "a" : [ { "i": "EJJR2nmwyYAfSVPzhzS6b5CMZAoTNZH3ULvaU6Z-i0d8", "s": "0", "d": "ELvaU6Z-i0d8JJR2nmwyYAZAoTNZH3UfSVPzhzS6b5CM" } ] } ``` ### Interaction Event (Also delegating Interaction) ```json { "v" : "KERI10JSON00011c_", "i" : "EZAoTNZH3ULvaU6Z-i0d8JJR2nmwyYAfSVPzhzS6b5CM", "s" : "2", "t" : "isn", "p" : "EULvaU6JR2nmwyZ-i0d8JZAoTNZH3YAfSVPzhzS6b5CM", "a" : [ { "i": "EJJR2nmwyYAfSVPzhzS6b5CMZAoTNZH3ULvaU6Z-i0d8", "s": "1", "d": "ELvaU6Z-i0d8JJR2nmwyYAZAoTNZH3UfSVPzhzS6b5CM" } ] } ``` ### Delegated Inception Event ```json { "v" : "KERI10JSON00011c_", "i" : "EJJR2nmwyYAfSVPzhzS6b5CMZAoTNZH3ULvaU6Z-i0d8", "s" : "0", "t" : "dip", "kt": "1", "k" : ["DaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM"], "n" : "EZ-i0d8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CM", "wt": "1", "w" : ["DTNZH3ULvaU6JR2nmwyYAfSVPzhzS6bZ-i0d8JZAo5CM"], "c" : ["DND"], "da" : { "i": "EZAoTNZH3ULvaU6Z-i0d8JJR2nmwyYAfSVPzhzS6b5CM", "s": "1", "t": "rot", "p": "E8JZAoTNZH3ULZ-i0dvaU6JR2nmwyYAfSVPzhzS6b5CM" } } ``` ### Delegated Rotation Event ```json { "v" : "KERI10JSON00011c_", "i" : "EZAoTNZH3ULvaU6Z-i0d8JJR2nmwyYAfSVPzhzS6b5CM", "s" : "1", "t" : "drt", "p" : "EULvaU6JR2nmwyZ-i0d8JZAoTNZH3YAfSVPzhzS6b5CM", "kt" : "1", "k" : ["DaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM"], "n" : "EYAfSVPzhzZ-i0d8JZAoTNZH3ULvaU6JR2nmwyS6b5CM", "wt": "1", "wa": ["DTNZH3ULvaU6JR2nmwyYAfSVPzhzS6bZ-i0d8JZAo5CM"], "wr": ["DH3ULvaU6JR2nmwyYAfSVPzhzS6bZ-i0d8TNZJZAo5CM"], "a" : [ ], "da" : { "i": "EZAoTNZH3ULvaU6Z-i0d8JJR2nmwyYAfSVPzhzS6b5CM", "s": "1", "t": "isn", "p": "E8JZAoTNZH3ULZ-i0dvaU6JR2nmwyYAfSVPzhzS6b5CM" } } ``` ### Non-Transferable Prefix Signer Receipt ```json { "v" : "KERI10JSON00011c_", "i" : "AaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM", "s" : "1", "t" : "rct", "d" : "DZ-i0d8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CM" } ``` ### Transferable Prefix Signer Receipt ```json { "v" : "KERI10JSON00011c_", "i" : "AaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM", "s" : "1", "t" : "vrc", "d" : "DZ-i0d8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CM", "a" : { "i" : "AYAfSVPzhzS6b5CMaU6JR2nmwyZ-i0d8JZAoTNZH3ULv", "s": "4", "d" : "DZ-i0d8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CM", } } ``` ## Key State Notice Messages While the actual Key State only needs the version number, that message itself needs the full version string so that it can be parsed when sent over the wire using low level TCP etc to support all the serializations. A different version of the message could be used with a higher level transport such as JSON only ReST. In that case then the "v" could be replaced with "vn" = "1.0" for example. The message type is `ksn` for Key State Notice message. Delegated key state notification messages have a non-empty `di` field for the delegator's fully qualified identifier prefix. The `ee` block or map means last received establishment event in key state. It includes the witness remove, `wr`, and witness add, `wa` lists from that establishment event. This is to enable promulgation and confirmation that any rotated out witnesses also witness the event that rotates them out from being a witness. Each key state notification message is signed by the entity providing the key state. The entity providing the key state may not necessarily be the controlling entity of the associate KEL for that key state. Essentially the signature on a key state notification message acts as an endorsement of that key state message by the provider. It is signifying that the endorsing provider has verified a given KEL and the result of its verification is the provided key state. Because the key state message is thusly signed any duplicity on the part of the endorsing provider (signer) now becomes detectable and provable. As a result duplicitous endorsers (signers) may therefore not be trusted by any validator that detects such duplicity. When the endorser has a nontransferable identifier then the attached signatures consist of a receipt couple count code plus one or more receipt couples. A receipt couple consists of a fully qualified non-transferable identifier followed by a fully qualified non-indexed signature. The full attachment may also include prelude pipeline count codes. Multiple receipt couples may occur if a given key state came from a cluster of watchers/or witnesses where each mutually consistent individual key state messages from were merged into one message with all their receipts attached in a group. When the endorser has a transferable identifier then the attached signatures consist of a transferable indexed signature group count code plus one or more complex indexed signature groups. The full attachments may also include prelude pipeline count codes. Each transferable indexed signature group consists of a triple of pre+snu+dig corresponding to the (i, s, d) of the establishment event from the endorser that was authoritative at the time of the endorsement. The key list of this establishment event provides the set of public keys for the attached indexed signatures. This triple is followed by a controller indexed signature count code and one or more indexed signatures corresponding to the keys from the establishment event of the preceding triple. The index in each signature corresponds to the offset of the public key in the key list. ### Key State Notice (Non-Delegated) ```json { "v": "KERI10JSON00011c_", "i": "EaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM", "s": "2", "t": "ksn", "d": "EAoTNZH3ULvaU6JR2nmwyYAfSVPzhzZ-i0d8JZS6b5CM", "te": "rot", "kt": "1", "k": ["DaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM"], "n": "EZ-i0d8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CM", "wt": "1", "w": ["DnmwyYAfSVPzhzS6b5CMZ-i0d8JZAoTNZH3ULvaU6JR2"], "c": ["eo"], "ee": { "s": "1", "d": "EAoTNZH3ULvaU6JR2nmwyYAfSVPzhzZ-i0d8JZS6b5CM", "wr": ["Dd8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CMZ-i0"], "wa": ["DnmwyYAfSVPzhzS6b5CMZ-i0d8JZAoTNZH3ULvaU6JR2"] }, "di": "" } ``` ### Key State Notice (Delegated) ```json { "v": "KERI10JSON00011c_", "i": "EaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM", "s": "2", "t": "ksn", "d": "EAoTNZH3ULvaU6JR2nmwyYAfSVPzhzZ-i0d8JZS6b5CM", "te": "rot", "kt": "1", "k": ["DaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM"], "n": "EZ-i0d8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CM", "wt": "1", "w": ["DnmwyYAfSVPzhzS6b5CMZ-i0d8JZAoTNZH3ULvaU6JR2"], "c": ["eo"], "ee": { "s": "1", "d": "EAoTNZH3ULvaU6JR2nmwyYAfSVPzhzZ-i0d8JZS6b5CM", "wr": ["Dd8JZAoTNZH3ULvaU6JR2nmwyYAfSVPzhzS6b5CMZ-i0"], "wa": ["DnmwyYAfSVPzhzS6b5CMZ-i0d8JZAoTNZH3ULvaU6JR2"] }, "di": "EJZAoTNZH3ULvYAfSVPzhzS6b5CMaU6JR2nmwyZ-i0d8" } ``` ## Usage of Labels - Configurations and System Metadata ### Configuration Traits/Modes The "c" element in inception and delegated inception events is a list strings specifying optional configuration data/traits/modes/options . The presence of a string in this list indicates a configuration option for the Key Events. The string values are provided in the following table. The order in which the string values appear in the trait list is normative. They must appear when present in the order in the following table. To clarify, when present `EO` must be first. When both `EO` and `DND` are present then `EO` must precede `DND`. If `EO` is not present then `DND` may be first in the list. Subsequent additions to the following table must follow that same precedence ordering rule. The reason for the rule is to ensure consistency (reproducability) in the key state notification message. |Option|Description|Notes| |---|---|---| | EO | Establishment Only | Only establishment events are allowed for this identifier prefix | | DND | Do Not Delegate | This identifier prefix does not allow delegations to other identifier prefixes | ### Version String Version string enables discovery of encoding when parsing serialized packet. Parts: KERI version kind size terminal KERI = KERI event packet identifier version = major minor = hex characters = 10 for 1.0 kind = encoding one of CBOR, JSOM, MGPK size = 6 character hex string length of serialized event max size 16777215 bytes in version 1.0 terminal is "_" underscore for future proofing version tuple = (1, 0) = (major, minor) major increments with backward breaking changes minor increments with backward compatible changes Serialize event with 0000 size value in version string. Terminal characters enables detectable parsable change in length of version string in the future Embedded version string with size obviates the needed for separate header when using headerless transports (not http). Because version string is embedded in event it is included in signed portion so is protected by authentication of signature. An attacker may not change the size of the event without breaking the signature. Serialize event with zero'd size in version string ``` KERI10CBOR000000_ KERI10JSON000000_ KERI10MGPK000000_ ``` Then replace the 000000 size field inside the version string of the serialized event with lowercase hex of actual size of serialized event. ``` KERI10CBOR000115_ KERI10JSON00011c_ KERI10MGPK000115_ ``` Then sign the encoded event that now has the correct size in its version string. ### Next Signing Config Digest for Future Event Labels The KERI pre-rotation scheme includes a commitment to the next signing configuration. This includes the next threshold and the next set of signing keys. This committment is made by creating a digest of each of the elements in this committment set and then combining them with a bitwize XOR (exclusive OR). The labels of the elements that are included for the next set are as follows: ```javascript [ "kt", //Signing threshold, key element threshold "k", //List (array) of signing keys ] ``` The next signing config has two primary elements, `kt` and `k`. The combination starts with the `kt` as the first element. The `k` element is then combined. But because the keys element is a list, each key from the list must be combined in order of appearance with the combination of the prior elements. The "kt" element may also be a list or list of lists when using a fractionally weighted threshold. The combination method is to first take a digest of each element and then combine the elements with an XOR. Finally the combined result is converted to a fully qualified Base64 representation with the derivation code for the type of digest used. All elements must use the same digest. The kt element is converted to a string before digesting. For an integer kt, the string is a hex representation of the integer with no leading zeros. Each of the keys in `k` is first converted to fully qualified Base64 format which is the normal format for the keys in key events. The digest is in this fully-qualified Base64 format. The digests, `kt` plus each of the keys, are combined in raw binary mode using a bitwise XOR. The combined digests are then converted to fully qualified Base64 and this is the format used in the key event for the value of the `n` element. #### Example computation The following example shows values. See [element labels](#element-labels) for field name abbreviations. ``` python kt = 2 k = ['BrHLayDN-mXKv62DAjFLX1_Y5yEUe0vA9YPe_ihiKYHE', 'BujP_71bmWFVcvFmkE9uS8BTZ54GIstZ20nj_UloF8Rk', 'B8T4xkb8En6o0Uo5ZImco1_08gT5zcYnXzizUPVNzicw'] # convert keys element threshold to hex string with no leading zeros kt = '2' # kt digest # fully qualified 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 n = 'ED8YvDrXvGuaIVZ69XsBVA5YN2pNTfQOFwgeloVHeWKs' ``` *Note: The keripy implementation is in `keri.core.coring.py` in the Nextor object class ._derive method. Test in test_nexter() function in the `tests.core.test_coring.py` .* The motivation for this new revised method is to enable multiple-signature controlled prefixes where the controllers of each public key are distributed. In this case, in order to create the `n` commitment, the public keys would otherwise have to be transmitted outside of the key creation infrastructure. This would expose them to a post-quantum attack on the public keys themselves. With the new method, only the digest of the public key need be transmitted outside the key creation infrastructure from each of the controllers. The digest of the public key is post quantum proof and therefore is not vulnerable to a post quantum attack. ### Prefix Derivation Data from Inception Event Prefixes are derived from Inception Event Data using the full event serialization, with the Prefix in the serialized event replaced with a string of `#` characters of the correct length according to the desired Prefix derivation method. This allows future proofing in that other elements included in inception event do not break derivation. ### Delegated Prefix Derivation Data from Delegated Inception Event Delegated Prefixes are derived from Delegated Inception Event Data using the full event serialization, with the Prefix in the serialized event replaced with a string of `#` characters of the correct length according to the desired Prefix derivation method. This allows future proofing in that other elements included in inception event do not break derivation. ### Delegating Seal Digest Data digest of complete serialized delegated event ## JavaScript Ordered Object Property Serialization (Stringify) The following code snippet shows how to enforce object property creation order preserving serialization using JSON.stringify for ES6-ES10. Not needed for ES11 or later. ### Code Snippet ```javascript "use strict" // Spec http://www.ecma-international.org/ecma-262/6.0/#sec-json.stringify const replacer = (key, value) => value instanceof Object && !(value instanceof Array) ? Reflect.ownKeys(value) .reduce((ordered, key) => { ordered[key] = value[key]; return ordered }, {}) : value; // Usage // JSON.stringify({c: 1, a: { d: 0, c: 1, e: {a: 0, 1: 4}}}, replacer); var main = function() { console.log("Running Main."); let x = { zip: 3, apple: 1, bulk: 2, _dog: 4 }; let y = JSON.stringify(x); console.log(y); console.log(Object.keys(x)); console.log(Object.getOwnPropertyNames(x)); console.log(Reflect.ownKeys(x)); console.log(replacer); let w = {w: 1, a: x, c: {e: 2, b: 3}}; let z = JSON.stringify(x, replacer); console.log(z); let v = JSON.stringify(w, replacer); console.log(v); } if (require.main === module) { main(); } //nodejs % node play.js //Running Main. //{"zip":3,"apple":1,"bulk":2,"_dog":4} //[ 'zip', 'apple', 'bulk', '_dog' ] //[ 'zip', 'apple', 'bulk', '_dog' ] //[ 'zip', 'apple', 'bulk', '_dog' ] //[Function: replacer] //{"zip":3,"apple":1,"bulk":2,"_dog":4} //{"w":1,"a":{"zip":3,"apple":1,"bulk":2,"_dog":4},"c":{"e":2,"b":3}} ``` ### Background We may impose ordered serialization with the JSON.stringify method by using the replacer option and the [[ownPropertyKeys]] internal method added in Javascript ES6 exposed as Reflect.ownKeys(). This method is provided in JavaScript ES6 (2015). [[ownPropertyKeys]] uses the property creation order. At the time of ES6, JSON.stringify was not required to use the [[ownPropertyKeys]] iteration order (ie property creation order). This appears to have been fixed in later versions of ES. (See the discussion below). As of this writing nodejs v14.2.0 and the latest versions of Chrome, Safari, and Firefox all appear to preserve property creation order in JSON.stringify() without having to use  Reflect.ownKeys(). This means that we can depend on and use that ordering in the specification. For earlier versions but still with support ES6, a custom replacer function for JSON.stringify(x, replacer) will ensure that property creation order is used. Earlier versions that do not support ES6 may still work with an ES6 polyfill if that includes support for [[ownPropertyKeys]]. https://stackoverflow.com/questions/30076219/does-es6-introduce-a-well-defined-order-of-enumeration-for-object-properties/30919039 In ES6 the stringify order is not required to follow the ownPropertyKeys (property creation order) ordering but this will be fixed in ES 2020 == ES11. It appears that the Babel polyfill as of 2020 already supports ES2020 already. https://www.keithcirkel.co.uk/metaprogramming-in-es6-part-2-reflect/ Reflect.ownKeys ( target ) This has already been discussed a tiny bit in this article, you see Reflect.ownKeys implements [[OwnPropertyKeys]] which if you recall above is a combination of Object.getOwnPropertyNames and Object.getOwnPropertySymbols. This makes Reflect.ownKeys uniquely useful. Lets see shall we: ```javascript var myObject = { foo: 1, bar: 2, [Symbol.for('baz')]: 3, [Symbol.for('bing')]: 4, }; assert.deepEqual(Object.getOwnPropertyNames(myObject), ['foo', 'bar']); assert.deepEqual(Object.getOwnPropertySymbols(myObject), [Symbol.for('baz'), Symbol.for('bing')]); // Without Reflect.ownKeys: var keys = Object.getOwnPropertyNames(myObject).concat(Object.getOwnPropertySymbols(myObject)); assert.deepEqual(keys, ['foo', 'bar', Symbol.for('baz'), Symbol.for('bing')]); // With Reflect.ownKeys: assert.deepEqual(Reflect.ownKeys(myObject), ['foo', 'bar', Symbol.for('baz'), Symbol.for('bing')]); ``` (For more rationale on serialization approach and JSON stringification, see [Commentary](KID0003Commentary.md). ### Stringify References * https://github.com/tc39/proposal-for-in-order * https://tc39.es/ecma262/#sec-ordinaryownpropertykeys * https://2ality.com/2015/10/property-traversal-order-es6.html#traversing-the-own-keys-of-an-object * https://www.stefanjudis.com/today-i-learned/property-order-is-predictable-in-javascript-objects-since-es2015/ * https://medium.com/@robertgrosse/how-es6-classes-really-work-and-how-to-build-your-own-fd6085eb326a

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully