{"id":19078220,"url":"https://github.com/zk-call/zkp-hmac-communication-cpp","last_synced_at":"2025-07-20T21:34:04.658Z","repository":{"id":231747968,"uuid":"781386665","full_name":"zk-Call/zkp-hmac-communication-cpp","owner":"zk-Call","description":"\"Zero-Knowledge\" Proof Implementation with HMAC Communication in C++","archived":false,"fork":false,"pushed_at":"2024-10-07T23:31:41.000Z","size":2044,"stargazers_count":221,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-17T17:14:16.697Z","etag":null,"topics":["cpp","hmac","zero-knowledge","zk-call","zkproof"],"latest_commit_sha":null,"homepage":"https://zkcall.net","language":"C++","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":"2024-04-03T09:31:57.000Z","updated_at":"2025-07-09T17:54:21.000Z","dependencies_parsed_at":"2024-04-05T18:24:33.209Z","dependency_job_id":"2f9ebe09-e8c5-4a3e-8c5a-ecd7fb55abfc","html_url":"https://github.com/zk-Call/zkp-hmac-communication-cpp","commit_stats":{"total_commits":23,"total_committers":7,"mean_commits":"3.2857142857142856","dds":"0.34782608695652173","last_synced_commit":"77c9d20971f7d8eaac22a81db90696ccc0efb845"},"previous_names":["zk-call/zkp-hmac-communication-cpp"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/zk-Call/zkp-hmac-communication-cpp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-cpp/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-cpp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zk-Call%2Fzkp-hmac-communication-cpp/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266204534,"owners_count":23892364,"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":["cpp","hmac","zero-knowledge","zk-call","zkproof"],"created_at":"2024-11-09T02:07:21.847Z","updated_at":"2025-07-20T21:34:04.638Z","avatar_url":"https://github.com/zk-Call.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"assets/zk-Call%20Preview%20%5BC++%5D.png\" alt=\"zk-Call Preview [C++]\"\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 C++\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 **`\"HMAC_Client\"`** С++ API is meant to be simple and intuitive:\n\n## Core Components\nThe **`Core Components`** streamline secure **Message Encryption** and **Decryption**, supporting both **Chunk** and **Character-Level** processing for enhanced data protection.\n\n![Detailed Schematic Overview of Core Components](assets/Core%20Components%20(C++).png)\n\n---\n\n#### HMAC_Client.encrypt_message_by_chunks\nMethod to **encrypt a message** by processing it in **chunks**.\n\n    std::string encrypt_message_by_chunks(const std::string\u0026 message);\n\n        message: string                    # The message to be encrypted, processed in chunks\n\n#### HMAC_Client.encrypt_message\nMethod to **encrypt a message** by a **chars**.\n\n    std::string encrypt_message(const std::string\u0026 message);\n\n        message: string                    # The message to be encrypted, processed in characters\n\n#### HMAC_Client.decrypt_message_by_chunks\nMethod to **decrypt a message** by processing it in **chunks**.\n\n     std::string decrypt_message_by_chunks(const std::string\u0026 message);\n\n        message: string                    # The message to be decrypted, processed in chunks\n\n#### HMAC_Client.decrypt_message\nMethod to **decrypt a message** by processing it in **chars**.\n\n     std::string encrypt_message(const std::string\u0026 message);\n\n        message: string                    # The message to be decrypted, processed in characters\n\n---\n\n# Example Usage\nTODO: Include **`Example Usage`**\n\n## Example 1\n\n    #include \u003ciostream\u003e // Include the input/output stream standard header\n    #include \u003cthread\u003e // Include the thread standard header\n    #include \u003cqueue\u003e // Include the queue standard header\n    #include \u003cstring\u003e // Include the string standard header\n    #include \"src/HMAC/core/base.h\" // Include the header file for HMAC_Client functionality\n    #include \"src/SeedGeneration/core/base.h\" // Include the header file for SeedGenerator functionality\n    \n    constexpr bool DEBUG = true; // Define a constexpr boolean variable DEBUG with value true\n    \n    void print_msg(const std::string \u0026who, const std::string \u0026message) { // Define a function to print messages\n        if (DEBUG) { // Check if debugging is enabled\n            std::cout \u003c\u003c \"[\" \u003c\u003c who \u003c\u003c \"] \" \u003c\u003c message \u003c\u003c std::endl; // Print the message with source identifier\n        }\n    }\n    \n    bool check_if_queue_empty(std::queue\u003cstd::string\u003e \u0026socket) { // Define a function to check if a queue is empty\n        while (true) { // Infinite loop\n            if (!socket.empty()) { // Check if the queue is not empty\n                return true; // Return true if the queue is not empty\n            }\n        }\n    }\n    \n    std::string get_content_from_socket(std::queue\u003cstd::string\u003e \u0026socket) { // Define a function to get content from a socket (queue)\n        if (check_if_queue_empty(socket)) { // Check if the queue is not empty\n            std::string val = socket.front(); // Get the front element of the queue\n            socket.pop(); // Remove the front element from the queue\n            return val; // Return the retrieved value\n        }\n    }\n    \n    void client(std::queue\u003cstd::string\u003e \u0026client_socket, std::queue\u003cstd::string\u003e \u0026server_socket) { // Define the client function\n        // Generating the main seed\n        SeedGenerator seed_generator(\"job\"); // Create an instance of SeedGenerator\n        std::vector\u003cunsigned char\u003e main_seed = seed_generator.generate(); // Generate the main seed\n    \n        // Creating an instance of HMAC_Client for encrypting messages\n        print_msg(\"client\", \"first\");\n        HMAC_Client obj(\"sha256\", main_seed, 1); // Create an instance of HMAC_Client\n    \n        // Sending the main seed to the server\n        server_socket.emplace(main_seed.begin(), main_seed.end()); // Convert the main seed vector to a string and send it to the server\n        print_msg(\"client\", \"after obj\");\n    \n        // Checking if the server has successfully received the seed\n        if (get_content_from_socket(client_socket) == obj.encrypt_message(\"\")) { // Check if the server received the seed\n            print_msg(\"client\", \"after if\");\n    \n            // If successful, send a message to the server\n            std::string message = \"hello\"; // Define the message to be sent\n            server_socket.push(obj.encrypt_message_by_chunks(message)); // Encrypt and send the message to the server\n            print_msg(\"client\", \"client sent message \" + message);\n    \n            // Checking if the server has successfully decrypted the message\n            if (get_content_from_socket(client_socket) == obj.encrypt_message(message)) { // Check if the server decrypted the message\n                print_msg(\"client\", \"server has decrypted message\");\n            }\n        }\n    }\n    \n    void server(std::queue\u003cstd::string\u003e \u0026server_socket, std::queue\u003cstd::string\u003e \u0026client_socket) { // Define the server function\n        // Receiving the main seed from the client\n        std::string main_seed = get_content_from_socket(server_socket); // Receive the main seed from the client\n    \n        // Creating an instance of HMAC_Client for encrypting messages\n        HMAC_Client obj(\"sha256\", std::vector\u003cunsigned char\u003e(main_seed.begin(), main_seed.end()), 1); // Create an instance of HMAC_Client\n    \n        // Sending an empty message to the client as acknowledgment\n        client_socket.push(obj.encrypt_message(\"\")); // Encrypt and send an empty message to the client as acknowledgment\n    \n        // Receiving the encrypted message from the client\n        std::string msg = get_content_from_socket(server_socket); // Receive the encrypted message from the client\n        print_msg(\"server\", \"message encrypted: \" + msg);\n    \n        // Decrypting the message\n        print_msg(\"server\", \"before decrypt \");\n        std::string msg_raw = obj.decrypt_message_by_chunks(msg); // Decrypt the received message\n        print_msg(\"server\", \"message raw: \" + msg_raw);\n    \n        // Sending the encrypted message back to the client\n        client_socket.push(obj.encrypt_message(msg_raw)); // Encrypt and send the decrypted message back to the client\n    }\n    \n    int main() { // Main function\n        std::queue\u003cstd::string\u003e client_socket, server_socket; // Create queues for client and server sockets\n        std::thread client_thread(client, std::ref(client_socket), std::ref(server_socket)); // Create a thread for the client function\n        std::thread server_thread(server, std::ref(server_socket), std::ref(client_socket)); // Create a thread for the server function\n    \n        // Joining the threads to wait for their completion\n        client_thread.join(); // Wait for the client thread to finish\n        server_thread.join(); // Wait for the server thread to finish\n    \n        return 0; // Return 0 to indicate successful execution\n    }\n\n---\n\n## Example 2\n\n    #include \"src/ZeroKnowledge/core/base.h\" // Include the header file for ZeroKnowledge class\n\n    int main() { // Main function\n        // Creating a ZeroKnowledge object for the client with specified curve and hash algorithm\n        ZeroKnowledge clientObject = ZeroKnowledge::createNew(\"secp256k1\", \"sha3_256\");\n    \n        // Creating a ZeroKnowledge object for the server with specified curve and hash algorithm\n        ZeroKnowledge serverObject = ZeroKnowledge::createNew(\"secp384r1\", \"sha3_512\");\n    \n        // Setting the server password\n        std::string serverPassword = \"SecretServerPassword\";\n    \n        // Creating a signature for the server password\n        ZeroKnowledgeSignature serverSignature = serverObject.createSignature(serverPassword);\n    \n        // Creating a signature for the client identity\n        std::string identity = \"John\";\n        ZeroKnowledgeSignature clientSignature = clientObject.createSignature(identity);\n        std::cout\u003c\u003c\"before\\n\";\n    \n        // Generating a token signed by the server for the client\n        std::cout\u003c\u003cclientObject.token()\u003c\u003c\"\\n\";\n    \n        ZeroKnowledgeData token = serverObject.sign(serverPassword, clientObject.token());\n        std::cout\u003c\u003c\"after\\n\";\n    \n        // Generating proof using client identity and token\n        ZeroKnowledgeData proof = clientObject.sign(identity, token.data);\n    \n        // Verifying the received proof\n        bool serverVerification = serverObject.verify(token, serverSignature);\n        if (!serverVerification) { // Check if server verification failed\n            std::cout \u003c\u003c \"Server verification failed\" \u003c\u003c std::endl; // Print error message\n        } else { // If server verification succeeded\n            // Otherwise, verify the proof using client signature\n            bool clientVerification = clientObject.verify(token, clientSignature, proof.proof);\n            if (!clientVerification) { // Check if client verification failed\n                std::cout \u003c\u003c \"Client verification failed\" \u003c\u003c std::endl; // Print error message\n            } else { // If client verification succeeded\n                std::cout \u003c\u003c \"Authentication successful\" \u003c\u003c std::endl; // Print success message\n            }\n        }\n    \n        return 0; // Return 0 to indicate successful execution\n    }\n\n---\n\n## Example 3\n\n    #include \"src/ZeroKnowledge/core/base.h\" // Include the header file for ZeroKnowledge class\n    #include \"src/HMAC/core/base.h\" // Include the header file for HMAC_Client functionality\n    #include \"src/SeedGeneration/core/base.h\" // Include the header file for SeedGenerator functionality\n    #include \u003ciostream\u003e // Include the input/output stream standard header\n    #include \u003cthread\u003e // Include the thread standard header\n    #include \u003cqueue\u003e // Include the queue standard header\n    #include \u003cstring\u003e // Include the string standard header\n    \n    constexpr bool DEBUG = true; // Define a constexpr boolean variable DEBUG with value true\n    \n    void print_msg(const std::string \u0026who, const std::string \u0026message) { // Define a function to print messages\n        if (DEBUG) { // Check if debugging is enabled\n            std::cout \u003c\u003c \"[\" \u003c\u003c who \u003c\u003c \"] \" \u003c\u003c message \u003c\u003c std::endl; // Print the message with source identifier\n        }\n    }\n    \n    bool check_if_queue_empty(std::queue\u003cstd::string\u003e \u0026socket) { // Define a function to check if a queue is empty\n        while (true) { // Infinite loop\n            if (!socket.empty()) { // Check if the queue is not empty\n                return true; // Return true if the queue is not empty\n            }\n        }\n    }\n    \n    std::string get_content_from_socket(std::queue\u003cstd::string\u003e \u0026socket) { // Define a function to get content from a socket (queue)\n        if (check_if_queue_empty(socket)) { // Check if the queue is not empty\n            std::string val = socket.front(); // Get the front element of the queue\n            socket.pop(); // Remove the front element from the queue\n            return val; // Return the retrieved value\n        }\n    }\n    \n    void client(std::queue\u003cstd::string\u003e \u0026client_socket, std::queue\u003cstd::string\u003e \u0026server_socket) { // Define the client function\n        // Generating the main seed\n        SeedGenerator seed_generator(\"job\"); // Create an instance of SeedGenerator\n        std::vector\u003cunsigned char\u003e main_seed = seed_generator.generate(); // Generate the main seed\n    \n        // Creating an instance of HMAC_Client for encrypting messages\n        print_msg(\"client\", \"first\");\n        HMAC_Client obj(\"sha256\", main_seed, 1); // Create an instance of HMAC_Client\n    \n        // Sending the main seed to the server\n        server_socket.emplace(main_seed.begin(), main_seed.end()); // Convert the main seed vector to a string and send it to the server\n        print_msg(\"client\", \"after obj\");\n    \n        // Checking if the server has successfully received the seed\n        if (get_content_from_socket(client_socket) == obj.encrypt_message(\"\")) { // Check if the server received the seed\n            print_msg(\"client\", \"after if\");\n    \n            // If successful, send a message to the server\n            std::string message = \"hello\"; // Define the message to be sent\n            server_socket.push(obj.encrypt_message_by_chunks(message)); // Encrypt and send the message to the server\n            print_msg(\"client\", \"client sent message \" + message);\n    \n            // Checking if the server has successfully decrypted the message\n            if (get_content_from_socket(client_socket) == obj.encrypt_message(message)) { // Check if the server decrypted the message\n                print_msg(\"client\", \"server has decrypted message\");\n            }\n        }\n    }\n    \n    void server(std::queue\u003cstd::string\u003e \u0026server_socket, std::queue\u003cstd::string\u003e \u0026client_socket) { // Define the server function\n        // Receiving the main seed from the client\n        std::string main_seed = get_content_from_socket(server_socket); // Receive the main seed from the client\n    \n        // Creating an instance of HMAC_Client for encrypting messages\n        HMAC_Client obj(\"sha256\", std::vector\u003cunsigned char\u003e(main_seed.begin(), main_seed.end()), 1); // Create an instance of HMAC_Client\n    \n        // Sending an empty message to the client as acknowledgment\n        client_socket.push(obj.encrypt_message(\"\")); // Encrypt and send an empty message to the client as acknowledgment\n    \n        // Receiving the encrypted message from the client\n        std::string msg = get_content_from_socket(server_socket); // Receive the encrypted message from the client\n        print_msg(\"server\", \"message encrypted: \" + msg);\n    \n        // Decrypting the message\n        print_msg(\"server\", \"before decrypt \");\n        std::string msg_raw = obj.decrypt_message_by_chunks(msg); // Decrypt the received message\n        print_msg(\"server\", \"message raw: \" + msg_raw);\n    \n        // Sending the encrypted message back to the client\n        client_socket.push(obj.encrypt_message(msg_raw)); // Encrypt and send the decrypted message back to the client\n    }\n    \n    void init_talking() { // Define a function to initialize client-server communication\n        std::queue\u003cstd::string\u003e client_socket, server_socket; // Create queues for client and server sockets\n        std::thread client_thread(client, std::ref(client_socket), std::ref(server_socket)); // Create a thread for the client function\n        std::thread server_thread(server, std::ref(server_socket), std::ref(client_socket)); // Create a thread for the server function\n    \n        // Joining the threads to wait for their completion\n        client_thread.join(); // Wait for the client thread to finish\n        server_thread.join(); // Wait for the server thread to finish\n    }\n    \n    int main() { // Main function\n    \n        // Creating a ZeroKnowledge object for the client with specified curve and hash algorithm\n        ZeroKnowledge clientObject = ZeroKnowledge::createNew(\"secp256k1\", \"sha3_256\");\n    \n        // Creating a ZeroKnowledge object for the server with specified curve and hash algorithm\n        ZeroKnowledge serverObject = ZeroKnowledge::createNew(\"secp384r1\", \"sha3_512\");\n    \n        // Setting the server password\n        std::string serverPassword = \"SecretServerPassword\";\n    \n        // Creating a signature for the server password\n        ZeroKnowledgeSignature serverSignature = serverObject.createSignature(serverPassword);\n    \n        // Creating a signature for the client identity\n        std::string identity = \"John\";\n        ZeroKnowledgeSignature clientSignature = clientObject.createSignature(identity);\n        std::cout \u003c\u003c \"before\\n\";\n    \n        // Generating a token signed by the server for the client\n        std::cout \u003c\u003c clientObject.token() \u003c\u003c \"\\n\";\n    \n        ZeroKnowledgeData token = serverObject.sign(serverPassword, clientObject.token());\n        std::cout \u003c\u003c \"after\\n\";\n    \n        // Generating proof using client identity and token\n        ZeroKnowledgeData proof = clientObject.sign(identity, token.data);\n    \n        // Verifying the received proof\n        bool serverVerification = serverObject.verify(token, serverSignature);\n        if (!serverVerification) { // Check if server verification failed\n            std::cout \u003c\u003c \"Server verification failed\" \u003c\u003c std::endl; // Print error message\n        } else { // If server verification succeeded\n            // Otherwise, verify the proof using client signature\n            bool clientVerification = clientObject.verify(token, clientSignature, proof.proof);\n            if (!clientVerification) { // Check if client verification failed\n                std::cout \u003c\u003c \"Client verification failed\" \u003c\u003c std::endl; // Print error message\n            } else { // If client verification succeeded\n                std::cout \u003c\u003c \"Authentication successful\" \u003c\u003c std::endl; // Print success message\n                init_talking(); // Initialize client-server communication\n    \n            }\n        }\n    \n        return 0; // Return 0 to indicate successful execution\n    }\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzk-call%2Fzkp-hmac-communication-cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzk-call%2Fzkp-hmac-communication-cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzk-call%2Fzkp-hmac-communication-cpp/lists"}