In Bitcoin, this is simply a pile of random secrets, randomly generated, but obviously it is frequently useful to have them not random, but merely seemingly random to outsiders. One important and valuable application of this is the paper wallet, where one can recreate the wallet from its master secret, because all the seemingly random secret keys are derived from a single master secret. But this does not cover all use cases.
Supposing Carol wants to talk to Dave, and the base point is B. Carols secret is the scalar `c`, and her public key is elliptic point `C=c*B`. Similarly Dave’s secret is the scalar `d`, and his public key is elliptic point
One flaw in this is that if Dave’s secret leaks, not only can he and the people communicating with him be spied upon, but he can receive falsified messages that appear to come from trusted associates.
That is assuming Carol needs to identify. If this is just a random anonymous client connection, in which Dave responds the same way to every client, all she needs to send is `R` and `D`. She does not need forward secrecy, since not re-using `R`. But chances are Dave does not like this, since chances are he wants to generate a record of the distinct entities applying, so a better solution is for Carol to use as her public key when talking to Dave `hash(c, D)*B`
Sometimes we are going to onion routing, where the general form of an onion routed message is \[`R, D,` encrypted\] with the encryption key being `d*R = r*D`. And inside that encryption may be another message of the same form, another layer of the onion.
But this means that Dave cannot contact Carol. But maybe Carol does not want to be contacted, in which case we need a flag to indicate that this is an uncontactable public key. Conversely, if she does want to be contactable, but her network address changes erratically, she may need to include contact info, a stable server that holds her most recent network address.
Likely all she needs is that Dave knows that she is the same entity as logged in with Dave before. (Perhaps because all he cares about is that this is the same entity that paid Dave for services to be rendered, whom he expects to keep on paying him for services he continues to render.)
The common practical situation, of course is that Carol@Name wants to talk to Dave@AnotherName, and Name knows the address of AnotherName, and AnotherName knows the name of Dave, and Carol wants to talk to Dave as Carol@Name. To make this secure, have to have have a a commitment to the keys of Carol@Name and Dave@AnotherName, so that Dave and Carol can see that Name and AnotherName are showing the same keys to everyone.
The situation we would like to have is a web of public documents rendered immutable by being linked into the blockchain, identifying keys, and a method of contacting the entity holding the key, the method of contacting the identity holding the key being widely available public data.
If using `d*C` as the identifier, inadvisable to use a widely known `C`, because this opens attacks via `d`, so `C` should be a per host public key that Carol keeps secret.
Suppose it is obvious that you are talking to Dave, because you had to look up Dave’s network address, but you do not want third parties to know that *Carol* is talking to Dave. Assume that Dave’s public key is the only public key associated with this network address.
We would rather not make it too easy for the authorities to see the public key of the entity you are contacting, so would like to have D end to end encrypted in the message. You are probably contacting the target through a rendevous server, so you contact the server on its encrypted key, and it sets up the rendevous talking to the wallet you want to contact on its encrypted key, in which case the messages you send in the clear do not need, and should not have, the public key of the target.
Suppose there are potentially many public keys associated with this network address, as is likely to be the case if it is a slave wallet performing Pop and Imap like functions. Then it has one primary public key for initiating communications. Call its low value primary keys p and P. Then Carol sends `R` in the clear, followed by `D` encrypted to `r*P = p*R`, followed by `C` and `r*D`, encrypted to `r*D = d*R`.
We can do this recursively, and Dave can return another, possibly transient, public key or public key chain that works like a network address. This implies a messaging system whose api is that you send an arbitrary length message with a public key as address, and possibly a public key as authority, and an event identifier, and then eventually you get an event call back, which may indicate merely that the message has gone through, or not, and may contain a reply message. The messaging system handles the path and the cached shared secrets. All shared secrets are in user space, and messages with different source authentication have different connections and different shared secrets.
Bitcoin just generates a key at random when you need one, and records it. A paper wallet is apt to generate a stack of them in advance. They offer the option of encrypting the keys with a lesser secret, but the master secret has to be stronger, because it has to be strong enough to resist attacks on the public keys.
On reflection, there are situations where this is difficult – we would like the customer, rather than the recipients, to generate the obfuscation keys, and pay the money to a public key that consists of the recipients deeply held secret, and a not very deeply held obfuscation shared secret.
This capability is redundant, because we also plan to attach to the transaction a Merkle hash that is the root of tree of Merkle hashes indexed by output, in Merkle-patricia order, each of which may be a random number or may identify arbitrary information, which could include any signed statements as to what the obligations the recipient of the payment has agreed to, plus information identifying the recipient of the payment, in that the signing key of the output is s\*B+recipient_public key. But it would be nice to make s derived from the hash of the recipients offer, since this proves that when he spends the output, he spends value connected to obligations.
Such receipts are likely generated by a slave wallet, which may well do things differently to a master wallet. So let us just think about the master wallet at this point. We want the minimum capability to do only those things a master wallet can do, while still being future compatible with all the other things we want to do.
When we generate a public key and use it, want to generate records of to how it was generated, why, and how it was used. But this is additional tables, and an identifier in the table of public keys saying which additional table to look at.
One meaning per public key. If we use the public key of a name for many purposes, use it as a name. We don’t use it as a transaction key except for transactions selling, buying, or assigning that name. But we could have several possible generation methods for a single meaning.
And, likely, the generation method depends on the meaning. So, in the table of public keys we have a single small integer telling us the kind of thing the public key is used for, and if you look up that table indicated by the integer, maybe all the keys in that table are generated by one method, or maybe several methods, and we have a single small integer identifying the method, and we look up the key in that table which describes how to generate the key by that method.
So, a table of public key private key pairs, with a small integer identifying the use and whether the private key has been zeroed out, and a table of names, with the rowid of the public key. Later we introduce more uses, more possible values for the use key, more tables for the uses, and more tables for the generation methods.
A wallet is the data of a Zooko identity. When logged onto the interent is *is* a Zooko triangle identity or Zookos quandrangle identity, but is capable of logging onto the internet as a single short user identity term, or logging on with one peer identity per host. When that wallet is logged in, it is Zooko identity with its master secret and an unlimited pile of secrets and keys generated on demand from a single master secret.
We will want to implement the capability to receive value into a key that is not currently available. So how are we going to handle the identity that the wallet will present?
Well, keys that have a time limited signature that they can be used for certain purposes in the name of another key are a different usage, that will have other tables, that we can add later.
A receive only wallet, when engaging in a transaction, identifies itself as Zooko identity for which it does not have the master key, merely a signed authorization allowing it to operate for that public key for some limited lifetime, and when receiving value, requests that value be placed in public keys that it does not currently possess, in the form of a scalar and the public key that will receive the value. The public key of the transaction output will be s\*B+`D`, where s is the obfuscating value that hides the beneficiery from the public blockchain, B is the base, and `D` is the beneficiary. B is public, s\*B+`D` is public, but s and `D` are known only to the parties to the transaction, unless they make them public.
The implementation can and will vary from one peer to the next. The canonical form is going to be a Merkle-patricia dac, but the Merkle-patricia dac has to be implemented on top of something, and our first implementation is going to implement the Merkle-patricia dac on top of a particular sqlite database with a particular name, and that name stored in a location global to all programs of a particular user on a particular machine, and thus that database global to all programs of that particular user on that particular machine.
Then we will implement a global consensus Merkle-patricia dac, so that everyone agrees on the one true mapping between human readable names, but the global consensus dac has to exist on top of particular implementations run by particular users on particular machines, whose implementation may well vary from one machine to the next.
A patricia tree contains, in itself, just a pile of bitstreams. To represent actual information, there has to be a schema. It has to be a representation of something equivalent to a pile of records in a pile of database tables. And so, before we represent data, before we create the patricia tree, have to first have a particular working database, a particular implementation, which represents actual data. Particular database first, then we construct universal canonical representation of that data second.
In every release version, starting with the very first release, we are going to have to install a database, if one is not already present, in order that the user can communicate with other users, so we will have no automagic creation of the database. I will manually create and install the first database, and will have a dump file for doing so, assuming that the dump file can create blobs.
A receive only wallet contains the public key and zooko name of its master wallet, optionally a thirty two byte secret, a numbered signed record by the master wallet authorizing it to use that name and receive value on the master wallet secret and its own public key.
A zooko quandrangle identifier consists of a public master key, a globally accepted human readable name globally accepted as identifying that key, a local human readable petname, normally identical to the global name, and an owner selected human readable nickname.
A contact consists of a public key, and network address information where you will likely find a person or program that knows the corresponding private key, or is authorized by that private key to deal with communications.
So, first thing we have to do is create a wxWidgets program that accesses the database, and have it create Zooko’s triangle identities, with the potential for becoming Zooko’s quandrangle identities.
Supposing you are sending value to someone, who has a big important reputation that he would not want damaged. And you want proof he got the value, and that he agreed to goods, services, or payment of some other form of money in return for the value.
Well, if he has a big important reputation, chances are you are not transacting with him personally and individually through a computer located behind a locked door in his basement, to which only he has the key, plus he has a shotgun on the wall near where he keeps the key. Rather, you are transacting with him through a computer somwhere in the cloud, in a big computing center to which far too many people have access, including the computer center management, police, the Russian mafia, the Russian spy agency, and the man who mops the floors.
So, when "he", which is to say the computer in the cloud, sends you public keys for you to put value into on the blockchain, you want to be sure that only he can control value you put into the blockchain. And you want to be able to prove it, but you do not want anyone else except you and he (and maybe everyone who has access to the data center on the cloud) can prove it except you make the data about your transaction public.
You are interacting with a program. And the program probably only has low value keys. It has a key signed by a key signed by a key signed by his high value and closely held key, with start times and timeouts on all of the intermediate keys.
So he should have a key that is not located in the datacenter, and you want proof that only the holder of that key can spend the money – maybe an intermediate key with a timeout on it that authorizes it to receive money, which signs an end key that authorizes the program to agree to deals, but not to receive money – the intermediate key authorized to receive money presumably not being in the highly insecure data center.
This document is licensed under the [CreativeCommons Attribution-Share Alike 3.0 License](http://creativecommons.org/licenses/by-sa/3.0/){rel="license"}