markkurossi / mpc

Secure Multi-Party Computation (MPC) with Go. This project implements secure two-party computation with Garbled circuit protocol.
https://www.markkurossi.com/mpcl/index.html
MIT License
106 stars 21 forks source link

How to run HMAC ? #15

Closed lucy-sha512 closed 1 year ago

lucy-sha512 commented 1 year ago

I am new to this repo. I want to run the HMAC circuit. Can you guide how to run it?

markkurossi commented 1 year ago

I added an HMAC-SHA256 example to apps/garbled/examples/hmac-sha256.mpcl. The computation goes as follows:

The garbler and evaluator share the HMAC key as random key shares. As an example, the garbler's share is:

keyG: 4de216d2fdc9301e5b9c78486f7109a05670d200d9e2f275ec0aad08ec42af47
      fcb59bf460d50b01333a748f3a9efb13e08036d49a26c21ba2e33a5f8a2cf0e7

and the evaluator's share is:

keyE: f87a00ef89c2396de32f6ac0748f6fa1b641013d46f74ce25cc625904215a675
      01c0c7196a2602f6516527958a82271847933c35d170d98bfdb04d2ddf3bb197

and the resulting HMAC key is keyG^keyE:

key : b598163d740b0973b8b312881bfe6601e031d33d9f15be97b0cc8898ae570932
      fd755ced0af309f7625f531ab01cdc0ba7130ae14b561b905f53777255174170

The example must define the message lengths - this example uses 32-byte messages (Garbler.msg [32]byte) - so let's use the following message:

msg : Hello, world!...................
hex : 48656c6c6f2c20776f726c64212e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e

and we should get the following HMAC-SHA256 output:

sum : 60d27dbd14f1e351f20069171fead00ef557d17ac9a41d02baa488ca4b90171a

Now we can run the MPC protocol. First, run the evaluator with one input: the evaluator's key share:

./garbled -e -v -i 0xf87a00ef89c2396de32f6ac0748f6fa1b641013d46f74ce25cc625904215a67501c0c7196a2602f6516527958a82271847933c35d170d98bfdb04d2ddf3bb197 examples/hmac-sha256.mpcl

The garbler takes two inputs: the message and the garbler's key share:

./garbled -v -i 0x48656c6c6f2c20776f726c64212e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e,0x4de216d2fdc9301e5b9c78486f7109a05670d200d9e2f275ec0aad08ec42af47fcb59bf460d50b01333a748f3a9efb13e08036d49a26c21ba2e33a5f8a2cf0e7 examples/hmac-sha256.mpcl

The MCP computation providers the expected HMAC result:

Result[0]: 60d27dbd14f1e351f20069171fead00ef557d17ac9a41d02baa488ca4b90171a
lucy-sha512 commented 1 year ago

Thanks for this. But how do you generate the keyshares . Is there an algorithm in this library to do it? I am getting the following error while trying to run the above.

could not resolve pkg root directory, tried:
 - $(MPCLDIR):
   - $(MPCLDIR)/pkg
 - $(GITHUB_WORKFLOW):
   - $(GITHUB_WORKSPACE)/pkg
 - *:
   - $(HOME)/go/src/github.com/markkurossi/mpc/pkg
could not find pkg root directory

Could you throw some light on why this is happening?

markkurossi commented 1 year ago

The HMAC keys are random so both parties could generate their key shares independently, for example, with the crypto/rand package and persist them locally.

The error comes from the garbled application when it can't find its library pkg files. The search is done:

  1. from the directory, pointed by the MPCLDIR environment variable
  2. directory, pointed by the GITHUB_WORKFLOW environment variable
  3. from the user's home directory using the default Go source directory go/src/. So if you clone the repository to $HOME/go/src/github.com/markkurossi directory, you don't have to set any additional environment variables
lucy-sha512 commented 1 year ago

I want to use my own key for hmac. How can I generate secret shares for it?

markkurossi commented 1 year ago

Added example apps/garbled/examples/key-import.mpcl that shows how to import a key and create random shares of it. It works as follows:

