static int Main(string[] args)
        {
            Encryption_Module helpers = new Encryption_Module();
            bool      verbose         = false;
            int       num_cols        = 8;
            const int pad_bytes       = 2;
            var       timer           = new System.Diagnostics.Stopwatch();

            // Validate inputs
            if (args.Length == 0)
            {
                Console.WriteLine("Usage: encrypt.exe [INPUT CSV DATA] [OUTPUT CSV] [OUTPUT PRIVATE KEY] [OUTPUT PUBLIC KEY]");
                return(1);
            }

            // Load file locations
            String input_csv = args[0];
            // String output_csv = args[1];
            // String output_private_key = args[2];
            // String output_public_key = args[3];

            // Load CSV into 2D Array
            preProccessedData data = CSV_Loader(input_csv);

            // Process Data
            UInt64[,] processed_data = process_korea_format(data);
            BinaryWriter file_writer = new BinaryWriter(File.Open(args[1], FileMode.Create));

            timer.Start();
            // Loop over rows of data
            for (int i = 0; i <= processed_data.GetUpperBound(0); i++)
            //for (int i = 0; i <= 1; i++)
            {
                if (processed_data[i, 0] != 0)
                {
                    // Print processed data
                    if (verbose)
                    {
                        for (int k = 0; k < num_cols; k++)
                        {
                            Console.Write("{0} ", processed_data[i, k]);
                        }
                        Console.WriteLine("");
                    }

                    // Store each row in bytes
                    byte[] byted_row = new byte[num_cols * sizeof(UInt64)];
                    for (int j = 0; j < num_cols; j++)
                    {
                        Buffer.BlockCopy(BitConverter.GetBytes(processed_data[i, j]), 0, byted_row, j * sizeof(UInt64), sizeof(UInt64));
                    }

                    // For each cell in the row
                    for (int k = 0; k < num_cols; k++)
                    {
                        if (verbose)
                        {
                            //Console.WriteLine("Before Rand:");
                            ProcessBA(byted_row, k * sizeof(UInt64));
                        }

                        // Pad 2 most significant bytes with random values
                        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
                        rng.GetBytes(byted_row, sizeof(UInt64) - pad_bytes + k * sizeof(UInt64), pad_bytes);

                        if (verbose)
                        {
                            //Console.WriteLine("After Rand:");
                            ProcessBA(byted_row, k * sizeof(UInt64));
                        }
                    }

                    //Encrypt Bytes:
                    //Parallel encryption (speeds up from 2.8 s -> 1.3s)
                    ParallelOptions po = new ParallelOptions();
                    po.MaxDegreeOfParallelism = 8;

                    UInt64[] encrypted_values = new UInt64[num_cols];
                    //for (int current_cell = 0; current_cell < num_cols; current_cell++)
                    Parallel.For(0, num_cols, po, (current_cell) =>
                    {
                        UInt64 c_value_int             = BitConverter.ToUInt64(byted_row, sizeof(UInt64) * current_cell);
                        encrypted_values[current_cell] = helpers.encryptCell(c_value_int);
                        Buffer.BlockCopy(BitConverter.GetBytes(encrypted_values[current_cell]), 0, byted_row, current_cell * sizeof(UInt64), sizeof(UInt64));
                        if (verbose)
                        {
                            //Console.WriteLine("After Rand:");
                            ProcessBA(byted_row, current_cell * sizeof(UInt64));
                        }
                    });

                    // write row to file

                    file_writer.Write(byted_row);
                }
            }
            timer.Stop();

            // Close data files
            file_writer.Flush();
            file_writer.Close();

            Console.WriteLine($"Execution Time: {timer.ElapsedMilliseconds} ms");
            return(0);
        }
        private static UInt64[,] process_korea_format(preProccessedData raw_CSV)
        {
            UInt64[,] processed_data = new UInt64[raw_CSV.num_rows, 8];
            int processed_data_row = 0;

            // Loop over all rows in raw_csv / preprocessed data
            for (int curr_row = 1; curr_row < raw_CSV.num_rows; curr_row++)
            {
                // Check if the row has data we want
                if (raw_CSV.data[curr_row, id_col] == "" || raw_CSV.data[curr_row, gender_col] == "" || raw_CSV.data[curr_row, age_col] == "" || raw_CSV.data[curr_row, state_col] == "")
                {
                    continue;
                }
                else
                {
                    // Copy over patient ID
                    processed_data[processed_data_row, 0] = (UInt64)processed_data_row;

                    // Copy over gender data
                    if (raw_CSV.data[curr_row, gender_col] == "male")
                    {
                        processed_data[processed_data_row, 1] = 1;
                        processed_data[processed_data_row, 2] = 0;
                        processed_data[processed_data_row, 3] = 0;
                    }
                    else if (raw_CSV.data[curr_row, gender_col] == "female")
                    {
                        processed_data[processed_data_row, 1] = 0;
                        processed_data[processed_data_row, 2] = 1;
                        processed_data[processed_data_row, 3] = 0;
                    }
                    else
                    {
                        processed_data[processed_data_row, 1] = 0;
                        processed_data[processed_data_row, 2] = 0;
                        processed_data[processed_data_row, 3] = 1;
                    }

                    // Copy over age
                    processed_data[processed_data_row, 4] = UInt64.Parse(raw_CSV.data[curr_row, age_col]);

                    // Copy over status

                    // Copy over gender data
                    if (raw_CSV.data[curr_row, state_col] == "deceased")
                    {
                        processed_data[processed_data_row, 5] = 1;
                        processed_data[processed_data_row, 6] = 0;
                        processed_data[processed_data_row, 7] = 0;
                    }
                    else if (raw_CSV.data[curr_row, state_col] == "released")
                    {
                        processed_data[processed_data_row, 5] = 0;
                        processed_data[processed_data_row, 6] = 1;
                        processed_data[processed_data_row, 7] = 0;
                    }
                    else
                    {
                        processed_data[processed_data_row, 5] = 0;
                        processed_data[processed_data_row, 6] = 0;
                        processed_data[processed_data_row, 7] = 1;
                    }

                    // Move to next row in processed data
                    processed_data_row++;
                }
            }
            return(processed_data);
        }