unboundsecurity / blockchain-crypto-mpc

Protecting cryptographic signing keys and seed secrets with Multi-Party Computation.
GNU General Public License v3.0
456 stars 165 forks source link

2-party BIP32 #8

Closed Wahahahahahahahahahaha closed 4 years ago

Wahahahahahahahahahaha commented 5 years ago

Hi, Recently have read the white paper of the blockchain-crypto-mpc library, but I still confused about that how to use BIP-Key-Derivation to output the shared private keys x1 and x2 of wallet private keys x. How to split the BIP32 seed and get the shared private keys x1 and x2 of wallet private keys x via 2-party BIP32 .I want to know hou to implementation 2-party BIP32 of the library? Looking forward to your reply, thanks

Samuel-Ranellucci commented 5 years ago

Here are instructions on how to run BIP derivation using our python script. If you have any questions, feel free to contact us at contact@unboundtech.com.

Step 1

Install python.

Step 2

Follow the instructions at
https://github.com/unbound-tech/blockchain-crypto-mpc/tree/master/python

Step 3

Open two shells (one for the server, and one for the client) at the same location as the python script "mpc_demo".

Step 4: Initial key initialization

a) Run the following script on the server shell py mpc_demo.py --type generic --command generate --out_file key_share.bin --server b) Run the following script on the client shell py mpc_demo.py --type generic --command generate --out_file key_share2.bin --host localhost

Note: After the protocol has been completed, you should see the text "Generating key..." and "ok" on both shells.

Step 5: BIP derivation

a) Run the following script on the server shell py mpc_demo.py --type BIP32 --command derive --in_file key_share.bin --out_file derived_key_share.bin --server b) Run the following script on the client shell py mpc_demo.py --type BIP32 --command derive --in_file key_share2.bin --out_file derived_key_share2.bin --host localhost

For hardened derivation add --hardened flag. Also, provide --index to identify the derived account. Note: initial derivation should not be hardened and index should be 0 (that's default). After executing the protocol, you should see no errors and "Took

Step 6: Signing

a) Run the following script on the server shell py mpc_demo.py --type ECDSA --command sign --in_file derived_key_share.bin --data_file data.dat --repeat 5 --server b) Run the following script on the client shell py mpc_demo.py --type ECDSA --command sign --in_file derived_key_share2.bin --data_file data.dat --repeat 5 --host localhost

Note: After this protocol is executed, you should see "ECDSA signing.." and "ok" on both sides. In addition, the average time should be shown on the client side.

Wahahahahahahahahahaha commented 5 years ago

hi, I tried to execute the above procedure, but when I reached the step 6: Signing stage, I received an error:
IOError: [Errno 2] No such file or directory: 'data.dat'. Is information of 'data.dat' file signed transaction information? This is just my guess. What shou I do ? Looking forward your replay. Thanks!

mkraitsberg commented 5 years ago

Hi, Wahahahahahahahahahaha,

The 'data.dat' input file is the data you would like to sign.

Wahahahahahahahahahaha commented 5 years ago

Hi, I am glad that I have completed the above process with your help. Now I have studied all the materials related to the blockchain-crypto-mpc, but I still don't deeply understand the theoretical basis of your project , especially the 6 zero-knowledge proofs and key derivation. Have you applied for the patent of your project or published any academic papers? This will help enthusiasts interested in your project articulate the theory behind the your project. Tried source code research, but limited by personal ability, it is a pity that did not succeed!

As far as I know, there is another 2PC-based blockchain key management project on GitHub. Its functions and main technologies have a high degree of coincidence with your project. And its white paper clearly explains the theoretical thinking of his scheme and the sub-algorithm of the protocol. but I think your project has a higher security. I am a theoretical fan in school, and I am very interested in this project. Based on your project, I would like to study how MPC can show its charm in blockchain. Can you provide me with some project documentation to give me a theoretical sense of the greatness of this library. Looking forward your replay so much. Thanks!

Philamericus commented 5 years ago

Hi,

