## 3 Proposed Method  
The implementation proposed in this paper was written using the C++ programming language and the MPI standard, specifically the OpenMPI implementation. MPI is a standard that allows multiple processors with distributed memory (each with its own separate memory) to work together on a task by exchanging information through messages. By breaking down a large task across processors, MPI enables faster and efficient processing, making it ideal for scientific computing and simulations. Our implementation leverages key MPI functions such as MPI_Send and MPI_Recv to exchange data and synchronize operations among processes. The approach for the parallel rainbow tables generation is based on the master-slave parallelization model with a modification. The classic model was used by [PERSON] [10] and it seems to be a reasonable choice, as it makes resolving merges in rainbow tables a lot easier in a distributed memory environment. The implementation from [PERSON] [10] follows the standard master-slave communication pattern, where the master generates the data and distributes it to all the slave processes, and they, in return, send the results back to the master process, which finalizes the task. The traditional master-slave models introduce a bottleneck due to the master distributing tasks. Our approach eliminates this step and improves efficiency. We decided to let each process (slaves and master) generate starting points independently and send back the generated chains to the master process, which decides whether to accept a chain or reject it depending on whether a chain with the same endpoint exists in the table. This is done by utilizing a set data structure that handles duplicates. This is done in order to get a clean rainbow table, which is a table without merged chains. It is important to note that the generated table is not a perfect table; the imperfection comes from the lack of a chain regeneration mechanism for rejected chains. This design choice helps not only to simplify the handling of merged chains but also to reduce the number of point-to-point communications, which can have a significant influence on the execution time, speedup and efficiency of the parallel implementation. By allowing each process to generate starting points independently, the workload is naturally distributed among all nodes, ensuring even computational distribution. This approach eliminates the risk of any single process becoming a bottleneck, leading to more efficient scaling as additional nodes are introduced. We emphasize that our implementation is designed to reduce the impact of network latency by decreasing the number of small messages being sent and eliminating the unnecessary communications. Figure 1 depicts a visual pseudocode of the proposed implementation. The light blue frame highlights the portion of the code that is executed by the master process, and the purple frame highlights the portion of the code that is executed by the slave processes. Figure 2 illustrates the parallel computing workflow using MPI for the proposed modified master-slave architecture. The sequence diagram depicts the interactions between a master process (rank 0) and multiple slave processes (rank 1 to rank N\(-\)1). Each lifeline in the sequence diagram represents an MPI process that performs the starting and endpoints generation. The program begins by initializing the MPI environment with MPI_Init(), where each process retrieves its rank and the total number of processes. Each process independently generates a subset of start points (SP) by converting indices into string representations and computes hash chains locally. For each starting point, the chain is computed by repeatedly applying a hash function followed by a reduction function, with the final reduced value stored as the endpoint (EP).