static bool RoundConstant(int t) { t = BinaryFunctions.Mod(t, 255); if (RoundConstants.ContainsKey(t)) { return(RoundConstants[t]); } var r = new BitString("10000000", 8); for (var i = 0; i < t; i++) { r.Prepend(BitString.Zero); r[0] ^= r[8]; r[4] ^= r[8]; r[5] ^= r[8]; r[6] ^= r[8]; r = r.Truncate(8); } var bit = r[0]; RoundConstants.Add(t, bit); return(bit); }
static SpongeState Rho(SpongeState state) { var newState = new SpongeState(state.Size, state.Rate); var w = state.Size.W; newState.SetLane(newState.GetLane(0, 0), state.GetLane(0, 0).GetBits()); var x = 1; var y = 0; for (var t = 0; t < 24; t++) { var u = ((t + 1) * (t + 2)) >> 1; for (var z = 0; z < w; z++) { newState[x, y, z] = state[x, y, BinaryFunctions.Mod(z - u, w)]; } var oldX = x; x = y; y = BinaryFunctions.Mod(2 * oldX + 3 * y, 5); } state.SetBitString(newState.BitString); return(state); }
public BitString(byte[] data, int length = -1) { data = data ?? throw new ArgumentNullException(nameof(data)); var count = data.Length; var bitCount = count << Shift; _length = length < 0 ? bitCount : length; if (_length > bitCount) { throw new ArgumentOutOfRangeException(nameof(length)); } // If the full range of bits is to be considered, whole process is a lot simpler. if (_length != bitCount) { // How many blocks will we need? count = (int)Math.Ceiling((double)_length / BlockBitSize); Array.Resize(ref data, count); // If the last block is not full, zero the trailing bits which do not belong to the bitString. var remaining = _length % BlockBitSize; if (remaining > 0) { data[count - 1] &= BinaryFunctions.LowerMask(remaining); } } _data = data; }
protected override BitString GetPadding(int r, int m) { var j = BinaryFunctions.Mod(-m - 2, r); var pad = new BitString(j + 2); pad[0] = true; pad[pad.Length - 1] = true; return(pad); }
public static BitString Random(Random random, int length) { var count = (int)Math.Ceiling((double)length / BlockBitSize); var data = new byte[count]; random.NextBytes(data); var left = length % BlockBitSize; if (left != 0) { data[count - 1] &= BinaryFunctions.LowerMask(left); } return(new BitString(data, length)); }
public BitString Truncate(int length) { length = Math.Min(_length, Math.Max(0, length)); var count = (int)Math.Ceiling((double)length / BlockBitSize); var data = new byte[count]; Array.Copy(_data, 0, data, 0, count); var left = length % BlockBitSize; if (left != 0) { data[count - 1] &= BinaryFunctions.LowerMask(left); } return(new BitString(data, length)); }
static SpongeState Pi(SpongeState state) { var newState = new SpongeState(state.Size, state.Rate); var w = state.Size.W; for (var y = 0; y < 5; y++) { for (var x = 0; x < 5; x++) { for (var z = 0; z < w; z++) { newState[x, y, z] = state[BinaryFunctions.Mod(x + 3 * y, 5), x, z]; } } } state.SetBitString(newState.BitString); return(state); }
static SpongeState Theta(SpongeState state) { var w = state.Size.W; var c = new bool[5, w]; for (var x = 0; x < 5; x++) { for (var z = 0; z < w; z++) { c[x, z] = state.GetColumn(x, z).GetBits().Aggregate((lhs, rhs) => lhs ^ rhs); } } var d = new bool[5, w]; for (var x = 0; x < 5; x++) { for (var z = 0; z < w; z++) { d[x, z] = c[BinaryFunctions.Mod(x - 1, 5), z] ^ c[BinaryFunctions.Mod(x + 1, 5), BinaryFunctions.Mod(z - 1, w)]; } } for (var x = 0; x < 5; x++) { for (var z = 0; z < w; z++) { var bit = d[x, z]; for (var y = 0; y < 5; y++) { state[x, y, z] ^= bit; } } } return(state); }