The zero-knowledge proof in items 1 and 2 is described in Section 5.1 of the white paper (referencing the academic paper and the changes). Items 3, 4, and 5 appear in [5] (see Section 3.1 of [5] and references within). There are some slight changes, as mentioned in Section 5.1 of the white paper.

The proof in item 6 is a cut-and-choose based proof that has not been published, but is straightforward.

Unbound Tech has multiple patents on MPC-based solutions, which we will hopefully be putting on our website soon (see here).

Wahahahahahahahahahaha commented 5 years ago

Hi, Thank you for your answer to the zero knowledge proof question. Sorry about I have another question that's what information do key_share.bin and key_share2.bin refer to and how to generate them? I've tried to generate them, but fail to Signature. Maybe because I don't know understand about generating key_share.bin and key_share2.bin. And my operation command of generating them.

mkraitsberg commented 5 years ago

Hi, Wahahahahahahahahahaha, The key_share files contain, not entirely unexpectedly, the key shares. They are produced during key generation, see step 4) above by @Samuel-Ranellucci .

Wahahahahahahahahahaha commented 5 years ago

Hi, but I don't think so. The execution of step 4) relies on the key_share.bin and key_share2.bin to generate derived_key_share.bin. Similarly. The execution of step 5) relies on the key_share.bin and key_share2.bin to generate derived_key_share2.bin. And then The execution of step 6) relies on derived_key_share.bin generated by step 4) and derived_key_share2.bin generated by step 5) to generate signature of transaction data file 'data.dat'. Thus Before performing step 4), the key_share.bin and key_share2.bin were generated. Otherwise, When you execute step 4), the following two error2 (one from server and another from localhost) occurs (1)root@fanliangyun-test-11:/home/mpc/blockchain-crypto-mpc/python# python mpc_demo.py --type generic --command generate --in_file key_share.bin --server Namespace(command='generate', size=256, type='generic') Traceback (most recent call last): File "mpc_demo.py", line 267, in run_server() File "mpc_demo.py", line 201, in run_server out, outputFile = run_command(params) File "mpc_demo.py", line 164, in run_command with open(args.in_file, "rb") as f: IOError: [Errno 2] No such file or directory: 'key_share.bin' (2)root@fanliangyun-test-11:/home/mpc/blockchain-crypto-mpc/python# python mpc_demo.py --type generic --command generate --in_file key_share2.bin --out_file derived_key_share.bin --host localhost Traceback (most recent call last): File "mpc_demo.py", line 270, in run_client() File "mpc_demo.py", line 221, in run_client out, outputFile = run_command(args) File "mpc_demo.py", line 164, in run_command with open(args.in_file, "rb") as f: IOError: [Errno 2] No such file or directory: 'key_share2.bin' Please confirm it. Thanks.

mkraitsberg commented 5 years ago

Hi, The shares should be generated in step 4) indeed. But there was an error in step 4) that probably caused the confusion. Please see the updated version. Also you may refer to the usage comment in the beginning of 'mpc_demo.py' file. Good luck!

Wahahahahahahahahahaha commented 5 years ago

Hi, I suggest maybe you'd better try the above process and the usage comment in the beginning of 'mpc_demo.py' file. Do this will help the development ofyour project. I think there also an error in step4) about " --out_file derived_key_share.bin". Because in step 5), there also has a " --out_file derived_key_share.bin". Thus step 4) and step 5) are in conflict. According to your project white paper, derived_key_share.bin file should be generated by step 5). Also I tried to execute the usage comment in the beginning of 'mpc_demo.py' file last week. And derived_key_share.bin and derived_key_share2.bin are private key's shares for signing , correspond to x1 and x2 of the white paper respectively. So I'm curious and want to know what key_share.bin and key_share2.bin are? According to your project white paper, perhaps "key_share.bin" and "key_share2.bin" refer to seed secret that is another subject of privacy protection osf your project. Please confirm it. I want to understand your great project and don't want to give up. Thank you for your help.

mkraitsberg commented 5 years ago

