ENGLISH 中文 Hierarchical Threshold Signature demonstration 徐粲邦 Follow Apr 27, 2020 · 8 min read This article is an example explanation of the open source project Alice (HTSS library from AMIS). Introduction In the previous article, we introduced the basic concept of HTSS. We know that the emergence of TSS is to deal with private key management. First, we could lower the risk of assets being transferred maliciously because the control of the assets is not belonged to one single entity (avoid single-point-of-failure). Second, with M-of-N scheme, we could prevent loss of the assets even if some of shares are missing (increase fault tolerance). Compared with multi-signature, TSS offers shorter signature and better privacy. Also, it does not save private key on the server and provides risk control as well as separation of duties. However, there is still room for improvement. HTSS introduced the different level of each share, which makes the application could be much closer to the real life scene and this property doesn’t exist in TSS. In this article, we will explain thoroughly about the example of Alice, an implementation of HTSS library worked by us. We will first illustrate the simplification of our example flow. Second, we will highlight the takeaway when running the example. Then, we will dive into the detail of 3 main commands of our TSS library. Last, we will conclude the demonstration. Simplification roles of TSS We imagine that the roles in TSS will be composed of two parts: an initiator and a group of share servers. initiator: The one who will initiate a TSS process. It could be one of the share servers or it could be a third-party entity. share servers: Servers that actually participate in TSS process. For example, an initiator might want some share servers to sign a message for it. First it will create a message and send it to specific share servers. Then it will initiate the signing process by telling these share servers they could start the process. However, in our example, we simplify the process of this flow. We discard the role of initiator. Each participant will consume a config file and that file will contain the required information to start a TSS process. Therefore, we don’t need the role of initiator to give orders. Highlights We leverage go-libp2p library to deal with the network connection in this example. To be noted, the communication in this example is not encrypted and the host ID of one peer is associated with its port, which means it’s not random. If you want to adopt this example to your production implementation, please be sure to adjust these configurations. According to the previous article, TSS contains four phases which are Key Generation, Sign a transaction, Verification, and Refresh share. In Alice, corresponding to the four phases TSS have, we have three main functions which are dkg (key generation), signer (sign a transaction), and reshare (refresh share). Verification could be achieved by using standard library of programming language. Take GoLang for example: import crypto/ecdsa ... ecdsa.Verify(publicKey, msg, r, s) ... Configuration All three commands in the example should have their own configuration. These config files are YAML format and they should contain the required input that commands need. Also, all three commands will create their own results after successful executions. These result files are YAML format as well. The input and output files of each command will be put at the same folder. And the naming rule is similar. For example, if a node is listening for port 10000 and it tries to start a dkg process, it will need to consume the input file dkg/id-10000-input.yaml and it will generate an output file dkg/id-10000-output.yaml if the process went well. If the required input file doesn’t exist, the execution will fail. By default, all config files already exist and have contained executable configurations. You don’t need to adjust anything to run the example. the location and the naming rule of each input / output file Execution In this example, we try to simulate the real situation of TSS algorithm. You will need to open different terminals and run TSS program on each terminal. After each process is executed, a node will be started and it will be blocked until it connects to all the peers. Therefore, you will see the following warnings when a new process started. WARN [04-15|11:07:07.592|peer/node.go:141] Failed to connect to peer err="..." WARN [04-15|11:07:07.592|peer/pm.go:89] Failed to connect to peer to=... err="..." WARN [04-15|11:07:07.592|peer/node.go:141] Failed to connect to peer err="..." WARN [04-15|11:07:07.592|peer/pm.go:89] Failed to connect to peer to=... err="..." These warnings are normal since it requires all peers connected before the algorithm execution. By default setting in the example, you will need to run three processes on three different terminals. After all three nodes are started and they are connected with each other, you will see the following debug messages and the process will continue. DEBUG[04-15|11:07:13.600|peer/pm.go:93] Successfully connect to peer to=... DEBUG[04-15|11:07:16.602|peer/pm.go:93] Successfully connect to peer to=... Usage At project root directory, you could use the following command to build an executable binary in example/ folder. > make tss-example > cd example DKG (Distributed Key Generation) When running a dkg process in the example, there are four parameters you need to provide: port, rank, threshold, peers. port: Port that this node will listen for. rank: The rank of this node during HTSS algorithm. The smaller the rank means the higher the level of the node’s share. threshold: Threshold that how many participants needed to generate a valid signature. peers: A list of peer’s ports that this node will try to connect. A complete dkg configuration is show below. port: 10001 rank: 0 threshold: 3 peers: - 10002 - 10003 Then, run three hosts on different terminals. Each node will need to consume a config file (e.g dkg/id-10001-input.yaml) by using --config or -c to specify the path of the config file. These three nodes will try to connect to each other. Once it connects to a peer, it will send the peer message out. The peer message is the input of the first step of key generation in HTSS. After the messages are fully transmitted, each node will start the process respectively. When the process is done, the result will be recorded as a file and put in dkg/ folder. On node A, > ./example dkg --config dkg/id-10001-input.yaml On node B, > ./example dkg --config dkg/id-10002-input.yaml On node C, > ./example dkg --config dkg/id-10003-input.yaml Signer When running a signer process in the example, there are six parameters you need to provide: port, peers, share, public key, Birkhoff parameters, and message. The port and peers are the same with the ones in dkg. share: The respective share generated from dkg. public key: The public key generated from dkg. Birkhoff parameters: The Birkhoff parameter of all peers. Birkhoff interpolation is the problem of finding a polynomial f of degree t such that certain derivatives have specified values at specified points. A pair (derivative, x-coordinate) is called a Birkhoff parameter. message: Message to be signed. The value of message for all participants must be the same. If the value of message is different, signing process will fail. Most of the time, this message will be a cryptographic transaction. And the transaction might be created from one party. Therefore, practically, before signing, another information exchange for the message might be required. A complete signer configuration is show below. port: 10001 peers: - 10002 - 10003 share: "101420976052030730685561069719911392914434824397492564228646546319061446487458" pubkey: x: "47143094896967716337843669989860432144962851204356940818421228324575441222601" y: "23336444423741848139737884993242101588835841992098573257496438799812162311375" bks: id-10001: x: "60804574656888231803750758362258552766945294870709728961250573287297336332061" rank: 0 id-10002: x: "69585139089653513675598669644888535871994689088749672680139122876344694547847" rank: 0 id-10003: x: "42617894318064911861435689891609248836936982258022075394462053252726961520252" rank: 0 msg: "hello tss" Then, run three hosts on different terminals. Each node will need to consume a config file (e.g signer/id-10001-input.yaml) by using --config or -c to specify the path of the config file. These three nodes will try to connect to each other. Once it connects to a peer, it will send the public key message out. The public key message is the input of the first step of signing in HTSS. After the messages are fully transmitted, each node will start the process respectively. When the process is done, the result will be recorded as a file and put in signer/ folder. On node A, > ./example signer --config signer/id-10001-input.yaml On node B, > ./example signer --config signer/id-10002-input.yaml On node C, > ./example signer --config signer/id-10003-input.yaml As we said before, all signer config files have already contained executable configurations. However, you could also try to copy the results from dkg/reshare result files and overwrite the configurations (e.g from dkg/id-10001-output.yaml to signer/id-10001-input.yaml). This should work as well. Reshare (Refresh share) When running a reshare process in the example, there are six parameters you need to provide: port, peers, threshold, share, public key, and Birkhoff parameters. All the parameters have appeared before. A complete reshare configuration is show below. port: 10001 threshold: 3 peers: - 10002 - 10003 share: "101420976052030730685561069719911392914434824397492564228646546319061446487458" pubkey: x: "47143094896967716337843669989860432144962851204356940818421228324575441222601" y: "23336444423741848139737884993242101588835841992098573257496438799812162311375" bks: id-10001: x: "60804574656888231803750758362258552766945294870709728961250573287297336332061" rank: 0 id-10002: x: "69585139089653513675598669644888535871994689088749672680139122876344694547847" rank: 0 id-10003: x: "42617894318064911861435689891609248836936982258022075394462053252726961520252" rank: 0 When refreshing share, all share servers must be involved. Again, each node will need to consume their own config file (e.g reshare/id-10001-input.yaml) by using --config or -c to specify the path of the config file. Once it connects to a peer, it will send the commit message out. The commit message is the input of the first step of refresh share in HTSS. After the messages are fully transmitted, each node will start the process respectively. When the process is done, the result will be recorded as a file and put in reshare/ folder. On node A, > ./example reshare --config reshare/id-10001-input.yaml On node B, > ./example reshare --config reshare/id-10002-input.yaml On node C, > ./example reshare --config reshare/id-10003-input.yaml Again, all reshare config files have already contained executable configurations. However, you could also try to copy the results from dkg/reshare result files and overwrite the configurations (e.g from dkg/id-10001-output.yaml to reshare/id-10001-input.yaml). This should work as well. Conclusion In conclusion, this example demonstrates a simple implementation of HTSS library. However, you should be aware that this example is NOT production ready. Be careful when you use it in the real environment. getamis/alice This is Hierarchical Threshold Signature Scheme (HTSS) worked by AMIS. Comparing to Threshold Signature Scheme (TSS)… github.com The above link is the complete implementation of Alice (include the example we discussed in this article). Feel free to open an issue if you have any question and creating a pull request is very welcome! Hope this article is helpful and educational. Cheers!! Threshold Signature Blockchain English 692 getamis Using breakthrough blockchain technology, AMIS (https//am.is) has created a standardized platform to let business create information exchange systems and make transaction data open and shareable to improve the quality of life for everyone. More From Medium Integrating Your Serverless Telegram Bot with AWS API Gateway Will Kelly Deploying a Prisma cluster to Kubernetes André König Software Architecture: Microservices Satrio Wibowo Quality is NOT perfection Lina Zubytė Pinpoint — a system of intelligence for software engineering Ed Sim in boldstart ventures Castcle Sprint Update #8 Woraphop Viriyaroj in Castcle Building Reliable Software Mark H in Misfit Coders Red Hat ACM’s ManagedCluster Lifecycle in “action” Randy Bruno-Piverger