Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
218 lines (110 sloc) 23.3 KB

Identity in Factom

Factom Servers and Users who vote for them must create an identity. The identity is contained within a set of chains. This document describes an identity system primarily intended for internal management. Identity in general is a powerful concept useful for numerous applications, and tying time to it is also very powerful. For example, it solves problems of authenticity of signed data after private keys are compromised. Data signed before the compromise can still be relied on. Old data does not need to be resigned with the new key to maintain authenticity. Identities from other contexts, like software distribution signing, should use independent identity schemes, but can model them on this design. Other identity systems probably don't need the chainID mining aspects, since that is primarily to consolidate internal identity chains into future network segments. Eliminating mining also would allow a deterministic directory structure with the extIDs as folder paths.

An Identity Chain

To establish an identity, a user needs to create several private keys, combine the public key hashes into a Chain Name, mine to get an appropriate prefix, then create a new chain with that Chain Name. Entry Credit keys are then linked to that identity. The identity then lends support to other identities, then ultimately to a server candidate, which may be a Federated or Audit server.

Root Factom Identity

A Factom identity is bootstrapped with a series of keys. Different logical identity subchains are associated with the root identity to catalog specific functions. The subchains segregate various types of data, so it does not need to be downloaded if the data is ignorable.

Human Readable Identity Keys

The first step in creating an identity is to create 4 levels of private keys, with level 1 being the lowest security online key.

The Factom identities are managed by ed25519 digital signatures. The keys can be represented in base58 form with checksums to allow for human interfacing.

Four different private keys are created, each a 32 byte random number. The 4 different levels are presented to the user with 4 different prefixes, resulting in address that start with sk1, sk2, sk3, and sk4.

The conversion to human readable form is very similar to Entry Credit keys, and only differs by having an extra byte in the prefix. The prefix is prepended to the private key, then that is hashed with SHA256d, and the first 4 bytes of the SHA256d is appended to the end of the key. The entire thing is converted to base58.

The prefixes and key ranges are shown here:

The secret part of the identity keys:

prefix All Zeros All Ones
4db6c9 sk11pz4AG9XgB1eNVkbppYAWsgyg7sftDXqBASsagKJqvVRKYodCU sk13mjEPiBP6rEnC5TWQSY7qUTtnjbKb4QcpEZ7jNDJVvsupCg9DV
4db6e7 sk229KM7j76STogyvuoDSWn8rvT6bRB1VoSMHgC5KD8W88E26iQM3 sk2464XMB8ws92poWcho4WjTThNDD8piLgDzMnSE178A8WiU46gJy
4db705 sk32Tee5C4fCkbjbN4zc4VPkr9vX4xg8n53XQuWZx6xAKm2cAP7gv sk34QPpJe6WdRpsQwmuBgVM5SvqdggKqcwqAV1kidzwpL9X86sVi9
4db723 sk42myw2f2Dy3PnCoEBzgU1NqPPwYWBG4LehY8q4azmpXPqGY6Bqu sk44ij7G745Picv2Nw6aJTxhSAK4ADpxuDSLcF5DGtmUXnKs6XT1F

The public part of the identity keys:

prefix All Zeros All Ones
3fbeba id11qFJ7fe26N29hrY3f1gUQC7UYArUg2GEy1rpPp2ExbnJdSj3mN id13mzUM7fsX3FHXSExEdgRintPena8Ns92c5y4YVvEccAoEttNTG
3fbed8 id229ab58barepCKHhF3df62BLwxePyoJXr9968tSv4coR7LbtoFL id246KmJadSHL3L8sQ9dFf3Ln7s5G7dW9QdnDCP38p4GoobsaTCHN
3fbef6 id32Tut2bZ9cwcEvirSSFdheAaRP7wUvaoTKGKTP5otH13uzjcHTd id34Qf4G3b13cqNkJZM1sdexmMLVjf8dRgExLRhXmhsw1SQSzthdm
3fbf14 id42nFAz4WiPEQHYA1dpscKG9otobUz3s54VPYmsihhwCgibnEPW5 id44izMDWYZoudRMjiYQVcGakaovDCdkhwr8Tf22QbhbD5D934waE

Factom Identity Chain Creation

Messages and updates for an identity occur within an identity chain. There is a single root chain per identity, and the 32 byte ChainID of the identity is how the identity is referenced. A Factom identity is not explicitly tied to any real world human/organizational entity. A real world entity can claim an identity, but it is not necessary.