Hi! Kudos for not giving up! While the instructions in 'mpc_demo.py' are fine, the 'step 4' still did contain a bogus out parameter. I also rewrote the instructions a bit for brevity and clarity. Hope that will help. Regarding the share files meaning, generally speaking - yes, they should contain two shares of some protected split entity, just like there name suggest. In particular, you should see what exactly is created and when. For example, in our favorite step 4), a seed for BIP derivation is generated.

Wahahahahahahahahahaha commented 5 years ago

Thank you so much! I try to do above process again. It's so great to complete the step 1) to the step 5). Sorry about the following error when I execute Step 6 to singing for data.dat. .............................................................................................................................................................................................................. root@fanliangyun-test-11:/home/mpc/blockchain-crypto-mpc/python# python mpc_demo.py --type ECDSA --command sign --in_file derived_key_share.bin --data_file data.dat --repeat 5 --server Namespace(command='sign', size=256, type='ECDSA') ECDSA signing... Traceback (most recent call last): File "mpc_demo.py", line 267, in run_server() File "mpc_demo.py", line 201, in run_server out, outputFile = run_command(params) File "mpc_demo.py", line 176, in run_command out = run_sign(inStr, params.type) File "mpc_demo.py", line 127, in run_sign exec_mpc_exchange(obj) File "mpc_demo.py", line 77, in exec_mpc_exchange messageBufIn = receive_message() File "mpc_demo.py", line 59, in receive_message length = struct.unpack("!i", rec)[0] struct.error: unpack requires a string argument of length 4 ............................................................................................................................................................................................................. root@fanliangyun-test-11:/home/mpc/blockchain-crypto-mpc/python# python mpc_demo.py --type ECDSA --command sign --in_file derived_key_share2.bin --data_file data.dat --repeat 5 --host localhost ECDSA signing... Traceback (most recent call last): File "mpc_demo.py", line 270, in run_client() File "mpc_demo.py", line 221, in run_client out, outputFile = run_command(args) File "mpc_demo.py", line 176, in run_command out = run_sign(inStr, params.type) File "mpc_demo.py", line 127, in run_sign exec_mpc_exchange(obj) File "mpc_demo.py", line 79, in exec_mpc_exchange finished, messageBufOut = perform_step(obj, messageBufIn) File "mpc_demo.py", line 36, in perform_step outMsg, flags = mpc_crypto.step(obj.ctx, inMsg) File "/home/mpc/blockchain-crypto-mpc/python/mpc_crypto.py", line 221, in step test_rv(libmpc.MPCCrypto_step(ctx, in_msg, byref(out_msg), byref(out_flags))) File "/home/mpc/blockchain-crypto-mpc/python/mpc_crypto.py", line 32, in test_rv raise MPCException(rv) mpc_crypto.MPCException ............................................................................................................................................................................................................. So what should I do? waiting for your help!

mkraitsberg commented 5 years ago

Hi! Glad to hear about your progress. Regarding your new issue with step 6), I am a bit at loss, not being able to reproduce it. My immediate suspicion is some kind of confusion with shares. Thus, I would propose to delete all the *share.dat file and run steps 4-6 again from scratch. If that doesn't help, another attempt may be to reproduce your exact conditions (the data.dat file you use/ exact python version/ something else?).

Wahahahahahahahahahaha commented 5 years ago

What are the conditions for data.dat file established by me? The following is content data.dat file established by me : d5ada064c6417ca25c4308bd158c34b77e1c0eca2a73cda16c737e7424afba2f And the version of python is Python 2.7.15+ Is there any qusetion? Thanks!

Wahahahahahahahahahaha commented 5 years ago

And I do above process that you proposed to delete all the *share.bin file and run steps 4-6 again. Sorry about that the question remains unresolved

mkraitsberg commented 5 years ago

Hi! I turns out the problem is input (data.dat) length, it shouldn't exceed 32 bytes. The reason behind this requirement is that input data is assumed to be hashed before signing. (EdDSA algorithm is an exception, hashing is done internally there as part of the signing and thus the input may be of arbitrary length.) I am going to add length validation accordingly. Thanks for your help in improving our project!

