private byte[] BlockConvert(byte[] input, BigInteger n_input, BigInteger n_output, blockconvertDelegate cFunc, bool encrypt) { int blocksize_input, blocksize_output; if (encrypt) { blocksize_input = (int)Math.Floor(BigInteger.Log(n_input, 256)); blocksize_output = (int)Math.Ceiling(BigInteger.Log(n_output, 256)); } else { blocksize_input = (int)Math.Ceiling(BigInteger.Log(n_input, 256)); blocksize_output = (int)Math.Floor(BigInteger.Log(n_output, 256)); } return(BlockConvert(input, blocksize_input, blocksize_output, cFunc)); }
///<summary> /// BlockConvert interprets the bytearray 'input' as a sequence of BigIntegers with 'blocksize_input' bytes per BigInteger. /// The funtion 'cFunc' is applied on each of these BigIntegers. The results of 'cFunc' are BigIntegers /// that are then transformed back into a bytearray with 'blocksize_output' bytes per BigInteger. ///</summary> private byte[] BlockConvert(byte[] input, int blocksize_input, int blocksize_output, blockconvertDelegate cFunc) { if (blocksize_input <= 0) { throw new Exception("Illegal Input blocksize " + blocksize_input); } if (blocksize_output <= 0) { throw new Exception("Output blocksize " + blocksize_output); } int blockcount = (input.Length + blocksize_input - 1) / blocksize_input; byte[] output = new byte[blocksize_output * blockcount]; for (int ofs_in = 0, ofs_out = 0; ofs_in < input.Length; ofs_in += blocksize_input, ofs_out += blocksize_output) { BigInteger m = BigIntegerFromBuffer(input, ofs_in, Math.Min(input.Length - ofs_in, blocksize_input)); m = cFunc(m); BigIntegerIntoBuffer(m, output, ofs_out, blocksize_output); } return(output); }