Is there an SHA-1 in the FEZs?
The onewire device i’m tring to write to requires a 160bit key generated via an SHA-1 function. I have ported the function over from the PC based C# but it REALLY takes ages to complete.
As a test, here is a small part(but the longest to execute) of the algorithm. It takes 142 seconds to do one (partial hash as I condensed the code) hash. The chip requires a hash for each 8 bytes written…
Code:
public static void Main()
{
UInt32[] M = new UInt32[16];
Debug.EnableGCMessages(false);
long StartTicks = DateTime.Now.Ticks;
Debug.Print("Start:" + DateTime.Now.ToString());
for (byte t = 0; t <= 79; t++)
{
Debug.Print(t.ToString() + ":" + ((float)(DateTime.Now.Ticks-StartTicks) /10000000).ToString());
SequenceW(M, t);
}
Debug.Print("End:" + DateTime.Now.ToString());
}
private static UInt32 CircularShiftLeft(byte t, UInt32 W)
{
while (t-- > 0)
{
if (W >= 2147483648)//(Int32.Max/2)+1
{
W = (W << 1) + 1;
}
else
{
W = (W << 1);
}
}
return W;
}
private static UInt32 SequenceW(UInt32[] M, byte t)
{
if (t <= 15)
{
return M[t];
}
else if (t <= 79)
{
UInt32 Exp = SequenceW(M, (byte)(t - 3)) ^ SequenceW(M, (byte)(t - 8)) ^ SequenceW(M, (byte)(t - 14)) ^ SequenceW(M, (byte)(t - 16));
return CircularShiftLeft(1, Exp);
}
else
{
throw new Exception();
}
}
Output:
I looking at the SHA-1 alogritm on Wikipedia I see that I can flaten the recursive calling of SequenceW. That will probably speed things up a bit…
Thanks,
Errol
Will look at it now, thanks.
I rewrote it acording to the Wikipedia “formula”. It uses more ram but is way faster. Now it calculates a hash in 0.25 seconds. But I really do need even faster…
private static UInt32 CircularShiftLeft(byte t, UInt32 W)
{
while (t-- > 0)
{
if (W >= 2147483648)//(Int32.Max/2)+1
{
W = (W << 1) + 1;
}
else
{
W = (W << 1);
}
}
return W;
}
public static byte[] CalcMAC(UInt32[] M)
{
UInt32 A = 0X67452301;
UInt32 B = 0xefcdab89;
UInt32 C = 0x98badcfe;
UInt32 D = 0x10325476;
UInt32 E = 0xc3d2e1f0;
UInt32[] W = new UInt32[80];
UInt32 f = 0;
UInt32 k = 0;
UInt32 temp = 0;
global::System.Array.Copy(M, W, M.Length);
for (byte i = 16; i <= 79; i++)
{
W[i] = CircularShiftLeft(1,(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]));
}
for (byte i = 0; i <= 79; i++)
{
if (i <= 19)
{
f = (B & C) | ((~B) & D);
k = 0x5A827999;
}
else if (i <= 39)
{
f = B ^ C ^ D;
k=0x6ED9EBA1;
}
else if (i <= 59)
{
f = (B & C) | (B & D) | (C & D);
k=0x8F1BBCDC;
}
else if (i <= 79)
{
f = B ^ C ^ D;
k = 0xCA62C1D6;
}
temp = CircularShiftLeft(5, A) + f + E + k + W[i];
E = D;
D = C;
C = CircularShiftLeft(30, B);
B = A;
A = temp;
}
byte[] Return = new byte[20];
global::System.Array.Copy(BitConverter.GetBytes(E), 0, Return, 0, 4);
global::System.Array.Copy(BitConverter.GetBytes(D), 0, Return, 4, 4);
global::System.Array.Copy(BitConverter.GetBytes(C), 0, Return, 8, 4);
global::System.Array.Copy(BitConverter.GetBytes(B), 0, Return, 12, 4);
global::System.Array.Copy(BitConverter.GetBytes(A), 0, Return, 16, 4);
return Return;
}
I have some good news for you
Look here and you will see http://netmf.codeplex.com/documentation
[quote]Cryptographic Primitives OM
The current support is obsolete and non-standard. We plan to provide a new object model that is compatible with the traditional .NET and Compact Framework model for the following primitives in the System.Security.Cryptography namespace (non-Cng): SHA-256 and 512, HMAC-SHA-256 and 512, SHA-1 , HMAC-SHA-1, MD-5, AES, 3-DES, RSA, Diffie-Hellman, DSA, and X509 certificates. The native code for the primitives will be the one from the OpenSSL stack.[/quote]
Cool.
But only August?
Guess we can kludge forward with a managed class till then… ;D
Architect:
I looked at the SHA1 in that link of yours, and the variables are named differently but otherwise almost exactly what I did…
Only thing I don’t understand is that they pad the output with 1 byte(0x80) and they add the length to the output stream, which I don’t need nor want as I always only hash one block…
Thanks,
Errol
Will probably look into that, but i will first look into porting our bitbanged onewire overdrive source over from an msp430 to RPL…