An identity is established with the first entry in the chain. It is updated with entries signed by keys placed in the first entry. The public keys are placed in the Chain Name, so the initial identity keys largely make up the identity.

There is something akin to mining in the identity creation. This marginally rate limits identity creation. It also makes future P2P network segmentation possible based solely on the ChainID. All the chains related to voting would share the first few bytes and be on the same network segment. All the ChainIDs related to identity start with 0x888888.

First, 4 random 32 bytes are chosen. These are the 4 different private keys of the different levels.

Level Four Private Keys Human Readable Equivalent
1 f84a80f204c8e5e4369a80336919f55885d0b093505d84b80d12f9c08b81cd5e sk13iLKJfxNQg8vpSmjacEgEQAnXkn7rbjd5ewexc1Un5wVPa7KTk
2 2bb967a78b081fafef17818c2a4c2ba8dbefcd89664ff18f6ba926b55e00b601 sk22UaDys2Mzg2pUCsToo9aKgxubJFnZN5Bc2LXfV59VxMvXXKwXa
3 09d51ae7cc0dbc597356ab1ada078457277875c81989c5db0ae6f4bf86ccea5f sk32Xyo9kmjtNqRUfRd3ZhU56NZd8M1nR61tdBaCLSQRdhUCk4yiM
4 72644033bdd70b8fec7aa1fea50b0c5f7dfadb1bce76aa15d9564bf71c62b160 sk43eMusQuvvChoGNn1VZZwbAH8BtKJSZNC7ZWoz1Vc4Y3greLA45

Raw public keys are created from those private keys. These are treated similar to Factoid RCDs. The pubkeys are prepended with a byte 0x01 and hashed with SHA256d.

The four keys above would result in these identity keys:

Level Four Identity Keys Human Readable Equivalent
1 3f2b77bca02392c95149dc769a78bc758b1037b6a546011b163af0d492b1bcc0 id12K4tCXKcJJYxJmZ1UY9EuKPvtGVAjo32xySMKNUahbmRcsqFgW
2 58190cd60b8a3dd32f3e836e8f1f0b13e9ca1afff16416806c798f8d944c2c72 id22pNvsaMWf9qxWFrmfQpwFJiKQoWfKmBwVgQtdvqVZuqzGmrFNY
3 b246833125481636108cedc2961338c1368c41c73e2c6e016e224dfe41f0ac23 id33pRgpm8ufXNGxtW7n5FgdGP6afXKjU4LfVmgfC8Yaq6LyYq2wA
4 12db35739303a13861c14862424e90f116a594eaee25811955423dce33e500b6 id42vYqBB63eoSz8DHozEwtCaLbEwvBTG9pWgD3D5CCaHWy1gCjF5

A Chain Name is constructed with 7 elements. The first element is a binary string 0 signifying the version. The second element is ASCII bytes "Identity Chain". The third element is the level 1 identity key in binary form. Elements 4-6 are levels 2-4. The 7th element is a nonce which is iterated until the first 3 bytes match 0x888888. The Entry content is not defined, and does not affect the Chain Name. On a 5 year old laptop the search took about 1 minute per core.

Chain Name = [00] [4964656E7469747920436861696E] [3f2b77bca02392c95149dc769a78bc758b1037b6a546011b163af0d492b1bcc0] [58190cd60b8a3dd32f3e836e8f1f0b13e9ca1afff16416806c798f8d944c2c72] [b246833125481636108cedc2961338c1368c41c73e2c6e016e224dfe41f0ac23] [12db35739303a13861c14862424e90f116a594eaee25811955423dce33e500b6] [nonce]

After iterating and finding a nonce 0000000000c512c7 we have a chainID 888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762

Factom Identity Registration

In order for Factom to pay attention to any individual identity, the identity must register itself. The registration should occur after the chain creation to prevent a 12 hour long denial-of-chain attack (detailed elsewhere). For the registration to take effect, the corresponding identity chain must be created within 144 blocks (normally 24 hours). Any updates to the identity (such as adding EC keys or updating keys) must occur during or after the block it was registered in. This prevents events being reinterpreted retroactively.

An identity only needs to be registered once, and cannot be unregistered.

The registration message has 5 ExtIDs. The first ExtID is a binary string 0 signifying the version. The second ExtID has 24 ASCII bytes "Register Factom Identity". It is a long string so there is no overlap in message interpretation with other message types. It also makes it clear that a hash is not being signed, and can be filtered on this string in potential future messages. The third ExtID is the binary encoded ChainID of the identity. It will start with 888888. The 4th ExtID is the preimage to the identity key. It includes the type prefix (0x01) and the raw ed25519 pubkey. The 5th ExtID is the signature of the first, second, and third ExtIDs serialized together.

