} // End method Crossover(). /// <summary> /// Mutate (XOR) the intermediate image with a secret /// image stored in the key. /// </summary> /// <param name="s3"> /// The stream array that is used to select a pseudo-random row index /// for XOR-ing with a secret image. /// </param> /// <param name="s4"> /// The stream array that is used to select a pseudo-random column /// index for XOR-ing with a secret image. /// </param> private void Mutate(int[] s3, int[] s4) { int m = PlaintextImage.Height; // Number of rows. int n = PlaintextImage.Width; // Number of columns. // The (x, y) pixel value from the intermediate image. uint intermediate = 0; // The (s3[x], s4[y]) pixel value from the secret image. uint secret = 0; // The "mutated" pixel is the exclusive-or (XOR) of the // intermediate pixel and the secret key pixel. uint xor = 0; for (int y = 0; y < m; ++y) { for (int x = 0; x < n; ++x) { intermediate = (uint)CiphertextImage. GetPixel(x, y).ToArgb(); secret = (uint)Key.SecretImage. GetPixel(s3[x], s4[y]).ToArgb(); xor = ((uint)(intermediate ^ secret) | 0xff000000); CiphertextImage.SetPixel(x, y, Color.FromArgb((int)xor)); } } } // End method Mutate().
/// <summary> /// Applies the k-epsilon dissipative turbulence /// value to the secret image. /// </summary> private void ApplyDissipativeTurbulence() { // Retrieve the size of the image in pixels. int m = PlaintextImage.Width; int n = PlaintextImage.Height; // This is the scalar value to apply to the XOR operation. byte scalar = GetTurbulenceMultiplier(); // For every pixel in the image, XOR its value with the // value of the secret image and the turbulence scalar value. for (int y = 0; y < n; ++y) { for (int x = 0; x < m; ++x) { int pixel = CiphertextImage.GetPixel(x, y).ToArgb(); int secPixel = Key.SecretImage.GetPixel(x, y).ToArgb(); // The luminance value of the XOR of the // input image and the secret image. byte Y = (byte)((pixel & 0x000000ff) ^ (secPixel & 0x000000ff)); // Apply the scalar value. int xor = Y ^ scalar; Color newPix = Color.FromArgb(0xff, xor, xor, xor); CiphertextImage.SetPixel(x, y, newPix); } } } // End method ApplyDissipativeTurbulence().
} // End method ApplyMomentumFlux(). /// <summary> /// This method applies the column-wise heat fluxes. /// </summary> private void ApplyHeatFlux() { // Retrieve the size of the image in pixels. int n = PlaintextImage.Height; int m = PlaintextImage.Width; // Generate a logistic map to seed the mass flow rate vector. double[] logisticMap = GenerateLogisticMap(Key.R_qdot, Key.HeatTransferInitializer, m); // The elements of the heat flux vector are in // the integer set [0, 255]. This is effectively an // initialization vector for the bottom scanline. int[] columnHeatFlux = new int[m]; for (int i = 0; i < m; ++i) { columnHeatFlux[i] = (int)(255 * logisticMap[i]); } // For every pixel in the image, XOR its value with the // value of the pixel beneath it. for (int x = 0; x < m; ++x) { for (int y = 0; y < n; ++y) { Color source = CiphertextImage.GetPixel(x, y); int Tj = (source.ToArgb() & 0x000000ff); int Tj1 = Tj ^ columnHeatFlux[x]; Color replaceWith = Color.FromArgb(0xff, Tj1, Tj1, Tj1); CiphertextImage.SetPixel(x, y, replaceWith); } } } // End method ApplyHeatFlux().
/// <summary> /// Perform row and column crossover operations to permute the /// image data into an intermediate image. /// </summary> /// <param name="s1"> /// The stream array that is used to perform row-wise crossover. /// </param> /// <param name="s2"> /// The stream array that is used to perform columnn-wise crossover. /// </param> private void CrossOver(int[] s1, int[] s2) { int m = PlaintextImage.Height; // Number of rows. int n = PlaintextImage.Width; // Number of columns. // Ensure that the number of cut points is even! int numRowCutPoints = (int)Math.Floor((double)n / 2.0); int numColCutPoints = (int)Math.Floor((double)m / 2.0); int[] rowCutPoints = new int[numRowCutPoints]; int[] colCutPoints = new int[numColCutPoints]; // Perform row-wise crossovers for (int y = 1; y < m; ++y) { rowCutPoints[0] = Math.Abs(s1[y - 1] - s1[y]) % m; for (int k = 1; k < numRowCutPoints; ++k) { rowCutPoints[k] = (rowCutPoints[k - 1] + Math.Abs(s1[y - 1] - s1[y])) % m; } Array.Sort(rowCutPoints); for (int k = 1; k < numRowCutPoints; ++k) { for (int x = rowCutPoints[k - 1]; x < rowCutPoints[k]; ++x) { // Swap the pixels. Color pix1 = CiphertextImage.GetPixel(x, s1[y]); Color pix2 = CiphertextImage.GetPixel(x, s1[y - 1]); CiphertextImage.SetPixel(x, s1[y], pix2); CiphertextImage.SetPixel(x, s1[y - 1], pix1); } } } // End row-wise crossovers. // Perform column-wise crossovers for (int x = 1; x < n; ++x) { colCutPoints[0] = Math.Abs(s2[x - 1] - s2[x]) % n; for (int k = 1; k < numColCutPoints; ++k) { colCutPoints[k] = (colCutPoints[k - 1] + Math.Abs(s2[x - 1] - s2[x])) % n; } Array.Sort(colCutPoints); for (int k = 1; k < numColCutPoints; ++k) { for (int y = colCutPoints[k - 1]; y < colCutPoints[k]; ++y) { // Swap the pixels. Color pix1 = CiphertextImage.GetPixel(s2[x], y); Color pix2 = CiphertextImage.GetPixel(s2[x - 1], y); CiphertextImage.SetPixel(s2[x], y, pix2); CiphertextImage.SetPixel(s2[x - 1], y, pix1); } } } // End column-wise crossovers. } // End method Crossover().