Wahahahahahahahahahaha commented 5 years ago

Hi, Thank you so much for answering my questions again and again. The test of python_demo.py has passed.
Personally, I think your project has greatly enhanced the security of blockchain wallet, very nice. But after a long time of study and research, I still don't understand how it realizes the distribution of private keys, that's how to realize the functionalites of Generate generic secret and BIP derivation described in the section 3 of the white paper. could you give me some suggestion about this? And What's limiting the length of data.dat shouldn't exceed 32 bytes, which largely limits Practical application of this great project. If this question can be resolved, I think there will be many blockchain project develop their wallet that without private key to improve security.

Samuel-Ranellucci commented 5 years ago

Hi,

I will get back to you by Sunday.

Best Regards,

Samuel Ranellucci

mkraitsberg commented 5 years ago

Great, we did it! Regarding the nature of 32-bytes requirement and why it is not a real limitation, please refer to my previous comment. Considering your further questions I leave you in good hands of @Samuel-Ranellucci, our cryptography expert being back from summer vacation.

Samuel-Ranellucci commented 5 years ago

Hi,

In this explanation, we focus on soft derivation (as opposed to hardened derivation), and we will keep the description high-level.

First, we will describe a naive approach of how BIP derivation is done. At a high level, a garbled circuit allows two parties to securely compute a boolean circuit. For the task of BIP derivation, each player inputs their shares of the old key, new account information, and the circuit gives a shares of the new private key to each player.

However, a corrupt player can break the security of this protocol by providing bad input shares. To deal with this problem, we modify the garbled circuit to produce multiple pairs of values instead of one. The garbled circuit will randomly choose half of the values to verify that the corrupt party did not tamper with values, the other half will be used to extract the output. A corrupt player can only cheat if he correctly guesses which half is the one used for verification. This only occurs with almost zero probability.

In the cryptographic literature, the above technique is known as cut-and-choose. For more details about BIP derivation, see section 5.2 of the white paper at

https://github.com/unbound-tech/blockchain-crypto-mpc/blob/master/docs/Unbound_Cryptocurrency_Wallet_Library_White_Paper.md

zekik64 commented 4 years ago

Hi @Samuel-Ranellucci, @mkraitsberg,

Apologies for jumping onto this thread, but I'm attempting the same thing as @Wahahahahahahahahahaha.

I've followed the instructions posted above and can successfully run the python demo, so thank you for posting them. However, I'm trying to figure out what the public key is from one of the derived key shares. I can see that there is a function named getPublic() which I have called. This returns me the following data if I do a print:

b'0V0\x10\x06\x07*\x86H\xce=\x02\x01\x06\x05+\x81\x04\x00\n\x03B\x00\x04\x18\xe1Dn)\xa9G\xc6\xf3\x8b\xd1\xa2"\xfc]\xb0!\xe1Y\xd3\xcd\x8b\t!S\x17\x81\xe0O\xd1\x1a\xc9vA\xb1\xc4^\xb4\x93\x9f|\xf0\x1at\x85r\xc3\xd4\x95\'\xc8u\x0e\x84\x83\n\xf0\x0f\xfa\xf1\xf0\xdc\x16\xc9'

If I call .encode("hex") on this data I get:

'3056301006072a8648ce3d020106052b8104000a0342000418e1446e29a947c6f38bd1a222fc5db021e159d3cd8b0921531781e04fd11ac97641b1c45eb4939f7cf01a748572c3d49527c8750e84830af00ffaf1f0dc16c9'

Is what I'm doing correct? I've tried to use the public key to verify a signature generated from my keyshares using an online tool (https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html) and it hasn't worked (which would suggest my public key is wrong)

Any help would be greatly appreciated.

Thanks, Zeki

Philamericus commented 4 years ago

@zekik64 - I apologize for the delay. We'll pick this up on the other issue that you opened.