The entry would consist of only ExtIDs and look like this:

[0 (version)] [Register Factom Identity] [identity ChainID] [identity key preimage] [signature of version through ChainID]

[00] [526567697374657220466163746F6D204964656E74697479] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [764974ae61de0d57507b80da61a809382e699cf0e31be44a5d357bd6c93d12fa6746b29c80f7184bd3c715eb910035d4dac2d8ecb1c4b731692e68631c69a503]

The identity registration chainID is 888888001750ede0eff4b05f0c3f557890b256450cabbb84cada937f9c258327 with a chain name of "Factom Identity Registration Chain" and "44079090249".

Coinbase Address

When an identity desires to receive a reward from the protocol, they need to provide an address for any Factoids that they receive. This example registers a factoid address with all zeros as the private key. The Factoid address being registered is an RCD hash.

This Entry goes into the Root Factom Identity Chain.

The message is a Factom Entry with several extIDs holding the various parts. The first part is a version binary string 0. The second is the ASCII string "Coinbase Address". The third is the root identity ChainID. Forth is the new Factoid address being asserted. 5th is the timestamp with an 8 byte epoch time. Next is the identity key preimage of the lowest level identity key (id1). 7th is the signature of the serialized version, text, chainID, new factoid address, and the timestamp.

[0 (version)] [Coinbase Address] [identity ChainID] [new factoid address] [timestamp] [identity key preimage] [signature of version through timestamp]

[00] [436F696E626173652041646472657373] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [031cce24bcc43b596af105167de2c03603c20ada3314a7cfb47befcad4883e6f] [00000000495EAA80] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [e08f8c763b1512d05bb6a6cf503e884a24ea6b7af0d30df1dff30444a9b9ba2db20d40555afddfcd5e03f737afaa7be78b6129787d9a561417531d263eaabb04]

Server Management Subchain

Messages related to being a Federated, Audit, or Candidate server would live in this subchain. The root identity chain links to it. This chain is only needed if the identity wants to be a server. It adds keys which are used to sign the Bitcoin anchors as well as keys to sign the directory blocks.

Server Management Subchain Creation

This chain is created after the identity chain is known. The Chain Name first element is a version, 0. The second is the ASCII string "Server Management". The 3rd consists of the root identity chainID. The 4th is a nonce which makes the first 6 bytes of the chainID match 0x888888. Since the root identity chainID would be known at this point, the management subchain would be susceptible to a denial-of-chain attack. To counter this, a random starting value for the nonce can be chosen. This makes it far less likely that an attacker could predict which subchain you are about to create.

Chain Name = [00] [536572766572204D616E6167656D656E74] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [nonce]

After iterating and finding a nonce 98765432103e2fbb we have a chainID 8888881d59de393d9acc2b89116bc5a2dd0d0377af7a5e04bc7394149a6dbe23

Server Management Subchain Registration

The Server Management subchain needs to be discoverable. The identity will place a signed Entry in their root identity chain which points to the subchain.

It is very similar to the Factom identity registration message.

[0 (version)] [Register Server Management] [subchain ChainID] [identity key preimage] [signature of version through ChainID]

[00] [526567697374657220536572766572204D616E6167656D656E74] [8888881d59de393d9acc2b89116bc5a2dd0d0377af7a5e04bc7394149a6dbe23] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [fcb3b9dd3cc9f09b61a07e859d13a569d481508f0d5e672f9412080255ee398428fb2c488e0c3d291218f573612badf84efa63439bbcdd3ca265a31074107e04]

This message is then placed into the root identity chain. Only one server management subchain is allowed. In the case of multiple messages, the valid one is the first message that also has a Chain which exists. For example, if there are two messages registering Chain B and A in that order, but Chain A is created first, then Chain A is considered the valid one. The chain must be created within 144 blocks (normally 24 hours) of being registered. In case of a tie (both chains created in the same block, the first entry in the registration chain will be the winning subchain.)

Add New Block Signing Key

