Skip to content

Commit

Permalink
+ unit tests (using https://gchq.github.io/CyberChef as reference)
Browse files Browse the repository at this point in the history
# algorithm fixes
  • Loading branch information
Hawkynt committed May 25, 2024
1 parent 8ba92bd commit cf948d1
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 159 deletions.
33 changes: 5 additions & 28 deletions Corlib.Extensions/System/Security/Cryptography/Adler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,36 +102,13 @@ void Reset() {

void Core(byte[] array, int index, int count) {
for (count += index; index < count; ++index) {
state = (state + array[index]) % PRIME;
sum = (sum + state) % PRIME;
state = (uint)(((ulong)state + array[index]) % PRIME);
sum = (uint)(((ulong)sum + state) % PRIME);
}
}

byte[] Final() => new[] { (byte)(sum >> 24), (byte)(sum >> 16), (byte)(sum >> 8), (byte)sum, (byte)(state >> 24), (byte)(state >> 16), (byte)(state >> 8), (byte)state };
}
case 128: {
const ulong PRIME = 18446744073709551557;
ulong state = default, sum = default;

this._reset = Reset;
this._core = Core;
this._final = Final;
break;

void Reset() {
state = 1;
sum = 0;
}

void Core(byte[] array, int index, int count) {
for (count += index; index < count; ++index) {
state = (state + array[index]) % PRIME;
sum = (sum + state) % PRIME;
}
}

byte[] Final() => new[] { (byte)(sum >> 56), (byte)(sum >> 48), (byte)(sum >> 40), (byte)(sum >> 32), (byte)(sum >> 24), (byte)(sum >> 16), (byte)(sum >> 8), (byte)sum, (byte)(state >> 56), (byte)(state >> 48), (byte)(state >> 40), (byte)(state >> 32), (byte)(state >> 24), (byte)(state >> 16), (byte)(state >> 8), (byte)state };
}
default:
throw new NotSupportedException();
}
Expand Down Expand Up @@ -164,9 +141,9 @@ public byte[] IV {
set => throw new NotSupportedException();
}

public static int MinOutputBits => 16;
public static int MaxOutputBits => 128;
public static int[] SupportedOutputBits => new[] { 16, 32, 64, 128 };
public static int MinOutputBits => SupportedOutputBits[0];
public static int MaxOutputBits => SupportedOutputBits[^1];
public static int[] SupportedOutputBits => new[] { 16, 32, 64 };

public static bool SupportsIV => false;
public static int MinIVBits => 0;
Expand Down
155 changes: 86 additions & 69 deletions Corlib.Extensions/System/Security/Cryptography/Fletcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ along with Hawkynt's .NET Framework extensions.
*/
#endregion

using System.Collections.Generic;

namespace System.Security.Cryptography;

