I have a function named ARCMF that is supposed to return the same pseudorandom output for every same set of inputs state and keys which are both passed by readonly reference using the keyword in. However, when I try running this function twice, the first and second result are never equal to each other (but are equal every time I restart the program). After extensive debugging, it seems as though the variable in question gets modified. I tried setting it to readonly but it STILL gets modified somehow. This has left me stumped for hours...
All of my code is here on this repo.
This is the variable in question (from now on I will refer to as IV) which I have in a watch window during debugging, and I pass it into a function called ARCMF...
var arc = new ARC128(key, iv);
var mf0 = arc.ARCMF(iv, arc.Schedule(key, iv, 1));
arc.PrintArray(mf0, "Main Function Iteration 0 Results");
var mf1 = arc.ARCMF(iv, arc.Schedule(key, iv, 1));
arc.PrintArray(mf1, "Main Function Iteration 1 Results");
c.WriteLine(Enumerable.SequenceEqual(mf0, mf1) ? "MF Gen success." : "MF Gen fail.");
internal byte[] ARCMF(in byte[] state, in byte[][] keys)
{
var output = state;
for (int i = 0; i < 9; i )
{
ARCLT.Permutate(ref output, ARCLT.MBLTv1, i);
ARCBMGR(ref output);
ARCLT.Permutate(ref output, ARCLT.SBLTv1, i);
output = OTPArray(output, keys[i]);
}
return output;
}
The modification of IV happens specifically after ARCLT.Permutate(ref output, ARCLT.MBLTv1, i);
To help show this, heres some screenshots.
Before ( I cant embed images :( ) and After.
And the function itself looks like this:
internal static void Permutate(ref byte[] io, in byte[] table, int seed = 1)
{
seed = (seed == 0) ? 1 : seed;
for (int i = 0; i <= io.Length - 1; i )
io[i] = (byte)((io[i] * seed % 256) ^ table[i]);
}
And for those curious, heres what the program outputs:
Main Function Iteration 0 Results: 785B62AFE54AB7FA7A4EE63D67A311A8
Main Function Iteration 1 Results: F47B4EF85524B92B6F210F9EDCD5786
MF Gen fail.
What should I do?
Update 1: Changing the Permutate function to
internal static byte[] Permutate(byte[] io, in byte[] table, int seed = 1)
{
var o = io;
seed = (seed == 0) ? 1 : seed;
for (int i = 0; i <= io.Length - 1; i )
o[i] = (byte)((o[i] * seed % 256) ^ table[i]);
return o;
}
makes no difference.
CodePudding user response:
You're mixing it in with Ref keywords. Ref will modify those values.
Make a copy of it and use the copy.
var output = new byte[state.Length];
state.CopyTo(output, 0);
or
var output = state.ToArray();
CodePudding user response:
Because you are using the ref keyword.
It allows sub-methods to modify the parameter's value in memory.
In your case, the parameter output (byte-structure typed) is modified twice when you set the value each time with:
io[i] = (byte)((io[i] * seed % 256) ^ table[i]);.
