diff --git a/Hashes.cs b/Hashes.cs
new file mode 100644
index 0000000..7dd9722
--- /dev/null
+++ b/Hashes.cs
@@ -0,0 +1,33 @@
+using System;
+using sharp.hashing.SHA3;
+namespace sharp.hashing
+{
+ public class Hashes
+ {
+
+ public static IHash createKeccak1600(Keccak1600.Keccak1600Parameters parameters){
+ return new Keccak1600(parameters);
+ }
+
+ public static IHash createSHA3_224()
+ {
+ return new Keccak1600(Keccak1600.SHA3_224);
+ }
+ public static IHash createSHA3_256()
+ {
+ return new Keccak1600(Keccak1600.SHA3_256);
+ }
+ public static IHash createSHA3_384()
+ {
+ return new Keccak1600(Keccak1600.SHA3_384);
+ }
+ public static IHash createSHA3_512()
+ {
+ return new Keccak1600(Keccak1600.SHA3_512);
+ }
+ public static IHash createKECCAK_256()
+ {
+ return new Keccak1600(Keccak1600.KECCAK_256);
+ }
+ }
+}
diff --git a/SHA3/Keccak.cs b/SHA3/Keccak.cs
index 8c7deae..dd15e1f 100644
--- a/SHA3/Keccak.cs
+++ b/SHA3/Keccak.cs
@@ -1,61 +1,199 @@
using System;
using System.Threading;
+using System.Runtime.Remoting.Metadata;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using sharp.extensions;
+using System.Resources;
+
namespace sharp.hashing.SHA3
{
- public class Keccak : HashBase
+ public class Keccak1600 : HashBase
{
- struct keccak_1600_std {
- public readonly int output_size;
- public readonly int r, c;
+ public static Keccak1600Parameters SHA3_224 = new Keccak1600Parameters(224, 1152, 448, 0x06, Padding.NIST);
+ public static Keccak1600Parameters SHA3_256 = new Keccak1600Parameters(256, 1088, 512, 0x06, Padding.NIST);
+ public static Keccak1600Parameters SHA3_384 = new Keccak1600Parameters(384, 832, 768, 0x06, Padding.NIST);
+ public static Keccak1600Parameters SHA3_512 = new Keccak1600Parameters(512, 576, 1024, 0x06, Padding.NIST);
- public keccak_1600_std(int output_size,int r,int c){
- this.output_size = output_size;
- this.r = r;
- this.c = c;
- }
- };
+ public static Keccak1600Parameters KECCAK_224 = new Keccak1600Parameters(224, 1152, 448, 0x01, Padding.NIST);
+ public static Keccak1600Parameters KECCAK_256 = new Keccak1600Parameters(256, 1088, 512, 0x01, Padding.NIST);
+ public static Keccak1600Parameters KECCAK_384 = new Keccak1600Parameters(384, 832, 768, 0x01, Padding.NIST);
+ public static Keccak1600Parameters KECCAK_512 = new Keccak1600Parameters(512, 576, 1024, 0x01, Padding.NIST);
- keccak_1600_std[] std1600 = {
- new keccak_1600_std(224,1152,448),
- new keccak_1600_std(256,1088,512),
- new keccak_1600_std(384,832,768),
- new keccak_1600_std(512,576,1024)
- };
-
- private int output_size,r, c;
+ Keccak1600Parameters parameters;
- public Keccak(int size)
+ public Keccak1600(Keccak1600Parameters p)
{
- foreach (keccak_1600_std std in std1600){
- if (std.output_size == size){
- this.r = std.r;
- this.c = std.c;
- this.output_size = std.output_size;
- }
- }
-
- if (this.output_size != size){
- throw new ArgumentException("No Standard Parameters for that Output Size defined!");
- }
-
-
+ this.parameters = p;
}
+ private int BlockByteSize { get { return this.parameters.r / 8; }}
+ private int BlockWordSize { get { return this.parameters.r / 64; }}
+
public override byte[] compute(byte[] data)
{
- byte[] result = null;
-
Monitor.Enter(this);
+ UInt64[] P = this.pad(data);
+ keccak1600_state S = new keccak1600_state();
+
+ int i, x, y;
+ int blockWordSize = BlockWordSize;
+ int PBlockCount = P.Length / BlockWordSize;
+
+// Console.WriteLine("Init:");
+// Console.WriteLine(S.ToString());
+
+ for (i = 0; i < PBlockCount;i++){
+ for (y = 0; y < 5; y++)
+ {
+ for (x = 0; (x < 5) && ((x + (5 * y)) < blockWordSize); x++)
+ {
+ S.xor(x,y, P[ (blockWordSize * i) + (x+(5*y)) ]);
+ }
+ }
+ Keccak_f(S);
+ }
+
+// Console.WriteLine("Final State:");
+// Console.WriteLine(S.ToString());
+
+
+ byte[] Z = new byte[ this.parameters.outsize / 8];
+ int outLanes = this.parameters.outsize / 64;
+
+ for (i = 0; i < PBlockCount;i++){
+ for (y = 0; y < 5; y++)
+ {
+ for (x = 0; (x < 5) && ((x + (5 * y)) < outLanes); x++)
+ {
+ Array.Copy(S[x, y].GetBytes(), 0, Z, 8 * (x + (5 * y)), 8);
+ }
+ }
+ }
Monitor.Exit(this);
- return result;
+ return Z;
}
+ public UInt64[] pad(byte[] M){
+ switch (this.parameters.padding){
+ case Padding.KECCAK:
+ return padKeccak(M);
+ case Padding.NIST:
+ return pad1asterisk01(M);
+ default:
+ return null;
+ }
+ }
+ public UInt64[] padKeccak(byte[] M)
+ {
+ int lenPadded = (M.Length + 3) + BlockByteSize - ((M.Length + 3) % BlockByteSize);
+ byte[] P = new byte[lenPadded];
+
+ Array.Copy(M,P,M.Length);
+
+ P[M.Length ] = 0x01;
+ P[M.Length + 1] = this.parameters.d;
+ P[M.Length + 2] = (byte)(this.parameters.r / 8);
+ P[M.Length + 3] = 0x01;
+
+ for (int n = M.Length + 4 ; n < lenPadded ; n++){
+ P[n] = 0x00;
+ }
+
+// Console.WriteLine("Padded:\n{0}",HexString.toString(P,8,2));
+
+ UInt64 []
+ P64 = new UInt64[P.Length / 8];
+ for (int n = 0; n
+
+
+
+ {97CA3CA9-98B3-4492-B072-D7A5995B68E9}
+ sharp.extensions
+
+
\ No newline at end of file