├── .idea
├── .DS_Store
└── .gitignore
├── LICENSE
├── README.md
├── assets
├── Core Components (C++).png
├── Elliptic Curve.png
├── HMAC.png
├── Purpose-1.png
├── Purpose-2.png
├── Schnorr's Protocol.png
├── Synergistic Operation.png
├── ZKP-HMAC-1.png
├── ZKP-HMAC-2.png
├── ZKP-HMAC-3.png
├── ZKP-HMAC-4.png
└── zk-Call Preview [C++].png
├── example1.cpp
├── example2.cpp
├── example3.cpp
└── src
├── HMAC
├── algorithms
│ ├── base.cpp
│ └── base.h
├── core
│ ├── base.cpp
│ └── base.h
├── errors
│ ├── base.cpp
│ └── base.h
├── types
│ ├── base.cpp
│ └── base.h
└── utils
│ ├── base.cpp
│ └── base.h
├── SeedGeneration
├── core
│ ├── base.cpp
│ └── base.h
├── errors
│ ├── base.cpp
│ └── base.h
├── types
│ ├── base.cpp
│ └── base.h
└── utils
│ ├── base.cpp
│ └── base.h
└── ZeroKnowledge
├── algorithms
├── base.cpp
└── base.h
├── core
├── base.cpp
└── base.h
├── errors
├── base.cpp
└── base.h
├── models
├── base.cpp
└── base.h
├── types
├── curve
│ ├── base.cpp
│ └── base.h
└── point
│ ├── base.cpp
│ └── base.h
└── utils
├── base.cpp
└── base.h
/.idea/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/.idea/.DS_Store
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | MIT License
3 |
4 | Copyright (c) 2023 zk-Call & Digital Co.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
![zk-Call Preview [C++]](assets/zk-Call%20Preview%20%5BC++%5D.png)
3 |
4 | zk-Call & Labs
5 |
6 |
7 | "Zero-Knowledge" Proof Implementation with HMAC Communication in C++
8 |
9 |
10 |
11 |