The Factom blockchain is signed with a key by each server. This key signs the Directory blocks, and those signatures are held in the Admin blocks. They are associated with the identity, but do not sign things other than the blocks. The public key is added to the Admin block by the Federated servers as part of the server promotion process. Before promotion, the key needs to be published to the server management subchain. Keys are not removed, but new keys replace older keys. To prevent replay attacks, a timestamp is included. To be valid, the key update must be the latest one seen. It also needs to be included in the blockchain between 12 hours +- of the message timestamp. (note: backup block signing key authorizations can be presigned offline in advance. Only 365 pre-prepared, signed messages would need to be held ready for broadcast to cover a year.)

The message is a Factom Entry with several extIDs holding the various parts. The first part is a version binary string 0. The second is the ASCII string "New Block Signing Key". The third is the root identity ChainID. Forth is the new public key being asserted. 5th is the timestamp with an 8 byte epoch time. Next is the identity key preimage. 7th is the signature of the serialized version, text, chainID, new key, and the timestamp.

[0 (version)] [New Block Signing Key] [identity ChainID] [new key] [timestamp] [identity key preimage] [signature of version through timestamp]

[00] [4E657720426C6F636B205369676E696E67204B6579] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [8473745873ec04073ecf005b0d2b6cfe2f05f88f025e0c0a83a40d1de696a9cb] [00000000495EAA80] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [0bb2cab2904a014bd915b276c350821620edb432ddfbceed3896e87e591a412712b7db6d8dad1a8313138ea919bbc9b7a1bd4ffe1d84d558b8a78ef7746f480d]

Add New Bitcoin Key

Factom uses the Bitcoin blockchain as a sibyl resistant communication channel, as well as a method to detect alterations to history. The bitcoin keys are published in the identity's server management subchain. When the server is promoted, or when a new key is added, the new Bitcoin key is published in the Admin block. If a Federated server publishes an update to its chain, the Federated servers place it in the next Admin block. Factom doesn't use this in M2 or on the launch of M3, although these are present in the blockchain.

Like the identity keys, there are multiple levels of authority for the Bitcoin keys. This allows servers to have an out of band backup signaling method when Bitcoin keys are stolen. Anchors placed by higher level keys will alert clients that the lower level Bitcoin key(s) are considered compromised, and not to trust anchors from lower level keys.

Multiple levels of bitcoin keys are specified, but only 1 level is need initially. The max is 4. The same rules for timing and priority level apply to this message as apply to the New Block Signing message.

Bitcoin keys can either be P2PKH or P2SH. The address type byte is set as follows: 0=P2PKH 1=P2SH.

The message is an entry with multiple extIDs. It has a version, a text string saying "New Bitcoin Key". It specifies the root identity chainID. Next is a byte signifying the bitcoin key level. It is 0 origin indexed, so with only 1 key it would be 0x00. The next extID specifies what type of Bitcoin key is used, P2PKH or P2SH. Next is the 20 byte Bitcoin key. Seventh is a timestamp, which prevents replay attacks. Eighth is the identity key preimage. Last is the signature of the serialized version through the timestamp.

[0 (version)] [New Bitcoin Key] [identity ChainID] [Bitcoin key level] [type byte] [new key] [timestamp] [identity key preimage] [signature of version through timestamp]

[00] [4e657720426974636f696e204b6579] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [00] [00] [c5b7fd920dce5f61934e792c7e6fcc829aff533d] [00000000495EAA80] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [379d64dd36ba724539ce19adb05b9a6a98cc3e3171785553e2985f5542a3ce3bf470ef78a884eee2ba75c9f2cfa64f21d3ace4dc981daeb3c00352dbb19a1e0c]

Add New Matryoshka Hash

Factom gets a set of randomness from a series of revealed SHA256 hash preimages. To enforce these to be hash preimages, the last hash in a long hash chain is published. A server will reveal sequential preimages, which are called Matryoshka hashes or M-hashes. This message publishes the outermost hash, which is placed in the Admin block when the server is promoted. Factom doesn't use this in M2 or on the launch of M3, although these are present in the blockchain.

The new M-hash message has the same timing and priority level rules at the block signing key message.

It starts with the version and the text "New Matryoshka Hash". Next is the root identity chainID. Forth is the outermost M-hash. Fifth is a timestamp. Sixth is the root identity key preimage. Last is the signature of the version through the timestamp.

[0 (version)] [New Matryoshka Hash] [identity ChainID] [new SHA256 M-hash] [timestamp] [identity key preimage] [signature of version through timestamp]

[00] [4e6577204d617472796f73686b612048617368] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [bf1e78e5755851242a2ebf703e8bf6aca1af9dbae09ebc495cd2da220e5d370f] [00000000495EAA80] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [b1bc034cf75d4ebf7c4025a6b6b15c8f11a4384dcb043160711f19da9f4efb1315d84811b2247bb703732c2116b464781daf5efe75efd4adc641fee220ec660c]

