[{"data":1,"prerenderedAt":15},["ShallowReactive",2],{"news-auction-demo-a-tutorial-on-using-the-sharemind-mpc-platform":3},{"articles":4},[5],{"documentId":6,"title":7,"slug":8,"createdAt":9,"publishingDate":10,"description":10,"content":11,"quote":10,"postAuthor":10,"thumbnail":10,"relatedProducts":10,"industry":10,"relatedPosts":12,"metaData":13},"s9fsnvq5j36nsfrllo1aiw7n","Auction demo - a tutorial on using the Sharemind MPC platform","auction-demo-a-tutorial-on-using-the-sharemind-mpc-platform","2021-07-07T13:59:55.000Z",null,"_This time our blog post features a small tutorial on using the Sharemind MPC platform._\n\n## Storyline\n\nI chose a very simple problem that has 3 stakeholders: Alice, Bob and Charlie (sorry for being so unimaginative with the names, but they are [familiar to cryptographers](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAlice_and_Bob)).\n\nThe story goes that Charlie wants to sell his house on the beach. Potential buyers are Alice and Bob, both real estate speculators who compete with each other. Charlie is interested in the highest bidder and wants to hold an auction. Alice and Bob both want to make a bid, but since they are competing in the same district, they do not want to reveal their bids. So Charlie proposes to hold a closed auction.\n\nSo far Sharemind is not yet needed: Alice and Bob can both follow a simple procedure: write their bid on a piece of paper, put it into an envelope, seal the envelope and give it to Charlie. Charlie would open the envelopes and determine the winner. Charlie promises not to reveal the losing bid. [Not every problem needs to be solved with Sharemind](https:\u002F\u002Fsharemind.cyber.ee\u002Fwhat-is-a-sharemind-problem\u002F).\n\nHowever, Alice is not happy with that plan. She is afraid that if Bob wins the auction and is going to celebrate the house deal with Charlie, it would be very easy for Bob to persuade Charlie to give him information about the amount Alice was willing to pay. That information would give Bob an edge over Alice in future deals. In short, Alice does not trust Charlie to keep the losing bid to himself.\n\nNow they have a problem that is suitable for solving with Sharemind and we will help them. We need an application that allows Alice and Bob to enter their bids into the Sharemind system and another application for Charlie to determine the outcome of the auction (the winner and the value of the winning bid).\n\n## System architecture\n\nI am not going to give you an [overview of Sharemind MPC](https:\u002F\u002Fsharemind.cyber.ee\u002Fsharemind-mpc\u002Fmulti-party-computation\u002F) in general, but rather explain the setup for solving this particular problem. Each stakeholder will host a Sharemind Application Server, and in addition, each will host a Redis database.\n\nThe base for the code comes from our [C++ client application demo](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Fstandalone-demo), however the latter is not very descriptive as there is only one party that inputs data and also gets the results. In order to use multiple inputs from separate stakeholders, we will need to use some kind of data storage inside the Sharemind MPC system. At the time of writing this, there are two options for persistent data storage in the Sharemind Application Server:\n\n1. mod\\_tabledb — a table-based storage format based on [HDF5](https:\u002F\u002Fwww.hdfgroup.org\u002Fdownloads\u002Fhdf5\u002F).\n2. mod\\_keydb — an adapter to [Redis](https:\u002F\u002Fredis.io) key-value database.\n\nI chose to keep the code simple and used mod\\_keydb, although it requires each stakeholder to also host a Redis server.\n\nThe data model is very simple, there are two variables named \"a\" and \"b\" in the key-value database. The first holds the bid for Alice and the second, \"b\", holds the amount for Bob.\n\n## Sharemind MPC setup\n\nNote that if you are not following the tutorial step-by-step and are only interested in the general use case, you should skip this section and jump directly to the [next section](#entering-bids-into-sharemind).\n\nI am not going to go over the whole Sharemind MPC configuration, because this should be covered in the manuals shipped with the platform.\n\nHowever, I will cover the following:\n\n### Key generation\n\nSharemind MPC uses TLS for securing the communications. We use public-key cryptography for TLS and for general authentication. There are many options to generate key pairs, two of them are listed below.\n\nWith OpenSSL\n\n```\nopenssl req -x509 -days 3650 -nodes -newkey rsa:4096 -keyout \"my-private-key\" -out \"my-public-key\" -outform deropenssl rsa -in \"my-private-key\" -out \"my-private-key\" -outform der\n```\n\nWith GnuTLS `certtool`\n\n```\n.\u002Fcerttool --generate-privkey --rsa --outfile my-private-key --outder.\u002Fcerttool --generate-self-signed --load-privkey my-private-key --inder --outfile my-public-key --outder\n```\n\n### Keydb module configuration\n\nIn order to use the keydb database module, one needs to configure the Sharemind Application Server or Emulator to load the database module. One should add the following under the modules configuration:\n\n```\n[Module keydb]File = libsharemind_mod_keydb.soConfiguration = %{CurrentFileDirectory}\u002Fkeydb.conf\n```\n\nThe configuration string for the module points to the file where keydb module specific configuration is stored. The configuration file for the keydb may contain multiple sections, where each section describes one Redis host. When using the keydb module from a SecreC application, one has to first connect to one database. An example of the configuration with one Redis host follows:\n\n```\n; This section defines a new host.; Because duplicate section names are not allowed you can use any other string; after the initial Host part.[Host host]; The name to access this host from the SecreC application.Name = dbhost; The hostname were the Redis database is listening.Hostname =localhost; The port number where Redis database is listening.; This is optional, when not present it defaults to 6379 which is the default; port number for Redis.Port =6379; Internal parameter, sets the number of items to load per request when; streaming keys in keydb_scan and keydb_clean.; This is optional, it defaults to 25.ScanCount =25; Whether to disable overwrites or not. Disabling overwrites ensures that there; are no inconsistencies from overwrites that succeed only partially.; This is optional, it defaults to falseDisableOverwrite =false\n```\n\nWhen using the Emulator, one also needs to load the datastore manager facility. This can be done by adding the following to your Sharemind Emulator configuration file:\n\n```\n[FacilityModule datastoremanager]File = libsharemind_facility_datastoremanager.so#Configuration =\n```\n\n### Access control\n\nSharemind MPC has granular access control. The access control policy can be configured based on users, programs and database resources.\n\nFirst, we declare 3 users by their public keys.\n\n```\n[User Alice]TlsPublicKeyFile = %{CurrentFileDirectory}\u002Falice-public-key[User Bob]TlsPublicKeyFile = %{CurrentFileDirectory}\u002Fbob-public-key[User Charlie]TlsPublicKeyFile = %{CurrentFileDirectory}\u002Fcharlie-public-key\n```\n\nNext, we allow them to execute specific SecreC bytecode programs.\n\n```\n[Ruleset sharemind:server]execute:alice_bid.sb = Aliceexecute:bob_bid.sb = Bobexecute:charlie_result.sb = Charlie\n```\n\nFinally, we allow access to some key-value pairs in the keydb database.\n\n```\n[Ruleset sharemind:keydb]a:write:* = Aliceb:write:* = Boba:read:* = Charlieb:read:* = Charlie\n```\n\nNote that the last star in the keydb rules means that Alice can write to \"a\" with every program Alice is allowed to run. To be more specific, one can also write out the program name.\n\n```\na:write:alice_bid.sb = Alice\n```\n\n## Entering bids into Sharemind\n\n### Server side\n\nWe start with the SecreC [code](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Fauction-demo\u002Fblob\u002Fmaster\u002Fsecrec\u002Falice_bid.sc) to enter the bid for Alice.\n\n```\nimport shared3p;import keydb;import shared3p_keydb;domain pd_shared3p shared3p;void main() { keydb_connect(\"dbhost\"); pd_shared3p uint b = argument(\"bid\"); keydb_set(\"a\", b); keydb_disconnect();}\n```\n\nAt the start, we have some imports, which I will explain:\n\n* shared3p — the definition of the shared3p protection domain kind.\n* keydb — for the keydb functions using public data (in our case `keydb_connect(string)` and `keydb_close()`).\n* shared3p\\_keydb — for the keydb functions specialized for shared3p protection domain kind (`keydb_set`).\n\nThen we have the definition of the security domain `pd_shared3p` of kind `shared3p`. In general, you can have multiple security domains with different kinds, but for now you can mostly ignore that, because we use only one protection domain kind: `shared3p`.\n\nBy the way, `shared3p` means that data is secret shared between 3 parties and the cryptographic protocols are secure in the passive (_honest-but-curious_) security model.\n\nThe main entry point of the program is called `main` just like in C, however the arguments to the SecreC program are not given as parameters of `main`, but they can be obtained using the `argument(string)` function.\n\nFirst we establish connection to the Redis server by using the `keydb_connect(string)` function. Note that the name _dbhost_ must match the name in the mod\\_keydb configuration file.\n\nNext we declare a private variable `b` of the security domain `pd_shared3p` and type `uint` that is short for `uint64`, which is a 64-bit unsigned integer. In the same line we assign the variable with the argument named \"bid\" that is provided by the runner of the SecreC program.\n\nThen we store the private data to the Redis database under the key \"a\", this means we store it as Alice's bid.\n\nLastly we close the connection to Redis, but this is actually not needed in this specific example, because the program is finished and the resources get freed anyway.\n\nFor Bob the [SecreC program](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Fauction-demo\u002Fblob\u002Fmaster\u002Fsecrec\u002Fbob_bid.sc) is almost identical, the only difference is:\n\n```\n-     keydb_set(\"a\", b);+     keydb_set(\"b\", b);\n```\n\nInstead of storing the bid to the database with key \"a\" we store the bid to \"b\", which corresponds to Bob's bid.\n\n### Client side\n\nThe corresponding [C++ client application](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Fauction-demo\u002Fblob\u002Fmaster\u002Fsrc\u002Fbid.cpp) starts with argument parsing using [Boost's program\\_options](https:\u002F\u002Fwww.boost.org\u002Fdoc\u002Flibs\u002F1_67_0\u002Fdoc\u002Fhtml\u002Fprogram_options.html). After that we load the Sharemind Controller configuration with the following lines:\n\n```\nif (vm.count(\"conf\")) { config = std::make_unique&#x3C;sm::SystemControllerConfiguration>( vm[\"conf\"].as&#x3C;std::string>());} else { config = std::make_unique&#x3C;sm::SystemControllerConfiguration>();}\n```\n\nIf we have a `\"conf\"` option specified we give that to the constructor to load the configuration from that file, otherwise the client configuration is searched from the default locations (in this order):\n\n* `~\u002F.config\u002Fsharemind\u002Fclient.conf`\n* `\u002Fetc\u002Fxdg\u002Fsharemind\u002Fclient.conf`\n* `\u002Fetc\u002Fsharemind\u002Fclient.conf`\n\nNext we need to set up an `LogHard::Logger` instance:\n\n```\nauto logBackend(std::make_shared&#x3C;LogHard::Backend>());logBackend->addAppender(std::make_shared&#x3C;LogHard::StdAppender>());logBackend->addAppender(std::make_shared&#x3C;LogHard::FileAppender>(\"auction-bid.log\", LogHard::FileAppender::OVERWRITE));const LogHard::Logger logger(logBackend);\n```\n\nAfter that is done, we can create an instance of the `SystemController` and then create an `SystemController::ValueMap` instance for the arguments. We add an argument called \"bid\", that the SecreC program expects. Note that the `SystemController::Value` constructor also needs the protection domain and type of the argument. The third argument to `Value` constructor is of type `std::shared_ptr&#x3C;void>` and the data is used directly as a pointer. Therefore we also need to pass in the size of the data. For passing in arrays of data, we would point to the start of the array and give the size as `sizeof(sm::Uint64) * lengthOfArray`.\n\nNote: if the conversion from `std::shared_ptr&#x3C;sm::Uint64>` to `std::shared_ptr&#x3C;void>` is confusing, you should read [this explanation](http:\u002F\u002Fshanekirk.com\u002F2017\u002F11\u002Fc-stdshared_ptrvoid\u002F).\n\n```\nsm::SystemControllerGlobals systemControllerGlobals;sm::SystemController c(logger, *config);\u002F\u002F Initialize the argument map and set the argumentssm::SystemController::ValueMap arguments;arguments[\"bid\"] =std::make_shared&#x3C;sm::SystemController::Value>(\"pd_shared3p\",\"uint64\",std::make_shared&#x3C;std::uint64_t>(bid),sizeof(std::uint64_t));\n```\n\nAfter we are finished with the arguments, we just run the right bytecode program with the arguments and as a result we will get back the same kind of `SystemController::ValueMap` that we used for the arguments:\n\n```\nsm::SystemController::ValueMap results = c.runCode(bytecode[bidder], arguments);\n```\n\nNote that `bytecode[bidder]` evaluates to `\"alice_bid.sb\"` or `\"bob_bid.sb\"` depending on the command line arguments.\n\n## Getting the results out of Sharemind\n\n### Server side\n\nThe SecreC [code](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Fauction-demo\u002Fblob\u002Fmaster\u002Fsecrec\u002Fcharlie_result.sc) for getting the results is straightforward:\n\n```\nimport shared3p;import keydb;import shared3p_keydb;import oblivious;domain pd_shared3p shared3p;void main() { keydb_connect(\"dbhost\"); pd_shared3p uint a = keydb_get(\"a\"); pd_shared3p uint b = keydb_get(\"b\"); pd_shared3p bool aliceWon = a > b; pd_shared3p uint winningBid = choose(aliceWon, a, b); publish(\"aliceWon\", aliceWon); publish(\"winningBid\", winningBid); keydb_disconnect();}\n```\n\nWe get Alice's bid `\"a\"` and Bob's bid `\"b\"` from the database and we compare them. The `choose` function is a private variant of the C's ternary operator (`&#x3C;cond> ? &#x3C;true_expr> : &#x3C;false_expr>`). Note that in this case we cannot use the typical `if\u002Felse` because that would need a public boolean to branch on. The `choose` function is defined in the `oblivious` module.\n\nFor outputting something from a SecreC program, one has to use the `publish` function, which sends the secret shared output back to the client application.\n\n### Client side\n\nThe [C++ code](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Fauction-demo\u002Fblob\u002Fmaster\u002Fsrc\u002Fresult.cpp) for getting the result is mostly the same as for entering the bid, just that now we give no arguments to the SecreC program and we will get back the published results.\n\n```\nsm::SystemControllerGlobals systemControllerGlobals;sm::SystemController c(logger, *config);\u002F\u002F Initialize the argument map and set the argumentssm::SystemController::ValueMap arguments;\u002F\u002F Run codelogger.info() &#x3C;&#x3C; \"Running SecreC bytecode on the servers.\";sm::SystemController::ValueMap results = c.runCode(\"charlie_result.sb\", arguments);\u002F\u002F Print the resultbool aliceWon = results[\"aliceWon\"]->getValue&#x3C;std::uint8_t>();auto winningBid = results[\"winningBid\"]->getValue&#x3C;std::uint64_t>();logger.info() &#x3C;&#x3C; \"The winner is \" &#x3C;&#x3C; (aliceWon ? \"Alice\" : \"Bob\") &#x3C;&#x3C; \". With a bid of \" &#x3C;&#x3C; winningBid &#x3C;&#x3C; \".\";\n```\n\n## Demonstration\n\nAliceBobCharlie\n\n```\n$ .\u002Fauction-bid -a --bid 10002018.04.26 17:34:50 INFO    [Controller] Loaded controller module 'shared3p' (15 data types, 1 PDKs) from'libsharemind_mod_shared3p_ctrl.so' using API version 1.2018.04.26 17:34:50 INFO    [Controller] Started protection domain 'pd_shared3p' of kind 'shared3p'.2018.04.26 17:34:50 INFO    Sending secret shared arguments and running SecreC bytecode on the servers2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Connecting...2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Connecting...2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Connected. Authenticating...2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Connected. Authenticating...2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Connecting...2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Connected. Authenticating...2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Authenticated.2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Authenticated.2018.04.26 17:34:50 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Authenticated.2018.04.26 17:34:50 INFO    [Controller] Stopping the network...\n```\n\n```\n$ .\u002Fauction-bid -b --bid 11002018.04.26 17:35:52 INFO    [Controller] Loaded controller module 'shared3p' (15 data types, 1 PDKs) from'libsharemind_mod_shared3p_ctrl.so' using API version 1.2018.04.26 17:35:52 INFO    [Controller] Started protection domain 'pd_shared3p' of kind 'shared3p'.2018.04.26 17:35:52 INFO    Sending secret shared arguments and running SecreC bytecode on the servers2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Connecting...2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Connecting...2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Connecting...2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Connected. Authenticating...2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Connected. Authenticating...2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Connected. Authenticating...2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Authenticated.2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Authenticated.2018.04.26 17:35:52 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Authenticated.2018.04.26 17:35:52 INFO    [Controller] Stopping the network...\n```\n\n```\n$ .\u002Fauction-result2018.04.26 17:36:20 INFO    [Controller] Loaded controller module 'shared3p' (15 data types, 1 PDKs) from'libsharemind_mod_shared3p_ctrl.so' using API version 1.2018.04.26 17:36:20 INFO    [Controller] Started protection domain 'pd_shared3p' of kind 'shared3p'.2018.04.26 17:36:20 INFO    Running SecreC bytecode on the servers.2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Connecting...2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Connecting...2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Connecting...2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Connected. Authenticating...2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Connected. Authenticating...2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Connected. Authenticating...2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner1] To 127.0.0.1:30001: Authenticated.2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner3] To 127.0.0.1:30003: Authenticated.2018.04.26 17:36:20 INFO    [Controller][Server DebugMiner2] To 127.0.0.1:30002: Authenticated.2018.04.26 17:36:20 INFO    The winner is Bob. With a bid of 1100.2018.04.26 17:36:20 INFO    [Controller] Stopping the network...\n```\n\n## Running the examples with the Sharemind Emulator\n\nFor running the SecreC programs with the Sharemind Emulator, one needs to know the protocol for giving arguments and receiving the results. The argument stream protocol is described in a [man page](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Femulator\u002Fblob\u002Fmaster\u002Fdoc\u002Fsharemind-emulator.h2m).\n\nAliceBobCharlie\n\n```\n$ sharemind-emulator alice_bid.sb --str=bid --str=pd_shared3p --str=uint64 --size=8 --uint64=1000\n```\n\n```\n$ sharemind-emulator bob_bid.sb --str=bid --str=pd_shared3p --str=uint64 --size=8 --uint64=1100\n```\n\n```\n$ sharemind-emulator charlie_result.sb |.\u002Fargument-stream-decipher.pyProcess returned status: 0aliceWon = [False]winningBid = [1100]\n```\n\nHere we piped the emulator output through `argument-stream-decipher.py` to make the output human readable. This [file](https:\u002F\u002Fgithub.com\u002Fsharemind-sdk\u002Femulator\u002Fblob\u002Fmaster\u002Fdoc\u002Fargument-stream-decipher.py) is available as part of the Sharemind Emulator distribution.\n\n## Conclusion\n\nCharlie sold his house to Bob and neither Charlie nor Bob learned the amount Alice was willing to pay.\n\nI have hopefully shown that it is not that hard to write privacy preserving application with the Sharemind MPC platform. The code itself is quite simple and the hardest part is organizational. All parties must coordinate to configure the servers, generate keys for the clients and the servers and then exchange the public keys. However, we are building tools to simplify that coordination.",[],{"metaTitle":14,"metaDescription":10,"shareImage":10},"A tutorial on using the Sharemind MPC platform",1788355408615]