{"id":15030550,"url":"https://github.com/zk-call/zkp-hmac-communication-python","last_synced_at":"2025-05-16T04:04:12.266Z","repository":{"id":230374383,"uuid":"701127414","full_name":"zk-Call/zkp-hmac-communication-python","owner":"zk-Call","description":"\"Zero-Knowledge\" Proof Implementation with HMAC Communication in Python","archived":false,"fork":false,"pushed_at":"2024-10-07T23:33:52.000Z","size":2197,"stargazers_count":966,"open_issues_count":0,"forks_count":235,"subscribers_count":201,"default_branch":"main","last_synced_at":"2025-05-11T08:14:03.443Z","etag":null,"topics":["hmac","python","zero-knowledge","zk-call","zkproof"],"latest_commit_sha":null,"homepage":"https://zkcall.net","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zk-Call.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-06T01:27:58.000Z","updated_at":"2025-05-03T09:08:25.000Z","dependencies_parsed_at":"2024-04-10T04:21:33.293Z","dependency_job_id":"514d6e2b-3948-4ad7-b41e-4803d872d89b","html_url":"https://github.com/zk-Call/zkp-hmac-communication-python","commit_stats":{"total_commits":34,"total_committers":3,"mean_commits":"11.333333333333334","dds":0.05882352941176472,"last_synced_commit":"715273045c14cb50e2edfc83ef43ade142d928cf"},"previous_names":["zk-call/style-dictionaries"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zk-Call","download_url":"https://codeload.github.com/zk-Call/zkp-hmac-communication-python/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254464891,"owners_count":22075570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hmac","python","zero-knowledge","zk-call","zkproof"],"created_at":"2024-09-24T20:13:40.450Z","updated_at":"2025-05-16T04:04:12.238Z","avatar_url":"https://github.com/zk-Call.png","language":"Python","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"assets/zk-Call%20Preview%20%5BPython%5D.png\" alt=\"zk-Call Preview [Python]\"\u003e\n\u003c/div\u003e\n\u003ch1 align=\"center\"\u003ezk-Call \u0026 Labs\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003e\"Zero-Knowledge\" Proof Implementation with HMAC Communication in Python\u003c/strong\u003e\n\u003c/div\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"http://badges.github.io/stability-badges/dist/experimental.svg\" alt=\"Experimental\" /\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003csub\u003e\n    Built by \u003ca href=\"https://github.com/zk-Call\"\u003e zk-Call\u003c/a\u003e :)\n  \u003c/sub\u003e\n\u003c/div\u003e\n\u003cbr /\u003e\n\n# Table of Contents\n- [Credits](#credits)\n- [Purpose](#purpose)\n- [How it Works](#how-it-works)\n- [API](#api)\n- [Example Usage](#example-usage)\n\u003cbr\u003e\n\n# Credits\n\nThis repository hosts a refined implementation of [**Schnorr's Protocol**](https://en.wikipedia.org/wiki/Schnorr_signature), innovatively incorporating a state seed for enhanced security measures. While the underlying proofs may appear intricate, I aim to elucidate their functionality to the best of my ability. However, for a deeper understanding, I encourage referencing the seminal research papers underpinning this implementation, as they offer comprehensive insights.\n\n---\n\n![Detailed Schematic Overview of Schnorr's Protocol (Example)](assets/Schnorr's%20Protocol.png)\n\u003cbr\u003e\n\u003cbr\u003e\n\n**For further exploration:**\n\n[**Elliptic Curve Based \"Zero-Knowledge\" Proofs and Their Applicability on Resource Constrained Devices by Ioannis Chatzigiannakis, Apostolos Pyrgelis, Paul G. Spirakis, and Yannis C. Stamatiou**](https://arxiv.org/pdf/1107.1626.pdf)\n\n---\n\n![Detailed Schematic Overview of Elliptic Curves (Example)](assets/Elliptic%20Curve.png)\n\u003cbr\u003e\n\nAdditionally, this repository delves into the concepts of **\"Zero-Knowledge\" Proofs (ZKPs)** and **Hash-based Message Authentication Codes (HMACs)**. **ZKPs** are cryptographic protocols that allow one party **(the prover)** to prove to another party **(the verifier)** that a given statement is true, without revealing any additional information beyond the validity of the statement itself. This property is particularly valuable for preserving privacy while establishing trust.\n\u003cbr\u003e\n\nOn the other hand, **HMACs** are a type of cryptographic hash function used for message authentication. They involve a cryptographic hash function **(such as SHA-256)** and a secret cryptographic key. **HMACs** provide a way to verify both the data integrity and the authenticity of a message, ensuring that it has not been altered or tampered with during transmission and that it indeed originates from the purported sender.\n\u003cbr\u003e\n\u003cbr\u003e\n\n# Purpose\n\nIn today's rapidly evolving IT and application development landscape, **\"Zero-Knowledge\" Proofs (ZKPs)** emerge as a pivotal paradigm for authentication security. Their capacity to affirm the validity of a claim, such as proving possession of a secret password — without revealing any sensitive information about the claim itself, such as passwords or hashes, revolutionizes the assurance of secure **AAA operations** (**authentication**, **authorization**, and **accounting**).\n\n---\n\n![The Purpose of our Repositories and The Overall Technology](assets/Purpose-1.png)\n\u003cbr\u003e\n\n**zk-Call \u0026 Labs** represents an implementation of a [**Non-Interactive \"Zero-Knowledge\" Proof**](https://en.wikipedia.org/wiki/Non-interactive_zero-knowledge_proof) **(NIZKP)** protocol tailored specifically for validating text-based secrets. This framework proves invaluable for safeguarding passwords and other authentication mechanisms, ensuring robust security measures without compromising privacy. Additionally, the integration of **HMAC (Hash-Based Message Authentication Code)** further fortifies the authentication process, enhancing data integrity and thwarting potential security breaches.\n\u003cbr\u003e\n\u003cbr\u003e\n\n# How It Works\n\nThe authentication protocol employed in this system operates based on two fundamental concepts:\n**\"Zero-Knowledge\" Proofs (ZKPs)** and **Hash-Based Message Authentication Code (HMAC)**. Let's delve into each of these components and understand how they synergize to ensure secure authentication in messaging applications.\n\u003cbr\u003e\n\n\"Zero-Knowledge\" Proofs (ZKPs)\n---\n\n\n#### **\"Zero-Knowledge\" Proofs (ZKPs):** \n**ZKPs** form the bedrock of privacy-preserving authentication mechanisms. These proofs allow one party **(the prover)** to demonstrate the validity of a claim to another party **(the verifier)** without revealing any additional information beyond the claim's validity. In essence, **ZKPs** enable authentication without the need for the prover to disclose sensitive data, such as passwords or cryptographic keys.\n\n---\n\n![Detailed Schematic Overview of \"Zero-Knowledge\" Technology (1)](assets/ZKP-HMAC-1.png)\n![Detailed Schematic Overview of \"Zero-Knowledge\" Technology (2)](assets/ZKP-HMAC-2.png)\n![Detailed Schematic Overview of \"Zero-Knowledge\" Technology (3)](assets/ZKP-HMAC-3.png)\n![Detailed Schematic Overview of \"Zero-Knowledge\" Technology (4)](assets/ZKP-HMAC-4.png)\n\u003cbr\u003e\n\n\n#### **Application in Authentication:** \nIn the context of messaging applications, **ZKPs** play a pivotal role in verifying a user's identity without the need to transmit explicit credentials over the network. Instead, users can generate cryptographic proofs attesting to their identity or possession of certain credentials without exposing those credentials themselves. This ensures that sensitive information remains confidential during the authentication process, bolstering security and privacy.\n\u003cbr\u003e\n\u003cbr\u003e\n\n\nHash-Based Message Authentication Code (HMAC)\n---\n\n#### **Hash-Based Message Authentication Code (HMAC):**\n**HMAC** provides a robust mechanism for verifying the integrity and authenticity of messages exchanged between parties. It involves the use of a cryptographic hash function in conjunction with a secret key to generate a unique code **(the HMAC)** for each message. This code serves as a digital signature, allowing the recipient to verify that the message has not been tampered with or altered during transmission.\n\n---\n\n![Detailed Schematic Overview of HMAC Encryption](assets/HMAC.png)\n\n\n#### **Application in Authentication:**\nIn messaging applications, **HMAC** can be employed to authenticate message senders and ensure the integrity of communication channels. By appending an **HMAC** to each message using a shared secret key, both the sender and recipient can validate the message's authenticity upon receipt. Any unauthorized modifications to the message would result in a mismatch between the **computed HMAC** and the **received HMAC**, thereby alerting the recipient to potential tampering.\n\u003cbr\u003e\n\u003cbr\u003e\n\nSynergistic Operation\n---\nWhen combined, **\"Zero-Knowledge\" Proofs** and **HMAC** create a formidable framework for secure authentication in messaging applications. **ZKPs** facilitate identity verification without divulging sensitive information, while **HMAC** ensures the integrity and authenticity of messages exchanged between parties. Together, these mechanisms uphold the confidentiality, integrity, and authenticity of communication channels, safeguarding users' privacy and security in the digital realm.\n\n---\n\n![The Advantages of Synergy between \"Zero-Knowledge\" Proof and HMAC](assets/Synergistic%20Operation.png)\n\u003cbr\u003e\n\u003cbr\u003e\n\n# API\n\nThe **`\"Zero-Knowledge\"`** Python API is meant to be simple and intuitive:\u003cbr\u003e\n\n\n## Core Components\nThe **`Core Components`** are key for establishing a secure and efficient framework for cryptographic protocols; streamlining the creation and validation of **\"Zero-Knowledge\" Proofs (ZKPs)**. They enhance anonymous, data-safe proof validations.\n\n![Detailed Schematic Overview of Core Components](assets/Core%20Components%20(Python).png)\n\n---\n\n#### ZeroKnowledge.models.ZeroKnowledgeParams\nThe parameters **used to initialize the \"Zero-Knowledge\"** crypto system.\n\n    class ZeroKnowledgeParams(NamedTuple):\n        \"\"\"\n        Parameters used to construct a Zero-Knowledge Proof state, utilizing an elliptic curve and a random salt\n        \"\"\"\n        algorithm: str                    # Hashing algorithm name\n        curve: str                  # Standard Elliptic Curve name to use\n        s: int                      # Random salt for the state\n\n#### ZeroKnowledge.models.ZeroKnowledgeSignature\nA **cryptographic \"Zero-Knowledge\"** signature that can be used to verify future messages.\n\n    class ZeroKnowledgeSignature(NamedTuple):\n        \"\"\"\n        Cryptographic public signature designed to verify future messages\n        \"\"\"\n        params: ZeroKnowledgeParams       # Reference ZeroKnowledge Parameters\n        signature: int              # The public key derived from your original secret\n\n\n#### ZeroKnowledge.models.ZeroKnowledgeProof\nA **cryptographic proof** that can be verified against a signature.\n\n    class ZeroKnowledgeProof(NamedTuple):\n        \"\"\"\n        Non-deterministic cryptographic Zero-Knowledge Proof designed to confirm that the\n        private key creating the proof matches the key used to generate the signature\n        \"\"\"\n        params: ZeroKnowledgeParams        # Reference ZeroKnowledge Parameters\n        c: int                      # The hash of the signed data and random point, R\n        m: int                      # The offset from the secret `r` (`R=r*g`) from c * Hash(secret)\n\n\n#### ZeroKnowledge.models.ZeroKnowledgeData\n**Wrapper** that contains **a proof and the necessary data** to validate the proof against a signature.\n\n    class ZeroKnowledgeData(NamedTuple):\n        \"\"\"\n        Wrapper designed to hold data along with its corresponding signed proof\n        \"\"\"\n        data: Union[str, bytes, int]\n        proof: ZeroKnowledgeProof\n\n---\n\n## ZeroKnowledge\nThe **`ZeroKnowledge`** class is the central component of **`ZeroKnowledge`** and its state (defined by **`ZeroKnowledgeParams`**) should be inherently known to both the **Client (Prover)** and **Server (Verifier)**.\n\n![Comprehensive Visual Guide to ZeroKnowledge Framework](assets/ZeroKnowledge%20(Python).png)\n\n---\n\n#### Instance Methods\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth width=\"9%\"\u003eMethod\u003c/th\u003e\n    \u003cth width=\"46%\"\u003eParams\u003c/th\u003e\n    \u003cth width=\"10%\"\u003eRole\u003c/th\u003e\n    \u003cth width=\"35%\"\u003ePurpose\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ecreate_signature\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003esecret: Union[str, bytes]\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eProver\u003c/td\u003e\n    \u003ctd\u003eCreate a cryptographic \u003ccode\u003esignature\u003c/code\u003e derived from the value \u003ccode\u003esecret\u003c/code\u003e to be generated during initial registration and stored for subsequent \u003ccode\u003echallenge\u003c/code\u003e proofs.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003esign\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003esecret: Union[str, bytes]\u003c/code\u003e \u003cbr /\u003e \u003ccode\u003edata: Union[str, bytes, int]\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eProver\u003c/td\u003e\n    \u003ctd\u003eCreate a \u003ccode\u003eZeroKnowledgeData\u003c/code\u003e object using the \u003ccode\u003esecret\u003c/code\u003e and any additional data.\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003everify\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003echallenge: Union[ZeroKnowledgeData, ZeroKnowledgeProof]\u003c/code\u003e \u003cbr /\u003e \u003ccode\u003esignature: ZeroKnowledgeSignature\u003c/code\u003e \u003cbr /\u003e \u003ccode\u003edata: Optional[Union[str, bytes, int]]\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eVerifier\u003c/td\u003e\n    \u003ctd\u003eVerify the user-provided \u003ccode\u003echallenge\u003c/code\u003e against the stored \u003ccode\u003esignature\u003c/code\u003e and randomly generated token to verify the validity of the \u003ccode\u003echallenge\u003c/code\u003e.\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n# Example Usage\nTODO: Include **`Example Usage`**\n\n## Example 1\n\n    \"\"\"\n    Extremely simple example of hmac\n    \"\"\"\n    from queue import Queue\n    from threading import Thread\n    from src.HMAC.core import HMACClient\n    from src.SeedGeneration.core import SeedGenerator\n    \n    DEBUG = True\n    \n    \n    def print_msg(who: str, message: str) -\u003e None:\n        \"\"\"\n        Function to print debug messages. Prints the message only if the DEBUG flag is set to True.\n    \n        Args:\n            who (str): Identifier of the message sender.\n            message (str): Message to print.\n        \"\"\"\n        if DEBUG:\n            print(f'[{who}] {message}\\n')\n    \n    \n    def client(client_socket: Queue, server_socket: Queue):\n        \"\"\"\n        Function representing the client logic.\n    \n        Args:\n            client_socket (Queue): Queue for data exchange between the client and server.\n            server_socket (Queue): Queue for data exchange between the server and client.\n        \"\"\"\n        # Generating the main seed\n        main_seed = SeedGenerator(phrase=\"job\").generate()\n    \n        # Creating an instance of HMACClient for encrypting messages\n        obj = HMACClient(algorithm=\"sha256\", secret=main_seed, symbol_count=1)\n    \n        # Sending the main seed to the server\n        server_socket.put(main_seed)\n    \n        # Checking if the server has successfully received the seed\n        if client_socket.get() == obj.encrypt_message(''):\n            # If successful, send a message to the server\n            message = 'hello'\n            server_socket.put(obj.encrypt_message_by_chunks(message))\n            print_msg('client', f'client sent message {message}')\n    \n            # Checking if the server has successfully decrypted the message\n            if client_socket.get() == obj.encrypt_message(message):\n                print_msg('client', 'server has decrypt message')\n    \n    \n    def server(server_socket: Queue, client_socket: Queue):\n        \"\"\"\n        Function representing the server logic.\n    \n        Args:\n            server_socket (Queue): Queue for data exchange between the server and client.\n            client_socket (Queue): Queue for data exchange between the client and server.\n        \"\"\"\n        # Receiving the main seed from the client\n        main_seed = server_socket.get()\n    \n        # Creating an instance of HMACClient for encrypting messages\n        obj = HMACClient(algorithm=\"sha256\", secret=main_seed, symbol_count=1)\n    \n        # Sending an empty message to the client as acknowledgment\n        client_socket.put(obj.encrypt_message(''))\n    \n        # Receiving the encrypted message from the client\n        msg = server_socket.get()\n        print_msg('server', f'msg encrypted {msg}')\n    \n        # Decrypting the message\n        msg_raw = obj.decrypt_message_by_chunks(msg)\n        print_msg('server', f'msg raw {msg_raw}')\n    \n        # Sending the encrypted message back to the client\n        client_socket.put(obj.encrypt_message(msg_raw))\n    \n    \n    def main():\n        \"\"\"\n        Main function to run the client and server threads.\n        \"\"\"\n        client_socket, server_socket = Queue(), Queue()\n        threads = []\n        threads.append(Thread(target=client, args=(client_socket, server_socket)))\n        threads.append(Thread(target=server, args=(server_socket, client_socket)))\n    \n        # Starting the threads\n        for thread in threads:\n            thread.start()\n    \n        # Joining the threads to wait for their completion\n        for thread in threads:\n            thread.join()\n    \n    \n    if __name__ == \"__main__\":\n        main()\n\n---\n\n## Example 2\n\n    \"\"\"\n    Extremely simple example of ZeroKnowledge\n    \"\"\"\n    from src.ZeroKnowledge.core import ZeroKnowledge\n    from src.ZeroKnowledge.models import ZeroKnowledgeSignature, ZeroKnowledgeData\n    from queue import Queue\n    from threading import Thread\n    \n    DEBUG = True\n    \n    \n    def print_msg(who: str, message: str) -\u003e None:\n        \"\"\"\n        Function to print debug messages.\n    \n        Args:\n            who (str): Identifier of the message sender.\n            message (str): Message to print.\n        \"\"\"\n        if DEBUG:\n            print(f'[{who}] {message}\\n')\n    \n    \n    def client(client_socket: Queue, server_socket: Queue):\n        \"\"\"\n        Function representing the client logic.\n    \n        Args:\n            client_socket (Queue): Queue for data exchange between the client and server.\n            server_socket (Queue): Queue for data exchange between the server and client.\n        \"\"\"\n        # Creating a ZeroKnowledge object for the client with specified curve and hash algorithm\n        client_object = ZeroKnowledge.new(curve_name=\"secp256k1\", hash_alg=\"sha3_256\")\n        idenity = 'John'\n    \n        # Creating a signature for the client identity\n        signature = client_object.create_signature(idenity)\n    \n        # Sending the signature to the server\n        server_socket.put(signature.to_json())\n        print_msg('client', f'its signature {signature.to_json()}')\n    \n        # Receiving token from the server\n        token = client_socket.get()\n        print_msg('client', f'its token {token}')\n    \n        # Generating proof using client identity and token\n        proof = client_object.sign(idenity, token).to_json()\n        print_msg('client', f'proof {proof}')\n    \n        # Sending proof to the server\n        server_socket.put(proof)\n    \n        # Receiving result from the server\n        result = client_socket.get()\n        print_msg('client', f\"{result}\")\n    \n    \n    def server(server_socket: Queue, client_socket: Queue):\n        \"\"\"\n        Function representing the server logic.\n    \n        Args:\n            server_socket (Queue): Queue for data exchange between the server and client.\n            client_socket (Queue): Queue for data exchange between the client and server.\n        \"\"\"\n        # Setting the server password\n        server_password = \"SecretServerPassword\"\n    \n        # Creating a ZeroKnowledge object for the server with specified curve and hash algorithm\n        server_zk = ZeroKnowledge.new(curve_name=\"secp384r1\", hash_alg=\"sha3_512\")\n    \n        # Creating a signature for the server password\n        server_signature: ZeroKnowledgeSignature = server_zk.create_signature(server_password)\n    \n        # Receiving client signature from the client\n        sig = server_socket.get()\n        client_signature = ZeroKnowledgeSignature.from_json(sig)\n        print_msg('server', f'its client signature {client_signature.to_json()}')\n    \n        # Creating a ZeroKnowledge object for the client using client signature parameters\n        client_zk = ZeroKnowledge(client_signature.params)\n        print_msg('server', f'its client_zk {client_zk}')\n    \n        # Generating a token signed by the server for the client\n        token = server_zk.sign(server_password, client_zk.token())\n        print_msg('server', f'its token {token}')\n    \n        # Sending the token to the client\n        client_socket.put(token.to_json())\n    \n        # Receiving proof from the client\n        proof = ZeroKnowledgeData.from_json(server_socket.get())\n        print_msg('server', f'its proof {proof}')\n    \n        # Verifying the received proof\n        token = ZeroKnowledgeData.from_json(proof.data)\n        print_msg('server', f'its token {token}')\n        server_verif = server_zk.verify(token, server_signature)\n        print_msg('server', f'its server_verif {server_verif}')\n    \n        # If server verification fails, notify the client\n        if not server_verif:\n            client_socket.put(False)\n        else:\n            # Otherwise, verify the proof using client signature\n            client_verif = client_zk.verify(proof, client_signature, data=token)\n            print_msg('server', f'its client_verif {client_verif}')\n            client_socket.put(client_verif)\n    \n    \n    def main():\n        \"\"\"\n        Main function to run the client and server threads.\n        \"\"\"\n        client_socket, server_socket = Queue(), Queue()\n        threads = []\n        threads.append(Thread(target=client, args=(client_socket, server_socket)))\n        threads.append(Thread(target=server, args=(server_socket, client_socket)))\n    \n        # Starting the threads\n        for thread in threads:\n            thread.start()\n    \n        # Waiting for threads to finish execution\n        for thread in threads:\n            thread.join()\n    \n    \n    if __name__ == \"__main__\":\n        main()\n\n---\n        \n## Example 3\n\n    \"\"\"\n    Extremely simple example of ZeroKnowledge and hmac together\n    \"\"\"\n    from src.ZeroKnowledge.core import ZeroKnowledge\n    from src.ZeroKnowledge.models import ZeroKnowledgeSignature, ZeroKnowledgeData\n    from queue import Queue\n    from threading import Thread\n    from src.HMAC.core import HMACClient\n    from src.SeedGeneration.core import SeedGenerator\n    \n    DEBUG = True\n    \n    \n    def print_msg(who: str, message: str) -\u003e None:\n        if DEBUG:\n            print(f'[{who}] {message}\\n')\n    \n    \n    def client(client_socket: Queue, server_socket: Queue):\n        # Initializing a ZeroKnowledge object for the client with specified curve and hash algorithm\n        client_object = ZeroKnowledge.new(curve_name=\"secp256k1\", hash_alg=\"sha3_256\")\n    \n        # Generating a main seed for encryption\n        main_seed = SeedGenerator(phrase=\"job\").generate()\n    \n        # Defining the client's identity\n        idenity = 'John'\n    \n        # Creating a signature for the client's identity\n        signature = client_object.create_signature(idenity)\n    \n        # Sending the signature to the server via server_socket\n        server_socket.put(signature.to_json())\n        print_msg('client', f'its signature {signature.to_json()}')\n    \n        # Receiving a token from the server via client_socket\n        token = client_socket.get()\n        print_msg('client', f'its token {token}')\n    \n        # Generating a proof of identity using the client's identity and token\n        proof = client_object.sign(idenity, token).to_json()\n        print_msg('client', f'proof {proof}')\n    \n        # Sending the proof to the server via server_socket\n        server_socket.put(proof)\n    \n        # Receiving a result from the server via client_socket\n        result = client_socket.get()\n        print_msg('client', f\"{result}\")\n    \n        # If the result is True, proceed with further communication steps\n        if result:\n            # Sending the main seed to the server\n            server_socket.put(main_seed)\n    \n            # Initializing an HMACClient object for message encryption/decryption\n            obj = HMACClient(algorithm=\"sha256\", secret=main_seed, symbol_count=1)\n    \n            # Verifying an empty message received from the server\n            if client_socket.get() == obj.encrypt_message(''):\n                # Sending a message to the server\n                message = 'hello'\n                server_socket.put(obj.encrypt_message_by_chunks(message))\n                print_msg('client', f'client sent message {message}')\n    \n                # Verifying if the server has decrypted the message correctly\n                if client_socket.get() == obj.encrypt_message(message):\n                    print_msg('client', 'server has decrypt message')\n    \n    \n    def server(server_socket: Queue, client_socket: Queue):\n        # Defining the server's password\n        server_password = \"SecretServerPassword\"\n    \n        # Initializing a ZeroKnowledge object for the server with specified curve and hash algorithm\n        server_zk = ZeroKnowledge.new(curve_name=\"secp384r1\", hash_alg=\"sha3_512\")\n    \n        # Creating a signature for the server's password\n        server_signature: ZeroKnowledgeSignature = server_zk.create_signature(server_password)\n    \n        # Receiving the client's signature from the client via server_socket\n        sig = server_socket.get()\n        client_signature = ZeroKnowledgeSignature.from_json(sig)\n        print_msg('server', f'its client signature {client_signature.to_json()}')\n    \n        # Initializing a ZeroKnowledge object for the client using client signature parameters\n        client_zk = ZeroKnowledge(client_signature.params)\n        print_msg('server', f'its client_zk {client_zk}')\n    \n        # Generating a token signed by the server for the client\n        token = server_zk.sign(server_password, client_zk.token())\n        print_msg('server', f'its token {token}')\n    \n        # Sending the token to the client via client_socket\n        client_socket.put(token.to_json())\n    \n        # Receiving a proof from the client via server_socket\n        proof = ZeroKnowledgeData.from_json(server_socket.get())\n        print_msg('server', f'its proof {proof}')\n    \n        # Verifying the received proof\n        token = ZeroKnowledgeData.from_json(proof.data)\n        print_msg('server', f'its token {token}')\n    \n        # Verifying the token and the server signature\n        server_verif = server_zk.verify(token, server_signature)\n        print_msg('server', f'its server_verif {server_verif}')\n    \n        # If server verification fails, notify the client\n        if not server_verif:\n            client_socket.put(False)\n        else:\n            # Otherwise, verify the proof using the client signature\n            client_verif = client_zk.verify(proof, client_signature, data=token)\n            print_msg('server', f'its client_verif {client_verif}')\n            client_socket.put(client_verif)\n    \n            # Receiving the main seed from the client via server_socket\n            main_seed = server_socket.get()\n    \n            # Initializing an HMACClient object for message encryption/decryption using the received main seed\n            obj = HMACClient(algorithm=\"sha256\", secret=main_seed, symbol_count=1)\n    \n            # Sending an empty message to the client\n            client_socket.put(obj.encrypt_message(''))\n    \n            # Receiving an encrypted message from the client via server_socket\n            msg = server_socket.get()\n            print_msg('server', f'msg encrypted {msg}')\n    \n            # Decrypting the message\n            msg_raw = obj.decrypt_message_by_chunks(msg)\n            print_msg('server', f'msg raw {msg_raw}')\n    \n            # Sending the decrypted message back to the client\n            client_socket.put(obj.encrypt_message(msg_raw))\n    \n    \n    def main():\n        \"\"\"\n        Main function to run the client and server threads.\n        \"\"\"\n        client_socket, server_socket = Queue(), Queue()\n        threads = []\n        threads.append(Thread(target=client, args=(client_socket, server_socket)))\n        threads.append(Thread(target=server, args=(server_socket, client_socket)))\n    \n        # Starting the threads\n        for thread in threads:\n            thread.start()\n    \n        # Joining the threads to wait for their completion\n        for thread in threads:\n            thread.join()\n    \n    \n    if __name__ == \"__main__\":\n        main()\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzk-call%2Fzkp-hmac-communication-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzk-call%2Fzkp-hmac-communication-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzk-call%2Fzkp-hmac-communication-python/lists"}