Add Server Efficiency

The Factom Authority servers are rewarded with new Factoids as part of their service to the protocol. They are each rewarded up to 6.4 Factoids every 25 blocks. As part of being good stewards of the protocol, Authority Servers can run a more efficient operation. They can opt to yeild some percentage of their reward to the Grant Pool. They would define that efficiency with this message. A 100% efficiency leaves all the Factoids in the protocol, while 0% puts the entire reward into the coinbase.

This message needs to be in the server management subchain. If it is not, the default is 100% efficiency. If the message specifies >100% efficiency, the coinbase descriptor defaults to 100% efficiency. Later Server Efficiency messages update older messages. To prevent replay attacks, a timestamp is included. To be valid, the efficiency update must be the latest one seen. It also needs to be included in the blockchain between 12 hours +- of the message timestamp.

The efficiency is serialized as a 16 bit unsigned integer. The percentage is in fixed point format with 2 decimals, so the maximum efficiency of 100% = 10000. An efficency of 49.52% = 4952 = 0x1358.

With a 49.52% efficiency almost half of the 6.4 Factoid Authority reward is yeilded to the Grant Pool. The coinbase would have an output of 3.23072 Factoids for this server. The Grant Pool would increase by 3.16928 FCT from this server.

The message is a Factom Entry with several extIDs holding the various parts. The first part is a version binary string 0. The second is the ASCII string "Server Efficiency". The third is the root identity ChainID. Forth is the new efficiency being asserted. 5th is the timestamp with an 8 byte epoch time. Next is the identity key preimage of the lowest level identity key (id1). 7th is the signature of the serialized version, text, chainID, new efficiency, and the timestamp.

[0 (version)] [Server Efficiency] [identity ChainID] [new efficiency] [timestamp] [identity key preimage] [signature of version through timestamp]

[00] [53657276657220456666696369656E6379] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [1358] [00000000495EAA80] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [2954c40f889d49a561d0ac419741f7efd11e145a99b67485fb8f7c3e3c42d3c698d50866beffbc09032243ab3d375b4c962745c09d1a184d91e5ba69762b4e09]

Coinbase Cancel

There is a chance that a Coinbase Descriptor gets created which is detrimental to the protocol. In order to protect the protocol against economic damage, a pending coinbase transaction can be modified. Since the 1000 block delay between the Coinbase Descriptor and the Coinbase was designed to give the community time to react to unexpected new Factoids. As such, the only change that can be made to a pending coinbase is to reduce one of the outputs to zero, removing it as an output. The canceled output would be retained by the Grant Pool. This means that the system doesn't support generating more Factoids than were described, only fewer. An individual line in a particular coinbase descriptor at a block height is the unit which is addressed.

The process begins with an Authority node discovering that a coinbase descriptor is wrong. After forming social consensus with several other Authority nodes, they will create the Coinbase Cancel message and write it to their Server Management Subchain. The message specifies a block height containing the Admin block with the offending output. It also specifies an index into the coinbase descriptor of the specific output to be canceled (0 origin indexed). Both fields are 4 bytes and big endian unsigned integers.

The message is only valid when it appears in an entry block after the block that the coinbase descriptor appears in and the block just before the coinbase.

The message is a Factom Entry with several extIDs holding the various parts. The first part is a version binary string 0. The second is the ASCII string "Coinbase Cancel". The third is the root identity ChainID. Fourth is the Coinbase Descriptor Height with a cancelation. 5th is the index into the Coinbase Descriptor. Next is the identity key preimage of the lowest level identity key (id1). 7th is the signature of the serialized version, text, chainID, Coinbase Descriptor height, and the index into the Coinbase Desciptor.

[0 (version)] [Coinbase Cancel] [identity ChainID] [Descriptor height] [Desciptor index] [identity key preimage] [signature of version through timestamp]

[00] [436f696e626173652043616e63656c] [888888d027c59579fc47a6fc6c4a5c0409c7c39bc38a86cb5fc0069978493762] [00030d40] [00000005] [0125b0e7fd5e68b4dec40ca0cd2db66be84c02fe6404b696c396e3909079820f61] [68c06b195771f801ff216c0ba98de485e54410c0765d662118aac389e319dcfdee12d11915206ab7d35f6f028584406156840fc30219111750bb1b0bc2b06106]