This example shows how a key can be imported to MCP peers garbler and evaluator so that after the import operation both peers hold a random share of the key, and shareG^shareE=key.

The garbler provides three arguments:

The evaluator provides two arguments: the split and the mask values.

The MPC program splits the key into two random shares:

The result shares are masked with respective masks and returned as the result of the computation:

Finally, both parties can extract their key shares because the know their mask values:

Using the example values:

key:    a968f050ebd5c4ed2ddf9717f0f0fd9325b07c68ff5d62094800f5b69464bab9
        8dd886a7c49460503fafa75f5f7430f2cdda7bd5cb60c1cbd471e35d67432d58
splitG: 7e1d9bb27838f5c8481b7194f07b5f3059f9471ae8e69ea3fe79c629a92588d9
        524a6e4364e77d222210135f6c5435a8be52fc99ad8fc8280e8207cac91fc7b3
maskG:  bed1bc2a3e6089bd016ff0175c62346438a9eb7b741f41787e5f7aad1720ee08
        233a89e81e3bbd5eef26d158750a0fdd47471ded518d781f23de6d4346ea68ad

splitE: b2146ed7385d63a76f599b27f03e83971149208b0c41604eea010806460a3266
        93820075bc25c485b2bfcb9226488ba961eeb07980f8ab374b38f793e41e5247
maskE:  a0698ff8e72f51bf3bff3895c80a8ba8a527abaa5a7603391545ed5dcebb22b5
        a2f191bcb3ac3a543cfdba99bded67a3ac6f5f254ff7e5c34520312c9b91f672

we run the evaluator with two arguments:

./garbled -e -v -i 0xb2146ed7385d63a76f599b27f03e83971149208b0c41604eea010806460a326693820075bc25c485b2bfcb9226488ba961eeb07980f8ab374b38f793e41e5247,0xa0698ff8e72f51bf3bff3895c80a8ba8a527abaa5a7603391545ed5dcebb22b5a2f191bcb3ac3a543cfdba99bded67a3ac6f5f254ff7e5c34520312c9b91f672 examples/key-import.mpcl

and the garbler with three arguments:

./garbled -v -i 0xa968f050ebd5c4ed2ddf9717f0f0fd9325b07c68ff5d62094800f5b69464bab98dd886a7c49460503fafa75f5f7430f2cdda7bd5cb60c1cbd471e35d67432d58,0x7e1d9bb27838f5c8481b7194f07b5f3059f9471ae8e69ea3fe79c629a92588d9524a6e4364e77d222210135f6c5435a8be52fc99ad8fc8280e8207cac91fc7b3,0xbed1bc2a3e6089bd016ff0175c62346438a9eb7b741f41787e5f7aad1720ee08233a89e81e3bbd5eef26d158750a0fdd47471ded518d781f23de6d4346ea68ad examples/key-import.mpcl

The program returns two values: garbler's and evaluator's masked key shares:

Result[0]: 72d8494f7e051fd2262d1aa45c27e8c370198cea90b8bf956a27b482f80f54b7e2f2e7dec6f904f97f8909953f16b1dc98fb510d7cfa1b0066649d1a6bebfd59
Result[1]: c5088acd4c9f033d3162453138bfaa9cc827b053418c9fdd493dd6c4b5f022b3eee1792daffae3a393fdc50ba885e950be096810a9e04717d4eb2228d1d34ede

and both peers can extract their key shares by XOR:ing their result with their mask value:

shareG: cc09f5654065966f2742eab30045dca748b06791e4a7feed1478ce2fef2fbabf
        c1c86e36d8c2b9a790afd8cd4a1cbe01dfbc4ce02d77631f45baf0592d0195f4
shareE: 65610535abb052820a9d7da4f0b521346d001bf91bfa9ce45c783b997b4b0006
        4c10e8911c56d9f7af007f9215688ef312663735e617a2d491cb13044a42b8ac

and we see that shareG^shareE = key

lucy-sha512 commented 1 year ago

Thank you so much for this. It was really helpful. One last query . The hmac here is implemented via sha_3_256 circuit right?