The challange of stealth transaction and zero knowledge transactions.
stealth by February all I care about! I'm not a criminal. thanks.
Stealth transactions (in my opinion) are imperative to the survival of Liberty. February is my goal for the formal Stealth launch, but this has to be perfect, via the cryptography that we have to work with right now. Zero Knowledge ("zk") transactions are the holy grail of financial privacy, and I want this to be impenetrable. Besides completion of the UI for Stealth, there was one final issue with Stealth that we had to tackle, called "trusted setup".
What is trusted setup?
zkSNARK allows us to implement the perfect anonymity, the only issue is the fact that verification of the proof requires some interaction among Prover and Verifier. They should generate some kind of “shared secret”, after that the Prover can prove something without disclosing any additional info. But this way is not acceptable in cryptocurrencies for transaction verification, because it's impossible to interact with the transaction issuer every time somebody verifies the transaction. The workaround for this issue is pre-generation of this “shared secret” (usually it is called public parameters, or "pp") for all transactions and Verifiers at the very beginning. Very roughly speaking this pp is the constant value in the zkSNARK library code. The problem is that if somebody knows some data (let’s call it “toxic waste”) that was used during this pp generation, he can counterfeit any proof that was generated with using this pp. Library authors didn’t include this pp in the original zkSNARK implementation code because it is difficult to prove that they didn’t know this toxic waste for this predefined pp. So every zkSNARK client app should invent the way to generate this pp and prove to the community the fact that they are not storing the toxic waste for this pp. If they can do that, then it is safe to use the same pp in every other app that uses zkSNARK in the future. Zcash was the first client app with the zkSNARK library and that’s why they should generate this pp. If this pp generation is safe, then we can use the same pp value. If we think this generation is not safe, then we can generate it one more time in another, safer way. If zkSNARK has the pp generated one time in a safe manner, then all the other apps that use it don’t need any trusted setup or something like this anymore.
What is wrong with Zcash trusted setup?
The only weak place in Zcash cryptography is in the pp generation, usually called the trusted setup. They found the way to generate it in a safe enough manner, but were criticized because it's still the weakest place in their system (but it’s still safer than many other cryptocurrency weak places are). They can generate this pp by several participants so that if at least one of the participants will not save his part of the toxic waste and share it with other trusted setup participants, pp generation will be safe and nobody can counterfeit the generated proofs. Their error was that they use a predefined small number of participants, so it's possible that the 6 participants weren’t honest and modified the pp generator code and saved their toxic waste parts. All other procedures were safe; there are several participants, if only one of the participants is honest then the generation is safe, and there are participants that are not associated with Zcash.
How can we improve upon their trusted setup?
Our main idea is to allow anyone/everyone to participate in the trusted setup who's interested in security. These participants should not only be the members of the Bitshares community, but there are at least several Zcash forks that need zkSNARK pp too. So we are preparing a generator (open source of course), that every web user can install and start it on a predefined date, and the network of these generators will generate safe pp for zkSNARK. If only one of these users will be honest and will not save his part of the toxic waste, the pp is safe and can be used (not only by Bitshares, but by any other zkSNARK client too (Zcash forks, for example)). So if you don’t want to trust anybody in trusted setup you can just participate in this setup and be sure it was honest by destroying your part of the toxic waste (you don’t need to do something special for this, just build the source code without modification and start up the generator).
The main risk in this case is performance (the more participants, the more generation rounds), so in the worst case we should limit the number of participants. We think it’s ok however, because Bitshares already has a set of trusted members (thanx to DPOS). It can be any number of Committee members, Witnesses, or Stakeholders, for example. We hope to create the algo without any participation limits and should be finished with it very soon.
We have kept the new algo (more or less) the same in our libsnark implementation (github.com/kenCode-de/libsnark), and mainly edited the build scripts to facilitate this “trustless” setup redesign. This procedure should be started only once and after that, its result will be hardcoded into the code. Stealth transactions will not require any additional actions from any Bitshares system participants.
BlockPay of course, will soon include this extra layer of privacy via Stealth transactions as an option in the Settings screen.
edit: ps: I will post my normal weekly update in just a few hours...
More IPFS updates from us.
https://github.com/kenCode-de?tab=repositories
C-IPFS and BlockPay related:
To align the hashes with what is stored in the Go version of IPFS, the hashes must match. That was the purpose of these commits this week:
https://github.com/kenCode-de/c-ipfs/commit/914d3caaeda5cfbdcb2a9f5cf80012768b496262
https://github.com/kenCode-de/c-ipfs/commit/8d2aeab0167a7e5145d07659c6d0e5a03ef9fd41
https://github.com/kenCode-de/c-ipfs/commit/15b432c70e977b9682b35c9690e6a10b49f42b03
https://github.com/kenCode-de/c-ipfs/commit/1dcbf8962e14d490ee331668966b3dff2bc54754
https://github.com/kenCode-de/c-ipfs/commit/3004f1411a121c9e7a085e6945a6de93c452a8b4
https://github.com/kenCode-de/c-ipfs/commit/8f44c857db04812267928f69b69177ab8597949c
After that, we began working on importing of directories...
https://github.com/kenCode-de/c-ipfs/commit/9d77b2709f6e59b7dc388b7136466dd35b9e65df
https://github.com/kenCode-de/c-ipfs/commit/fa3dd77e96544863c238096a23442ddc28dd4263
..and making the directory hash match the Go version:
https://github.com/kenCode-de/c-ipfs/commit/396dfc6abc45d664c5240e002a3295fe991b0b67
We have now added the code to retrieve a file based on the hash of the directory and the path to the file:
https://github.com/kenCode-de/c-ipfs/commit/addb5ba302cdb102a6ec2362d64adb2a5655ed42
The storage system is now to a point where it is functional and installable. It is not perfectly tested, but a damn good number of use cases work.
What is planned for the coming week:
More testing / commenting / docs (the IPFS community will be helping us with this)
Error handling around user input and better responses to the user
Resolving files across networks
More c-ipfs and c-ipns(lots of speed improvements thanx to our protobuf completion) commits:
https://github.com/kenCode-de/c-ipfs/commit/00bf29b0fafc37e7e058c8cfa2d43d6b5c891fe9
https://github.com/kenCode-de/c-ipfs/commit/37bab54a5c7d7cb4015ec97bb0e9515f4f9c952e
https://github.com/kenCode-de/c-ipfs/commit/d9774095d3948afd4abd537ea8d80d42e77b96ea
https://github.com/kenCode-de/c-ipfs/commit/ef380f2a6915e978bbd9f28fb7a7a1b495c6e94d
https://github.com/kenCode-de/c-ipfs/commit/9d194ad484a540cad515c015ca203f8abb847200
https://github.com/kenCode-de/c-ipfs/commit/f7a029ade3422fe636373df721925d265bedcc16
..and more:
"ipfs add [filename]" and "ipfs add -r [directory]" are now both functional
"ipfs object get [hash]" and "ipfs object get [path]" are now both functional
namesys-protobuf, c-ipfs-node and CJDNS basic support are also complete
Early next week we will finish pin, routing, libp2p-routing and c-ipns.
The CLI was released right before Christmas, and we now have Pre-Releases ready for Linux and Mac here:
https://github.com/kenCode-de/c-ipfs/releases
We should also have a Windows, and first formal Release for all platforms ready by next week at the link above.
Android Smartcoins Wallet and security audits:
We found a very rare bug that was preventing the storage of newly created keys to persistent storage. The previous procedure was storing them in memory and just promoting them to the shared preferences once we got the response back from the network and the account update procedure was deemed successful. This of course leaves a small breach that would happen if something were to happen in case the account update was successful, but the network response failed to reach the user. The situation described before never actually happened, but it could be emulated by purposely crashing the thread at a very specific point. Most users are not going to try to crash a thread on purpose.
The code written to treat this very rare situation also took special care of checking if the stored key actually does match the public address of the "active" role of the account, and only then it proceeds to replace it. The described changes can be inspected in this commit (https://github.com/kenCode-de/smartcoins-wallet/commit/4ea07e741223680363225c5a038769988927a95f).
After having added support for the 'get_market_history' API call in our new graphenej library (https://github.com/kenCode-de/graphenej), this was introduced in the Smartcoins Wallet and used to obtain the historical market data, which in turn is useful to calculate the equivalent fiat values of past transactions. This was previously being done on-demand every time the app was restarted, a solution which was very inefficient and actually wrong, because the equivalent values were being calculated with current values, not past ones.
With the new changes introduced, after a batch of transactions is loaded and stored into the database, the app will perform a query looking for historical transactions that don't have an equivalent fiat value. With this in hand, the aforementioned 'get_market_history' API call is used to obtain historical market data and calculate the equivalent value.
Because not every token might have a very active market with the user desired Smartcoin, we make a 2-step equivalent value calculation. First calculating the historical relationship of the token with the BTS, and then in turn finding out how much that amount of BTS would have been in bitUSD or bitEUR (or the desired Smartcoin) at that point in time.
If the transaction was already made in BTS the first step was avoided, and if it was already a Smartcoin no conversion is needed of course. Every one of these special cases was treated and upgraded.
Also a mapping was created to match the location of the user with a set of Smartcoins. If no Smartcoin exists for a specific country (a situation that applies for most countries actually) then bitUSD is now used as a default.
The relevant commits for this work are:
https://github.com/kenCode-de/smartcoins-wallet/commit/0decd87e1f8160d98e7d77b458cae698072b67d0
https://github.com/kenCode-de/smartcoins-wallet/commit/ee7ac88eb45dd21fb19353d44f9e8f92bc029a51
https://github.com/kenCode-de/smartcoins-wallet/commit/39b581d17a36e230b779bd7e9451f5018bb1c060
And a more detailed description of the specific details about this procedure:
Transactions loading (on the home screen) - The procedure to load the database with historical transfers is somewhat complex due to the fact that what we want to display and what the API gives us is slightly different. Namely time and equivalent value information is missing. There is of course ways to obtain this data, but more on the specifics of this later. Let us first focus on obtaining the list of transactions and display whatever it already gives us.
The list of historical transactions is obtained by using the ‘get_relative_account_history’ API call. And even though this call has a hard limit on 100 operations per request, we can easily schedule a new request in case we note the user might have more than 100 transactions already. It is not really a problem to chain operations like this, since this procedure is only performed once upon installation to initially fill the database with operations performed prior to the apps' (Smartcoins Wallet and BlockPay both) install.
With this in place, we can already display information about what was sent, and if it was an incoming or outgoing transaction. A quick search to this newly loaded database can also give us the list of assets used and that information is used to obtain more information about each one of them. Specifically we would like to know each asset’s symbol and precision, in order to properly format them to the user. So that we can display USD 1.00 to the user instead of its raw value of 1000 for instance.
The first complication arises from the fact that the list of operations retrieved by this API call doesn’t explicitly have the time information in it. Instead each operation does indicate the block number in which it was included in the blockchain.
By taking the block number information however, we can then use the ‘get_block_header’ API call to get the UTC time for that specific block. The downside of this API call is that it doesn’t support batched calls. That is, a request has to be made specifically for every missing block header. This can be time-consuming, especially if we decide to load all historical transfer’s time information and then proceed to calculate equivalent values.
Since the user is more likely to be interested in the most recent transactions first, and recalling that this operation is only performed ONCE upon app install, it was decided to split the timestamp query and equivalent value calculations into batches. So this way the app will load all transactions first, and display the information about every transfer without any date and time or equivalent value first.
Then we’ll proceed to load date time information from top to bottom, but not going all the way down the list. But instead stopping at a specific batch size, and then proceed with the equivalent value calculation. In other words, don't annoy the user.
Please note that the equivalent value calculation depends on us having the specific date and time for every operation, since we’re using the ‘get_market_history’ API call, which takes a timestamp information instead of block number.
The timestamp query and the equivalent values thus are performed going from most recent to older transactions, which will appear low in the list anyways. Once this operation is finished, the app will just query the local database.
This initial database loading operation can take a while to conclude, but since it is done in the background by threads filling in the database the user doesn’t have to wait for it to conclude and is free to use the app. He can even interrupt the procedure by pressing the home button, and it will just resume from where it left when the app is reopened.
With the information about historical equivalent values in the databse, it was now possible to re-enable the "export to PDF/CSV" and "eReceipt" functionalities (which will be included in v1.5.6). This was done here:
https://github.com/kenCode-de/smartcoins-wallet/commit/a341882bb4e96c567be545be5c8641b2eb73b116
https://github.com/kenCode-de/smartcoins-wallet/commit/6e4325bfd6a51bc912a70b80879946e10c9e7c28
More features updated:
Caching for getAssets (more speed improvements)
Changing BalanceFragment Structure (Separating the view from the logic for the future c-ipfs integration)
As always, never keep more money in your wallet than you can afford to lose. Latest release can be downloaded from google play:
https://play.google.com/store/apps/details?id=de.bitsharesmunich.smartcoinswallet
Stealth related:
Finishing the "trustless" setup algo now, see my details on that in the forum post just above.
UI now being worked on, will upload more screenshots soon.