12 |
13 |
14 |
15 | Built by zk-Call :)
16 |
17 |
18 |
19 |
20 | # Table of Contents
21 | - [Credits](#credits)
22 | - [Purpose](#purpose)
23 | - [How it Works](#how-it-works)
24 | - [API](#api)
25 | - [Example Usage](#example-usage)
26 |
27 |
28 | # Credits
29 |
30 | This 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.
31 |
32 | ---
33 |
34 | 
35 |
36 |
37 |
38 | **For further exploration:**
39 |
40 | [**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)
41 |
42 | ---
43 |
44 | 
45 |
46 |
47 | Additionally, 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.
48 |
49 |
50 | On 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.
51 |
52 |
53 |
54 | # Purpose
55 |
56 | In 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**).
57 |
58 | ---
59 |
60 | 
61 |
62 |
63 | **zk-Call & 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.
64 |
65 |
66 |
67 | # How It Works
68 |
69 | The authentication protocol employed in this system operates based on two fundamental concepts:
70 | **"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.
71 |
72 |
73 | "Zero-Knowledge" Proofs (ZKPs)
74 | ---
75 |
76 |
77 | #### **"Zero-Knowledge" Proofs (ZKPs):**
78 | **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.
79 |
80 | ---
81 |
82 | 
83 | 
84 | 
85 | 
86 |
87 |
88 |
89 | #### **Application in Authentication:**
90 | In 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.
91 |
92 |
93 |
94 |
95 | Hash-Based Message Authentication Code (HMAC)
96 | ---
97 |
98 | #### **Hash-Based Message Authentication Code (HMAC):**
99 | **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.
100 |
101 | ---
102 |
103 | 
104 |
105 |
106 | #### **Application in Authentication:**
107 | In 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.
108 |
109 |
110 |
111 | Synergistic Operation
112 | ---
113 | When 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.
114 |
115 | ---
116 |
117 | 
118 |
119 |
120 |
121 | # API
122 |
123 | The **`"HMAC_Client"`** С++ API is meant to be simple and intuitive:
124 |
125 | ## Core Components
126 | The **`Core Components`** streamline secure **Message Encryption** and **Decryption**, supporting both **Chunk** and **Character-Level** processing for enhanced data protection.
127 |
128 | .png)
129 |
130 | ---
131 |
132 | #### HMAC_Client.encrypt_message_by_chunks
133 | Method to **encrypt a message** by processing it in **chunks**.
134 |
135 | std::string encrypt_message_by_chunks(const std::string& message);
136 |
137 | message: string # The message to be encrypted, processed in chunks
138 |
139 | #### HMAC_Client.encrypt_message
140 | Method to **encrypt a message** by a **chars**.
141 |
142 | std::string encrypt_message(const std::string& message);
143 |
144 | message: string # The message to be encrypted, processed in characters
145 |
146 | #### HMAC_Client.decrypt_message_by_chunks
147 | Method to **decrypt a message** by processing it in **chunks**.
148 |
149 | std::string decrypt_message_by_chunks(const std::string& message);
150 |
151 | message: string # The message to be decrypted, processed in chunks
152 |
153 | #### HMAC_Client.decrypt_message
154 | Method to **decrypt a message** by processing it in **chars**.
155 |
156 | std::string encrypt_message(const std::string& message);
157 |
158 | message: string # The message to be decrypted, processed in characters
159 |
160 | ---
161 |
162 | # Example Usage
163 | TODO: Include **`Example Usage`**
164 |
165 | ## Example 1
166 |
167 | #include // Include the input/output stream standard header
168 | #include // Include the thread standard header
169 | #include // Include the queue standard header
170 | #include // Include the string standard header
171 | #include "src/HMAC/core/base.h" // Include the header file for HMAC_Client functionality
172 | #include "src/SeedGeneration/core/base.h" // Include the header file for SeedGenerator functionality
173 |
174 | constexpr bool DEBUG = true; // Define a constexpr boolean variable DEBUG with value true
175 |
176 | void print_msg(const std::string &who, const std::string &message) { // Define a function to print messages
177 | if (DEBUG) { // Check if debugging is enabled
178 | std::cout << "[" << who << "] " << message << std::endl; // Print the message with source identifier
179 | }
180 | }
181 |
182 | bool check_if_queue_empty(std::queue &socket) { // Define a function to check if a queue is empty
183 | while (true) { // Infinite loop
184 | if (!socket.empty()) { // Check if the queue is not empty
185 | return true; // Return true if the queue is not empty
186 | }
187 | }
188 | }
189 |
190 | std::string get_content_from_socket(std::queue &socket) { // Define a function to get content from a socket (queue)
191 | if (check_if_queue_empty(socket)) { // Check if the queue is not empty
192 | std::string val = socket.front(); // Get the front element of the queue
193 | socket.pop(); // Remove the front element from the queue
194 | return val; // Return the retrieved value
195 | }
196 | }
197 |
198 | void client(std::queue &client_socket, std::queue &server_socket) { // Define the client function
199 | // Generating the main seed
200 | SeedGenerator seed_generator("job"); // Create an instance of SeedGenerator
201 | std::vector main_seed = seed_generator.generate(); // Generate the main seed
202 |
203 | // Creating an instance of HMAC_Client for encrypting messages
204 | print_msg("client", "first");
205 | HMAC_Client obj("sha256", main_seed, 1); // Create an instance of HMAC_Client
206 |
207 | // Sending the main seed to the server
208 | server_socket.emplace(main_seed.begin(), main_seed.end()); // Convert the main seed vector to a string and send it to the server
209 | print_msg("client", "after obj");
210 |
211 | // Checking if the server has successfully received the seed
212 | if (get_content_from_socket(client_socket) == obj.encrypt_message("")) { // Check if the server received the seed
213 | print_msg("client", "after if");
214 |
215 | // If successful, send a message to the server
216 | std::string message = "hello"; // Define the message to be sent
217 | server_socket.push(obj.encrypt_message_by_chunks(message)); // Encrypt and send the message to the server
218 | print_msg("client", "client sent message " + message);
219 |
220 | // Checking if the server has successfully decrypted the message
221 | if (get_content_from_socket(client_socket) == obj.encrypt_message(message)) { // Check if the server decrypted the message
222 | print_msg("client", "server has decrypted message");
223 | }
224 | }
225 | }
226 |
227 | void server(std::queue &server_socket, std::queue &client_socket) { // Define the server function
228 | // Receiving the main seed from the client
229 | std::string main_seed = get_content_from_socket(server_socket); // Receive the main seed from the client
230 |
231 | // Creating an instance of HMAC_Client for encrypting messages
232 | HMAC_Client obj("sha256", std::vector(main_seed.begin(), main_seed.end()), 1); // Create an instance of HMAC_Client
233 |
234 | // Sending an empty message to the client as acknowledgment
235 | client_socket.push(obj.encrypt_message("")); // Encrypt and send an empty message to the client as acknowledgment
236 |
237 | // Receiving the encrypted message from the client
238 | std::string msg = get_content_from_socket(server_socket); // Receive the encrypted message from the client
239 | print_msg("server", "message encrypted: " + msg);
240 |
241 | // Decrypting the message
242 | print_msg("server", "before decrypt ");
243 | std::string msg_raw = obj.decrypt_message_by_chunks(msg); // Decrypt the received message
244 | print_msg("server", "message raw: " + msg_raw);
245 |
246 | // Sending the encrypted message back to the client
247 | client_socket.push(obj.encrypt_message(msg_raw)); // Encrypt and send the decrypted message back to the client
248 | }
249 |
250 | int main() { // Main function
251 | std::queue client_socket, server_socket; // Create queues for client and server sockets
252 | std::thread client_thread(client, std::ref(client_socket), std::ref(server_socket)); // Create a thread for the client function
253 | std::thread server_thread(server, std::ref(server_socket), std::ref(client_socket)); // Create a thread for the server function
254 |
255 | // Joining the threads to wait for their completion
256 | client_thread.join(); // Wait for the client thread to finish
257 | server_thread.join(); // Wait for the server thread to finish
258 |
259 | return 0; // Return 0 to indicate successful execution
260 | }
261 |
262 | ---
263 |
264 | ## Example 2
265 |
266 | #include "src/ZeroKnowledge/core/base.h" // Include the header file for ZeroKnowledge class
267 |
268 | int main() { // Main function
269 | // Creating a ZeroKnowledge object for the client with specified curve and hash algorithm
270 | ZeroKnowledge clientObject = ZeroKnowledge::createNew("secp256k1", "sha3_256");
271 |
272 | // Creating a ZeroKnowledge object for the server with specified curve and hash algorithm
273 | ZeroKnowledge serverObject = ZeroKnowledge::createNew("secp384r1", "sha3_512");
274 |
275 | // Setting the server password
276 | std::string serverPassword = "SecretServerPassword";
277 |
278 | // Creating a signature for the server password
279 | ZeroKnowledgeSignature serverSignature = serverObject.createSignature(serverPassword);
280 |
281 | // Creating a signature for the client identity
282 | std::string identity = "John";
283 | ZeroKnowledgeSignature clientSignature = clientObject.createSignature(identity);
284 | std::cout<<"before\n";
285 |
286 | // Generating a token signed by the server for the client
287 | std::cout< // Include the input/output stream standard header
320 | #include // Include the thread standard header
321 | #include // Include the queue standard header
322 | #include // Include the string standard header
323 |
324 | constexpr bool DEBUG = true; // Define a constexpr boolean variable DEBUG with value true
325 |
326 | void print_msg(const std::string &who, const std::string &message) { // Define a function to print messages
327 | if (DEBUG) { // Check if debugging is enabled
328 | std::cout << "[" << who << "] " << message << std::endl; // Print the message with source identifier
329 | }
330 | }
331 |
332 | bool check_if_queue_empty(std::queue &socket) { // Define a function to check if a queue is empty
333 | while (true) { // Infinite loop
334 | if (!socket.empty()) { // Check if the queue is not empty
335 | return true; // Return true if the queue is not empty
336 | }
337 | }
338 | }
339 |
340 | std::string get_content_from_socket(std::queue &socket) { // Define a function to get content from a socket (queue)
341 | if (check_if_queue_empty(socket)) { // Check if the queue is not empty
342 | std::string val = socket.front(); // Get the front element of the queue
343 | socket.pop(); // Remove the front element from the queue
344 | return val; // Return the retrieved value
345 | }
346 | }
347 |
348 | void client(std::queue &client_socket, std::queue &server_socket) { // Define the client function
349 | // Generating the main seed
350 | SeedGenerator seed_generator("job"); // Create an instance of SeedGenerator
351 | std::vector main_seed = seed_generator.generate(); // Generate the main seed
352 |
353 | // Creating an instance of HMAC_Client for encrypting messages
354 | print_msg("client", "first");
355 | HMAC_Client obj("sha256", main_seed, 1); // Create an instance of HMAC_Client
356 |
357 | // Sending the main seed to the server
358 | server_socket.emplace(main_seed.begin(), main_seed.end()); // Convert the main seed vector to a string and send it to the server
359 | print_msg("client", "after obj");
360 |
361 | // Checking if the server has successfully received the seed
362 | if (get_content_from_socket(client_socket) == obj.encrypt_message("")) { // Check if the server received the seed
363 | print_msg("client", "after if");
364 |
365 | // If successful, send a message to the server
366 | std::string message = "hello"; // Define the message to be sent
367 | server_socket.push(obj.encrypt_message_by_chunks(message)); // Encrypt and send the message to the server
368 | print_msg("client", "client sent message " + message);
369 |
370 | // Checking if the server has successfully decrypted the message
371 | if (get_content_from_socket(client_socket) == obj.encrypt_message(message)) { // Check if the server decrypted the message
372 | print_msg("client", "server has decrypted message");
373 | }
374 | }
375 | }
376 |
377 | void server(std::queue &server_socket, std::queue &client_socket) { // Define the server function
378 | // Receiving the main seed from the client
379 | std::string main_seed = get_content_from_socket(server_socket); // Receive the main seed from the client
380 |
381 | // Creating an instance of HMAC_Client for encrypting messages
382 | HMAC_Client obj("sha256", std::vector(main_seed.begin(), main_seed.end()), 1); // Create an instance of HMAC_Client
383 |
384 | // Sending an empty message to the client as acknowledgment
385 | client_socket.push(obj.encrypt_message("")); // Encrypt and send an empty message to the client as acknowledgment
386 |
387 | // Receiving the encrypted message from the client
388 | std::string msg = get_content_from_socket(server_socket); // Receive the encrypted message from the client
389 | print_msg("server", "message encrypted: " + msg);
390 |
391 | // Decrypting the message
392 | print_msg("server", "before decrypt ");
393 | std::string msg_raw = obj.decrypt_message_by_chunks(msg); // Decrypt the received message
394 | print_msg("server", "message raw: " + msg_raw);
395 |
396 | // Sending the encrypted message back to the client
397 | client_socket.push(obj.encrypt_message(msg_raw)); // Encrypt and send the decrypted message back to the client
398 | }
399 |
400 | void init_talking() { // Define a function to initialize client-server communication
401 | std::queue client_socket, server_socket; // Create queues for client and server sockets
402 | std::thread client_thread(client, std::ref(client_socket), std::ref(server_socket)); // Create a thread for the client function
403 | std::thread server_thread(server, std::ref(server_socket), std::ref(client_socket)); // Create a thread for the server function
404 |
405 | // Joining the threads to wait for their completion
406 | client_thread.join(); // Wait for the client thread to finish
407 | server_thread.join(); // Wait for the server thread to finish
408 | }
409 |
410 | int main() { // Main function
411 |
412 | // Creating a ZeroKnowledge object for the client with specified curve and hash algorithm
413 | ZeroKnowledge clientObject = ZeroKnowledge::createNew("secp256k1", "sha3_256");
414 |
415 | // Creating a ZeroKnowledge object for the server with specified curve and hash algorithm
416 | ZeroKnowledge serverObject = ZeroKnowledge::createNew("secp384r1", "sha3_512");
417 |
418 | // Setting the server password
419 | std::string serverPassword = "SecretServerPassword";
420 |
421 | // Creating a signature for the server password
422 | ZeroKnowledgeSignature serverSignature = serverObject.createSignature(serverPassword);
423 |
424 | // Creating a signature for the client identity
425 | std::string identity = "John";
426 | ZeroKnowledgeSignature clientSignature = clientObject.createSignature(identity);
427 | std::cout << "before\n";
428 |
429 | // Generating a token signed by the server for the client
430 | std::cout << clientObject.token() << "\n";
431 |
432 | ZeroKnowledgeData token = serverObject.sign(serverPassword, clientObject.token());
433 | std::cout << "after\n";
434 |
435 | // Generating proof using client identity and token
436 | ZeroKnowledgeData proof = clientObject.sign(identity, token.data);
437 |
438 | // Verifying the received proof
439 | bool serverVerification = serverObject.verify(token, serverSignature);
440 | if (!serverVerification) { // Check if server verification failed
441 | std::cout << "Server verification failed" << std::endl; // Print error message
442 | } else { // If server verification succeeded
443 | // Otherwise, verify the proof using client signature
444 | bool clientVerification = clientObject.verify(token, clientSignature, proof.proof);
445 | if (!clientVerification) { // Check if client verification failed
446 | std::cout << "Client verification failed" << std::endl; // Print error message
447 | } else { // If client verification succeeded
448 | std::cout << "Authentication successful" << std::endl; // Print success message
449 | init_talking(); // Initialize client-server communication
450 |
451 | }
452 | }
453 |
454 | return 0; // Return 0 to indicate successful execution
455 | }
456 |
--------------------------------------------------------------------------------
/assets/Core Components (C++).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/Core Components (C++).png
--------------------------------------------------------------------------------
/assets/Elliptic Curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/Elliptic Curve.png
--------------------------------------------------------------------------------
/assets/HMAC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/HMAC.png
--------------------------------------------------------------------------------
/assets/Purpose-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/Purpose-1.png
--------------------------------------------------------------------------------
/assets/Purpose-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/Purpose-2.png
--------------------------------------------------------------------------------
/assets/Schnorr's Protocol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/Schnorr's Protocol.png
--------------------------------------------------------------------------------
/assets/Synergistic Operation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/Synergistic Operation.png
--------------------------------------------------------------------------------
/assets/ZKP-HMAC-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/ZKP-HMAC-1.png
--------------------------------------------------------------------------------
/assets/ZKP-HMAC-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/ZKP-HMAC-2.png
--------------------------------------------------------------------------------
/assets/ZKP-HMAC-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/ZKP-HMAC-3.png
--------------------------------------------------------------------------------
/assets/ZKP-HMAC-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/ZKP-HMAC-4.png
--------------------------------------------------------------------------------
/assets/zk-Call Preview [C++].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zk-Call/zkp-hmac-communication-cpp/77c9d20971f7d8eaac22a81db90696ccc0efb845/assets/zk-Call Preview [C++].png
--------------------------------------------------------------------------------
/example1.cpp:
--------------------------------------------------------------------------------
1 | #include // Include the input/output stream standard header
2 | #include // Include the thread standard header
3 | #include // Include the queue standard header
4 | #include // Include the string standard header
5 | #include "src/Hmac/core/base.h" // Include the header file for HMAC_Client functionality
6 | #include "src/SeedGeneration/core/base.h" // Include the header file for SeedGenerator functionality
7 |
8 | constexpr bool DEBUG = true; // Define a constexpr boolean variable DEBUG with value true
9 |
10 | void print_msg(const std::string &who, const std::string &message) { // Define a function to print messages
11 | if (DEBUG) { // Check if debugging is enabled
12 | std::cout << "[" << who << "] " << message << std::endl; // Print the message with source identifier
13 | }
14 | }
15 |
16 | bool check_if_queue_empty(std::queue &socket) { // Define a function to check if a queue is empty
17 | while (true) { // Infinite loop
18 | if (!socket.empty()) { // Check if the queue is not empty
19 | return true; // Return true if the queue is not empty
20 | }
21 | }
22 | }
23 |
24 | std::string get_content_from_socket(std::queue &socket) { // Define a function to get content from a socket (queue)
25 | if (check_if_queue_empty(socket)) { // Check if the queue is not empty
26 | std::string val = socket.front(); // Get the front element of the queue
27 | socket.pop(); // Remove the front element from the queue
28 | return val; // Return the retrieved value
29 | }
30 | }
31 |
32 | void client(std::queue &client_socket, std::queue &server_socket) { // Define the client function
33 | // Generating the main seed
34 | SeedGenerator seed_generator("job"); // Create an instance of SeedGenerator
35 | std::vector main_seed = seed_generator.generate(); // Generate the main seed
36 |
37 | // Creating an instance of HMAC_Client for encrypting messages
38 | print_msg("client", "first");
39 | HMAC_Client obj("sha256", main_seed, 1); // Create an instance of HMAC_Client
40 |
41 | // Sending the main seed to the server
42 | server_socket.emplace(main_seed.begin(), main_seed.end()); // Convert the main seed vector to a string and send it to the server
43 | print_msg("client", "after obj");
44 |
45 | // Checking if the server has successfully received the seed
46 | if (get_content_from_socket(client_socket) == obj.encrypt_message("")) { // Check if the server received the seed
47 | print_msg("client", "after if");
48 |
49 | // If successful, send a message to the server
50 | std::string message = "hello"; // Define the message to be sent
51 | server_socket.push(obj.encrypt_message_by_chunks(message)); // Encrypt and send the message to the server
52 | print_msg("client", "client sent message " + message);
53 |
54 | // Checking if the server has successfully decrypted the message
55 | if (get_content_from_socket(client_socket) == obj.encrypt_message(message)) { // Check if the server decrypted the message
56 | print_msg("client", "server has decrypted message");
57 | }
58 | }
59 | }
60 |
61 | void server(std::queue &server_socket, std::queue &client_socket) { // Define the server function
62 | // Receiving the main seed from the client
63 | std::string main_seed = get_content_from_socket(server_socket); // Receive the main seed from the client
64 |
65 | // Creating an instance of HMAC_Client for encrypting messages
66 | HMAC_Client obj("sha256", std::vector(main_seed.begin(), main_seed.end()), 1); // Create an instance of HMAC_Client
67 |
68 | // Sending an empty message to the client as acknowledgment
69 | client_socket.push(obj.encrypt_message("")); // Encrypt and send an empty message to the client as acknowledgment
70 |
71 | // Receiving the encrypted message from the client
72 | std::string msg = get_content_from_socket(server_socket); // Receive the encrypted message from the client
73 | print_msg("server", "message encrypted: " + msg);
74 |
75 | // Decrypting the message
76 | print_msg("server", "before decrypt ");
77 | std::string msg_raw = obj.decrypt_message_by_chunks(msg); // Decrypt the received message
78 | print_msg("server", "message raw: " + msg_raw);
79 |
80 | // Sending the encrypted message back to the client
81 | client_socket.push(obj.encrypt_message(msg_raw)); // Encrypt and send the decrypted message back to the client
82 | }
83 |
84 | int main() { // Main function
85 | std::queue client_socket, server_socket; // Create queues for client and server sockets
86 | std::thread client_thread(client, std::ref(client_socket), std::ref(server_socket)); // Create a thread for the client function
87 | std::thread server_thread(server, std::ref(server_socket), std::ref(client_socket)); // Create a thread for the server function
88 |
89 | // Joining the threads to wait for their completion
90 | client_thread.join(); // Wait for the client thread to finish
91 | server_thread.join(); // Wait for the server thread to finish
92 |
93 | return 0; // Return 0 to indicate successful execution
94 | }
95 |
--------------------------------------------------------------------------------
/example2.cpp:
--------------------------------------------------------------------------------
1 | #include "src/ZeroKnowledge/core/base.h" // Include the header file for ZeroKnowledge class
2 |
3 | int main() { // Main function
4 | // Creating a ZeroKnowledge object for the client with specified curve and hash algorithm
5 | ZeroKnowledge clientObject = ZeroKnowledge::createNew("secp256k1", "sha3_256");
6 |
7 | // Creating a ZeroKnowledge object for the server with specified curve and hash algorithm
8 | ZeroKnowledge serverObject = ZeroKnowledge::createNew("secp384r1", "sha3_512");
9 |
10 | // Setting the server password
11 | std::string serverPassword = "SecretServerPassword";
12 |
13 | // Creating a signature for the server password
14 | ZeroKnowledgeSignature serverSignature = serverObject.createSignature(serverPassword);
15 |
16 | // Creating a signature for the client identity
17 | std::string identity = "John";
18 | ZeroKnowledgeSignature clientSignature = clientObject.createSignature(identity);
19 | std::cout<<"before\n";
20 |
21 | // Generating a token signed by the server for the client
22 | std::cout< // Include the input/output stream standard header
5 | #include // Include the thread standard header
6 | #include // Include the queue standard header
7 | #include // Include the string standard header
8 |
9 | constexpr bool DEBUG = true; // Define a constexpr boolean variable DEBUG with value true
10 |
11 | void print_msg(const std::string &who, const std::string &message) { // Define a function to print messages
12 | if (DEBUG) { // Check if debugging is enabled
13 | std::cout << "[" << who << "] " << message << std::endl; // Print the message with source identifier
14 | }
15 | }
16 |
17 | bool check_if_queue_empty(std::queue &socket) { // Define a function to check if a queue is empty
18 | while (true) { // Infinite loop
19 | if (!socket.empty()) { // Check if the queue is not empty
20 | return true; // Return true if the queue is not empty
21 | }
22 | }
23 | }
24 |
25 | std::string get_content_from_socket(std::queue &socket) { // Define a function to get content from a socket (queue)
26 | if (check_if_queue_empty(socket)) { // Check if the queue is not empty
27 | std::string val = socket.front(); // Get the front element of the queue
28 | socket.pop(); // Remove the front element from the queue
29 | return val; // Return the retrieved value
30 | }
31 | }
32 |
33 | void client(std::queue &client_socket, std::queue &server_socket) { // Define the client function
34 | // Generating the main seed
35 | SeedGenerator seed_generator("job"); // Create an instance of SeedGenerator
36 | std::vector main_seed = seed_generator.generate(); // Generate the main seed
37 |
38 | // Creating an instance of HMAC_Client for encrypting messages
39 | print_msg("client", "first");
40 | HMAC_Client obj("sha256", main_seed, 1); // Create an instance of HMAC_Client
41 |
42 | // Sending the main seed to the server
43 | server_socket.emplace(main_seed.begin(), main_seed.end()); // Convert the main seed vector to a string and send it to the server
44 | print_msg("client", "after obj");
45 |
46 | // Checking if the server has successfully received the seed
47 | if (get_content_from_socket(client_socket) == obj.encrypt_message("")) { // Check if the server received the seed
48 | print_msg("client", "after if");
49 |
50 | // If successful, send a message to the server
51 | std::string message = "hello"; // Define the message to be sent
52 | server_socket.push(obj.encrypt_message_by_chunks(message)); // Encrypt and send the message to the server
53 | print_msg("client", "client sent message " + message);
54 |
55 | // Checking if the server has successfully decrypted the message
56 | if (get_content_from_socket(client_socket) == obj.encrypt_message(message)) { // Check if the server decrypted the message
57 | print_msg("client", "server has decrypted message");
58 | }
59 | }
60 | }
61 |
62 | void server(std::queue &server_socket, std::queue &client_socket) { // Define the server function
63 | // Receiving the main seed from the client
64 | std::string main_seed = get_content_from_socket(server_socket); // Receive the main seed from the client
65 |
66 | // Creating an instance of HMAC_Client for encrypting messages
67 | HMAC_Client obj("sha256", std::vector(main_seed.begin(), main_seed.end()), 1); // Create an instance of HMAC_Client
68 |
69 | // Sending an empty message to the client as acknowledgment
70 | client_socket.push(obj.encrypt_message("")); // Encrypt and send an empty message to the client as acknowledgment
71 |
72 | // Receiving the encrypted message from the client
73 | std::string msg = get_content_from_socket(server_socket); // Receive the encrypted message from the client
74 | print_msg("server", "message encrypted: " + msg);
75 |
76 | // Decrypting the message
77 | print_msg("server", "before decrypt ");
78 | std::string msg_raw = obj.decrypt_message_by_chunks(msg); // Decrypt the received message
79 | print_msg("server", "message raw: " + msg_raw);
80 |
81 | // Sending the encrypted message back to the client
82 | client_socket.push(obj.encrypt_message(msg_raw)); // Encrypt and send the decrypted message back to the client
83 | }
84 |
85 | void init_talking() { // Define a function to initialize client-server communication
86 | std::queue client_socket, server_socket; // Create queues for client and server sockets
87 | std::thread client_thread(client, std::ref(client_socket), std::ref(server_socket)); // Create a thread for the client function
88 | std::thread server_thread(server, std::ref(server_socket), std::ref(client_socket)); // Create a thread for the server function
89 |
90 | // Joining the threads to wait for their completion
91 | client_thread.join(); // Wait for the client thread to finish
92 | server_thread.join(); // Wait for the server thread to finish
93 | }
94 |
95 | int main() { // Main function
96 |
97 | // Creating a ZeroKnowledge object for the client with specified curve and hash algorithm
98 | ZeroKnowledge clientObject = ZeroKnowledge::createNew("secp256k1", "sha3_256");
99 |
100 | // Creating a ZeroKnowledge object for the server with specified curve and hash algorithm
101 | ZeroKnowledge serverObject = ZeroKnowledge::createNew("secp384r1", "sha3_512");
102 |
103 | // Setting the server password
104 | std::string serverPassword = "SecretServerPassword";
105 |
106 | // Creating a signature for the server password
107 | ZeroKnowledgeSignature serverSignature = serverObject.createSignature(serverPassword);
108 |
109 | // Creating a signature for the client identity
110 | std::string identity = "John";
111 | ZeroKnowledgeSignature clientSignature = clientObject.createSignature(identity);
112 | std::cout << "before\n";
113 |
114 | // Generating a token signed by the server for the client
115 | std::cout << clientObject.token() << "\n";
116 |
117 | ZeroKnowledgeData token = serverObject.sign(serverPassword, clientObject.token());
118 | std::cout << "after\n";
119 |
120 | // Generating proof using client identity and token
121 | ZeroKnowledgeData proof = clientObject.sign(identity, token.data);
122 |
123 | // Verifying the received proof
124 | bool serverVerification = serverObject.verify(token, serverSignature);
125 | if (!serverVerification) { // Check if server verification failed
126 | std::cout << "Server verification failed" << std::endl; // Print error message
127 | } else { // If server verification succeeded
128 | // Otherwise, verify the proof using client signature
129 | bool clientVerification = clientObject.verify(token, clientSignature, proof.proof);
130 | if (!clientVerification) { // Check if client verification failed
131 | std::cout << "Client verification failed" << std::endl; // Print error message
132 | } else { // If client verification succeeded
133 | std::cout << "Authentication successful" << std::endl; // Print success message
134 | init_talking(); // Initialize client-server communication
135 |
136 | }
137 | }
138 |
139 | return 0; // Return 0 to indicate successful execution
140 | }
--------------------------------------------------------------------------------
/src/HMAC/algorithms/base.cpp:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | // Function definition for Hash_type_and_len()
4 | std::map Hash_type_and_len() {
5 | // Create a map object to store hash types and their corresponding lengths
6 | std::map obj;
7 |
8 | // Assign hash types and their lengths to the map
9 | obj["sha3_224"] = 56; // SHA-3 224-bit hash length
10 | obj["sha256"] = 64; // SHA-256 hash length
11 |
12 | // Return the populated map
13 | return obj;
14 | }
15 |
--------------------------------------------------------------------------------
/src/HMAC/algorithms/base.h:
--------------------------------------------------------------------------------
1 | #ifndef HMAC_ALGORITHMS_BASE_H
2 | // Preprocessor directive to ensure that this header file is included only once during compilation
3 |
4 | #define HMAC_ALGORITHMS_BASE_H
5 | // Definition of the header guard macro to prevent multiple inclusions of the header file
6 |
7 | #include