public sealed class Fletcher : HashAlgorithm, IAdvancedHashAlgorithm {
Expand All @@ -40,33 +42,8 @@ public Fletcher(int outputBits) {

public override void Initialize() {
switch (this.OutputBits) {
case 4: {
byte state = 0;
byte sum = 0;

this._reset = Reset;
this._core = Core;
this._final = Final;
break;

void Reset() {
state = 0;
sum = 0;
}

void Core(byte[] array, int index, int count) {
for (count += index; index < count; ++index) {
state = (byte)((state + array[index]) % 3);
sum = (byte)((sum + state) % 3);
}
}

byte[] Final() => new[] { (byte)(sum << 2 | state) };

}
case 8: {
byte state = 0;
byte sum = 0;
byte state = default, sum = default;

this._reset = Reset;
this._core = Core;
Expand All @@ -86,11 +63,9 @@ void Core(byte[] array, int index, int count) {
}

byte[] Final() => new[] { (byte)(sum << 4 | state) };

}
case 16: {
byte state = 0;
byte sum = 0;
byte state = default, sum = default;

this._reset = Reset;
this._core = Core;
Expand All @@ -109,83 +84,125 @@ void Core(byte[] array, int index, int count) {
}
}

byte[] Final() => new[] { state, sum };

byte[] Final() => new[] { sum, state };
}
case 32: {
ushort state = 0;
ushort sum = 0;
ushort state = default, sum = default;
List<byte> carry = new(2);

this._reset = Reset;
this._core = Core;
this._final = Final;
break;

ushort ConvertFrom(byte b0, byte b1) => (ushort)((b0) | (b1 << 8));

void Round(ushort value) {
state = (ushort)(((uint)state + value) % ushort.MaxValue);
sum = (ushort)(((uint)sum + state) % ushort.MaxValue);
}

void Reset() {
state = 0;
sum = 0;
carry.Clear();
}

void Core(byte[] array, int index, int count) {
for (count += index; index < count; ++index) {
state = (ushort)((state + array[index]) % ushort.MaxValue);
sum = (ushort)((sum + state) % ushort.MaxValue);
var end = index + count;

while (carry.Count > 0) {
if (index >= end)
return;

carry.Add(array[index++]);
if (carry.Count != 2)
continue;

Round(ConvertFrom(carry[0], carry[1]));
carry.Clear();
break;
}

while (index + 1 < end)
Round(ConvertFrom(array[index++], array[index++]));

while (index < end)
carry.Add(array[index++]);
}

byte[] Final() => BitConverter.GetBytes((uint)sum << 16 | state);
byte[] Final() {
if (carry.Count == 1)
Round(ConvertFrom(carry[0], 0));

return new[] {
(byte)(sum >> 8), (byte)sum,
(byte)(state >> 8), (byte)state
};
}
}
case 64: {
uint state = 0;
uint sum = 0;
uint state = default, sum = default;
List <byte> carry = new(4);

this._reset = Reset;
this._core = Core;
this._final = Final;
break;

uint ConvertFrom(byte b0, byte b1, byte b2, byte b3) => (uint)((b0) | (b1 << 8) | (b2 << 16) | (b3 << 24));

void Round(uint value) {
state = (uint)(((ulong)state + value) % uint.MaxValue);
sum = (uint)(((ulong)sum + state) % uint.MaxValue);
}

void Reset() {
state = 0;
sum = 0;
carry.Clear();
}

void Core(byte[] array, int index, int count) {
for (count += index; index < count; ++index) {
state = (state + array[index]) % uint.MaxValue;
sum = (sum + state) % uint.MaxValue;
}
}
var end = index + count;

byte[] Final() => BitConverter.GetBytes((ulong)sum << 32 | state);
while (carry.Count > 0) {
if (index >= end)
return;

}
case 128: {
ulong state = 0;
ulong sum = 0;
carry.Add(array[index++]);
if (carry.Count != 4)
continue;

this._reset = Reset;
this._core = Core;
this._final = Final;
break;
Round(ConvertFrom(carry[0], carry[1], carry[2], carry[3]));
carry.Clear();
break;
}

void Reset() {
state = 0;
sum = 0;
}
while (index + 3 < end)
Round(ConvertFrom(array[index++], array[index++], array[index++], array[index++]));

void Core(byte[] array, int index, int count) {
for (count += index; index < count; ++index) {
state = (state + array[index]) % ulong.MaxValue;
sum = (sum + state) % ulong.MaxValue;
}
while (index < end)
carry.Add(array[index++]);
}

byte[] Final() {
var result = new byte[16];
Array.Copy(BitConverter.GetBytes(state),0,result,0,8);
Array.Copy(BitConverter.GetBytes(sum), 0, result, 8, 8);
return result;
switch (carry.Count) {
case 1:
Round(ConvertFrom(carry[0], 0, 0, 0));
break;
case 2:
Round(ConvertFrom(carry[0], carry[1], 0, 0));
break;
case 3:
Round(ConvertFrom(carry[0], carry[1], carry[2], 0));
break;
}

return new[] {
(byte)(sum >> 24), (byte)(sum >> 16), (byte)(sum >> 8), (byte)sum,
(byte)(state >> 24), (byte)(state >> 16), (byte)(state >> 8), (byte)state
};
}
}
default:
Expand Down Expand Up @@ -220,9 +237,9 @@ public byte[] IV {
set => throw new NotSupportedException();
}

public static int MinOutputBits => 4;
public static int MaxOutputBits => 128;
public static int[] SupportedOutputBits => new[]{ 4, 8, 16, 32, 64, 128 };
public static int MinOutputBits => SupportedOutputBits[0];
public static int MaxOutputBits => SupportedOutputBits[^1];
public static int[] SupportedOutputBits => new[]{ 8, 16, 32, 64 };

public static bool SupportsIV => false;
public static int MinIVBits => 0;
Expand Down
12 changes: 3 additions & 9 deletions Corlib.Extensions/System/Security/Cryptography/JavaHash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,12 @@ public byte[] IV {
set => throw new NotImplementedException();
}

public static int MinOutputBits => 32;

public static int MaxOutputBits => 64;

public static int[] SupportedOutputBits => new[] { MinOutputBits, MaxOutputBits };

public static int MinOutputBits => SupportedOutputBits[0];
public static int MaxOutputBits => SupportedOutputBits[^1];
public static int[] SupportedOutputBits => new[] { 32, 64 };
public static bool SupportsIV => false;

public static int MinIVBits => 0;

public static int MaxIVBits => MinIVBits;

public static int[] SupportedIVBits => Utilities.Array.Empty<int>();

#endregion
Expand Down
Loading

0 comments on commit cf948d1

Please sign in to comment.