Working BETA

master
Harald Wolff 2017-10-17 21:44:25 +02:00
parent 7193cd0df9
commit 191e70a563
3 changed files with 291 additions and 39 deletions

33
Hashes.cs 100644
View File

@ -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);
}
}
}

View File

@ -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<P64.Length; n++){
P64[n] = BitConverter.ToUInt64(P, n* 8);
}
return P64;
}
public UInt64[] pad1asterisk01(byte[] M){
int lenPadded = (M.Length + 2) + BlockByteSize - ((M.Length + 2) % BlockByteSize);
byte[] P = new byte[lenPadded];
Array.Copy(M,P,M.Length);
P[M.Length] = this.parameters.d;
for (int n = M.Length + 1; n<lenPadded;n++){
P[n] = 0x00;
}
P[lenPadded - 1] ^= 0x80;
// Console.WriteLine("Padded:\n{0}",HexString.toString(P,8,2));
UInt64 [] P64 = new UInt64[P.Length / 8];
for (int n = 0; n < P64.Length; n++){
P64[n] = BitConverter.ToUInt64(P, n * 8);
}
return P64;
}
private keccak1600_state Keccak_f(keccak1600_state A){
// Console.WriteLine("Before Round 0:");
// Console.WriteLine(A.ToString());
for (int n = 0; n < 24;n++){
// Console.WriteLine("Round {0}",n);
Round(A, this.RC[n]);
}
return A;
}
private keccak1600_state Round(keccak1600_state A,UInt64 RC){
keccak1600_state B = new keccak1600_state();
UInt64[] C = new UInt64[5],
D = new UInt64[5];
int x, y;
for (x = 0; x < 5;x++){
C[x] = A[x, 0] ^ A[x, 1] ^ A[x, 2] ^ A[x, 3] ^ A[x, 4];
}
for (x = 0; x < 5;x++){
D[x] = C[(((x - 1) % 5) + 5) % 5] ^ C[(x + 1) % 5].RotateLeft(1);
}
for (y = 0; y < 5;y++){
for (x = 0; x < 5;x++){
A[x, y] ^= D[x];
}
}
// Console.WriteLine("After Theta:");
// Console.WriteLine(A.toCheckString());
for (y = 0; y < 5;y++){
for (x = 0; x < 5;x++){
B[y, (2 * x) + (3 * y)] = A[x, y].RotateLeft(this.RO[y][x]);
}
}
// Console.WriteLine("After Rho:");
// Console.WriteLine(B.toCheckString());
for (y = 0; y < 5;y++){
for (x = 0; x < 5;x++){
A[x, y] = B[x, y] ^ ( (~B[x+1,y]) & B[x+2,y] );
}
}
A[0, 0] ^= RC;
return A;
}
@ -88,12 +226,86 @@ namespace sharp.hashing.SHA3
// RO[y][x]
private int[][] RO = {
new int[]{03,10,43,25,39},
new int[]{36,44,06,55,20},
new int[]{00,01,62,28,27},
new int[]{18,02,61,56,14},
new int[]{41,45,15,21,08}
new int[]{36,44,06,55,20},
new int[]{03,10,43,25,39},
new int[]{41,45,15,21,08},
new int[]{18,02,61,56,14}
};
class keccak1600_state {
public UInt64[] lanes;
public keccak1600_state(){
this.lanes = new UInt64[25];
for (int n = 0; n < this.lanes.Length;n++){
this.lanes[n] = 0;
}
}
private int index(int x,int y){
return (x % 5) + ((y % 5) * 5);
}
public void xor(int x,int y,UInt64 v){
this.lanes[index(x, y)] ^= v;
}
public UInt64 this[int x,int y]{
get { return this.lanes[index(x, y)]; }
set { this.lanes[index(x, y)] = value; }
}
public byte[] getBytes(){
byte[] t = new byte[ this.lanes.Length * 8 ];
for (int n = 0; n < this.lanes.Length; n++){
Array.Copy(this.lanes[n].GetBytes(),0,t,(n*8),8);
}
return t;
}
public override string ToString()
{
int x, y;
StringBuilder sb = new StringBuilder();
sb.AppendLine("[keccak1600_state]");
for (y = 0; y < 5;y++){
for (x = 0; x < 5;x++){
sb.AppendFormat("{0} ",HexString.toString(this[x,y].GetBytes()));
}
sb.AppendLine();
}
return sb.ToString();
}
public string toCheckString(){
return HexString.toString(getBytes(), 1, 16);
}
}
public enum Padding { NIST, KECCAK }
public struct Keccak1600Parameters {
public int outsize;
public int r, c;
public byte d;
public Padding padding;
public Keccak1600Parameters(int os,int r,int c,byte d,Padding padding){
this.outsize = os;
this.r = r;
this.c = c;
this.d = d;
this.padding = padding;
}
}
}
}

View File

@ -34,9 +34,16 @@
<Compile Include="IHash.cs" />
<Compile Include="HashBase.cs" />
<Compile Include="SHA3\Keccak.cs" />
<Compile Include="Hashes.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="SHA3\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
<Name>sharp.extensions</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>