/************************************************** * Public Methods * **************************************************/ /// <summary> /// Encrypt the plaintext image with the given key. /// </summary> public void Encrypt() { // Check the input for the correct domain of values. if (Key == null || !Key.IsValidKey()) { throw new System.ArgumentException("The key is not valid."); } // Ensure that a plaintext image is available for encryption. if (PlaintextImage == null) { throw new System.NullReferenceException( "The plaintext image is not defined."); } // Ensure that we have a 24bpp image to work with since SetPixel() // won't work with an indexed image. CiphertextImage = PlaintextImage.Clone( new Rectangle(0, 0, PlaintextImage.Width, PlaintextImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); ApplyMomentumFlux(); ApplyHeatFlux(); ApplyDissipativeTurbulence(); } // End method Encrypt().
/************************************************** * Public Methods * **************************************************/ /// <summary> /// Encrypt the plaintext image with the given key. /// </summary> public void Encrypt() { // Check the input for the correct domain of values. if (Key == null || !Key.IsValidKey()) { throw new System.ArgumentException("The key is not valid."); } // Ensure that a plaintext image is available for encryption. if (PlaintextImage == null) { throw new System.NullReferenceException( "The plaintext image is not defined."); } // Ensure that we have a 24bpp image to work with since SetPixel() // won't work with an indexed image. CiphertextImage = PlaintextImage.Clone( new Rectangle(0, 0, PlaintextImage.Width, PlaintextImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); double [] x1; // Chaos map for row crossovers. double [] x2; // Chaos map for col. crossovers. double [] x3; // Chaos map for row mutation. double [] x4; // Chaos map for col. mutation. GenerateLogisticMaps(out x1, out x2, out x3, out x4); // Quantification Unit -- Generates four key streams. // // s1 is used to perform row-wise crossover // s2 is used to perform columnn-wise crossover // s3 is used to select a pseudo-random row index // in a secret image for XOR-ing. // s4 is used to select a pseudo-random column index // in a secret image for XOR-ing. // int [] s1; // The indices of the sorted x1 array. int [] s2; // The indices of the sorted x2 array. int [] s3; // The indices of the sorted x3 array. int [] s4; // The indices of the sorted x4 array. GenerateQuantificationUnits( x1, x2, x3, x4, out s1, out s2, out s3, out s4); // Perform the row and column crossover steps. CrossOver(s1, s2); // Mutate (XOR) the intermediate image with the // secret image from the key. Mutate(s3, s4); CiphertextImage = GrayScale(CiphertextImage); } // End method Encrypt.
} // End method Encrypt(). /// <summary> /// This method applies the row-wise (scanline) momentum (mass) fluxes. /// </summary> private void ApplyMomentumFlux() { // 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_mdot, Key.MassFlowRateInitializer, n); // The row-wise mass flow rates are a true set of integers [0, n]. int[] rowMassFlowRate = new int[n]; for (int i = 0; i < n; ++i) { rowMassFlowRate[i] = i; } // Randomize the mass flow rates by the sort order // of the logistic map vector. Array.Sort(logisticMap, rowMassFlowRate); // Right circular rotate each scanline in the image. int row = 0; for (int y = 0; y < n; ++y) { for (int x = 0; x < m; ++x) { int replacementIndex = (x + rowMassFlowRate[row]) % m; Color replaceWith = PlaintextImage.GetPixel(replacementIndex, y); CiphertextImage.SetPixel(x, y, replaceWith); } row++; } } // End method ApplyMomentumFlux().
/************************************************** * Public Methods * **************************************************/ /// <summary> /// Encrypt the plaintext image with the given key. /// </summary> public void Encrypt() { // Make sure we have a key! if (Key == null) { throw new System.ArgumentException( "The key has not been instantiated."); } // Ensure that a plaintext image is available for encryption. if (PlaintextImage == null) { throw new System.NullReferenceException( "The plaintext image is not defined."); } // We need to ensure that the plaintext image is grayscale. PlaintextImage = GrayScale( PlaintextImage.Clone(new Rectangle(0, 0, PlaintextImage.Width, PlaintextImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb)); // Ensure that we have a 24bpp image to work with since SetPixel() // won't work with an indexed image. CiphertextImage = PlaintextImage.Clone( new Rectangle(0, 0, PlaintextImage.Width, PlaintextImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); int [,] schedule = GenerateStateSchedule(Key.Seed); int [] attractorRing = MakeAttractorRing(Key.StateOne, Key.Rule); int lum = 0; // The luminance value of a given pixel. int stateIndex = 0; for (int y = 0; y < PlaintextImage.Height; ++y) { for (int x = 0; x < PlaintextImage.Width; ++x) { // Since the image is grayscale we only need // one channel's data. lum = PlaintextImage.GetPixel(x, y).ToArgb() & 0x000000ff; // Jin recommends each pixel's starting state use the // attractor ring index (x + y) mod 8. stateIndex = (x + y) % 8; lum ^= attractorRing[stateIndex]; // This provides the avalanche effect. for (int i = 0; i < schedule[x, y]; ++i) { stateIndex = (++stateIndex) % 8; lum ^= attractorRing[stateIndex]; } // Write the pixel data to the ciphertext image. CiphertextImage.SetPixel( x, y, Color.FromArgb(0xff, lum, lum, lum)); } } } // End method Encrypt().