473,809 Members | 2,805 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

SHA-1 algorithm help

11 New Member
Hi, I'm trying to make the sha-1 algorithm based on the wikipedia pseudocode.
For the 'The quick brown fox jumps over the lazy dog" string I should get
2fd4e1c6 7a2d28fc ed849ee1 bb76e739 1b93eb12 but what I get is
1D8B8841 A544939A 98BB54FE 4C325476 C44AE1F0
(after I convert from dec to hex)
I have no idea what the problem is :(
Thx in advance
Expand|Select|Wrap|Line Numbers
  1.  
  2. #define ROTL ( a , b ) ( ( ( b ) << a ) | ( ( b ) >> ( 32 - a ) ) )
  3.  
  4. void SHA1(char *in, long nr, char *sha)
  5. {
  6.     long i, j, w[80];
  7.     unsigned long h0 = 0x67452301;
  8.     unsigned long h1 = 0xEFCDAB89;
  9.     unsigned long h2 = 0x98BADCFE;
  10.     unsigned long h3 = 0x10325476;
  11.     unsigned long h4 = 0xC3D2E1F0;
  12.     unsigned long a, b, c, d, e, f, k, temp;
  13.     unsigned long length = nr*32;
  14.     in[nr++] = (char)128;//1 7x0
  15.     while(nr%64 != 60)in[nr++] = 0;//8x0
  16.     *((long*)(in+nr)) = length;
  17.     nr += 4;
  18.     for(i=0;i<nr;i+=64)
  19.     {
  20.         for(j=i;j<i+64;j+=4)w[(i-j)/4] = *((long*)in+j);// break chunk into sixteen 32-bit big-endian words w[i], 0 <= i <= 15
  21.         for(i=16;i<80;i++)w[i] = ROTL((w[i-3]^w[i-8]^w[i-14]^w[i-16]), 1);
  22.         a = h0;
  23.         b = h1;
  24.         c = h2;
  25.         d = h3;
  26.         e = h4;
  27.         for(i=0;i<80;i++)
  28.         {
  29.             if(0<=i&&i<20)
  30.             {
  31.                 f = (b & c) | ((! b) & d);
  32.                 k = 0x5A827999;
  33.             }
  34.             else if(i>=20&&i<40)
  35.             {
  36.                 f = b ^ c ^ d;
  37.                 k = 0x6ED9EBA1;
  38.             }
  39.             else if(i>=40&&i<60)
  40.             {
  41.                 f = (b & c) | (b & d) | (c & d);
  42.                 k = 0x8F1BBCDC;
  43.             }
  44.             else if(i>=60&&i<80)
  45.             {
  46.                 f = b ^ c ^ d;
  47.                 k = 0xCA62C1D6;
  48.             }
  49.             temp = ROTL(a, 5) + f + e + k + w[i];
  50.             e = d;
  51.             d = c;
  52.             c = ROTL(b, 30);
  53.             b = a;
  54.             a = temp;
  55.         }
  56.         h0 = h0 + a;
  57.         h1 = h1 + b;
  58.         h2 = h2 + c;
  59.         h3 = h3 + d;
  60.         h4 = h4 + e;
  61.     }
  62.     sprintf_s(sha, 512, "%u %u %u %u %u", h0, h1, h2, h3, h4);
  63. }
Aug 13 '08 #1
12 4213
gpraghuram
1,275 Recognized Expert Top Contributor
I tired compiling this in Cygwin using gcc and i am getting the error for ROTL sayings its not a function...

Raghu
Aug 14 '08 #2
gulyan
11 New Member
thx for the reply

Expand|Select|Wrap|Line Numbers
  1. unsigned long ROTL(unsigned long a, unsigned long b)
  2. {
  3.     return (a<<b)|(a>>(32-b));
  4. }
should do the same thing as
Expand|Select|Wrap|Line Numbers
  1. #define ROTL ( a , b ) ( ( ( b ) << a ) | ( ( b ) >> ( 32 - a ) ) )
but my problems are not compiler errors :(
btw.. I'm using vc++
Aug 14 '08 #3
gpraghuram
1,275 Recognized Expert Top Contributor
Since the endianess is involved in this you will get a different answer in the Intel machine...
Do you know which compiler or processor the example has used for this?

raghu
Aug 14 '08 #4
Banfa
9,065 Recognized Expert Moderator Expert
Expand|Select|Wrap|Line Numbers
  1. #define ROTL ( a , b ) ( ( ( b ) << a ) | ( ( b ) >> ( 32 - a ) ) )
This syntax is not correct it should be

Expand|Select|Wrap|Line Numbers
  1. #define ROTL( a , b ) ( ( ( b ) << a ) | ( ( b ) >> ( 32 - a ) ) )
Notice the lack of space following ROTL, other wise ROTL becomes a normal macro defined as

"( a , b ) ( ( ( b ) << a ) | ( ( b ) >> ( 32 - a ) )"

not a function like macro taking 2 parameters.
Aug 14 '08 #5
Banfa
9,065 Recognized Expert Moderator Expert
Hi, I'm trying to make the sha-1 algorithm based on the wikipedia pseudocode.
I Did this myself a couple of months ago and it works fine so there is no problem with the pseudo code you are using as a base.

Looking at you code the actual data manipulation in the loop looks fine, what concerns me is your buffer manipulation before the loop. In fact your inner most loop is almost exactly the same as mine (not withstanding variable name differences) but the buffer manipulation you do in 3 or four lines outside the loops and 2 lines inside the outer most loop is 30 lines of code in my version.

Of course it may well be able to do it in less lines of code, I was memory constrained because my version had to work on a low memory micro-controller target.

Anyway here are some specific issues

Expand|Select|Wrap|Line Numbers
  1. void SHA1(char *in, long nr, char *sha)
  2. {
  3. <snip>
  4.  
  5. // This is not the bit length of your data, you have passed a char * and 
  6. // so nr is presumably the number of chars.  The bit length of your data 
  7. // is then nr*8
  8.     unsigned long length = nr*32;
  9.  
  10. // These next 2 lines are extremely dangerous, they assume that the caller 
  11. // has called the function with a buffer that is long enough to extend the data 
  12. // to the next multiple of 512 bites (or 64 bytes). in should have type const 
  13. // char * and you should have your own work buffer to copy the data to.
  14.     in[nr++] = (char)128;//1 7x0
  15.     while(nr%64 != 60)in[nr++] = 0;//8x0
  16.  
  17. // Dangerous and will only work on a big endian platform, non portable code
  18.     *((long*)(in+nr)) = length;
  19.  
  20.     nr += 4;
  21.     for(i=0;i<nr;i+=64)
  22.     {
  23. // This is wrong and a major difference between you and my impementation, 
  24. // you have converted each byte to a 32 bit word, I pack the bytes into the
  25. // 32 bit words, where as your first word in the buffer has the value 
  26. // 0x00000054 in my implementation it has the value 0x54686520
  27. // You need to pack the bytes into 32 bit words
  28.         for(j=i;j<i+64;j+=4)w[(i-j)/4] = *((long*)in+j);// break chunk into sixteen 32-bit big-endian words w[i], 0 <= i <= 15
  29.  
  30. <snip>
  31.     }
  32. }
Aug 14 '08 #6
gulyan
11 New Member
thx for the reply :D
I've made changes to the code and also found that i was using "i" inside the for wich used it as an index....

I'm a little confuze about big and little endians

after the firs run through the loop, w[0] contains " ehT" not "The" .. so i gues this is a little endian.

Expand|Select|Wrap|Line Numbers
  1. for(j=i;j<i+64;j+=4)w[(j-i)/4] = *((long*)(buff+j));
How can I make a 32-bit big endian using 4 bytes? :-??


the code now looks like this

Expand|Select|Wrap|Line Numbers
  1. #define ROTL( a , b ) ( ( ( b ) << a ) | ( ( b ) >> ( 32 - a ) ) )
  2.  
  3. void SHA1(const char *in, long length, char *sha)
  4. {
  5.     char *buff = new char[length + 64];
  6.     int i, j;
  7.     for(i = 0; i < length; i++)buff[i] = in[i];//copy to buffer
  8.     long bitLength = length * sizeof(char);//size in bits
  9.     long w[80], a, b, c, d, e, f, k, temp;
  10.     unsigned long h0 = 0x67452301;
  11.     unsigned long h1 = 0xEFCDAB89;
  12.     unsigned long h2 = 0x98BADCFE;
  13.     unsigned long h3 = 0x10325476;
  14.     unsigned long h4 = 0xC3D2E1F0;
  15.     buff[length++] = (char)128;//1 7x0
  16.     while(length%64 != 60)buff[length++] = 0;//8x0
  17.     *((long*)(in+length)) = bitLength;
  18.     length+=4;
  19.     for(i=0;i<length;i+=64)
  20.     {
  21.         for(j=i;j<i+64;j+=4)w[(j-i)/4] = *((long*)(buff+j));
  22.         for(j=16;j<80;j++)w[j] = ROTL((w[j-3]^w[j-8]^w[j-14]^w[j-16]), 1);
  23.         if(i==0)cout<<w[0]<<endl;
  24.         a = h0;
  25.         b = h1;
  26.         c = h2;
  27.         d = h3;
  28.         e = h4;
  29.         for(j=0;j<80;j++)
  30.         {
  31.             if(0<=j&&j<20)
  32.             {
  33.                 f = (b & c) | ((! b) & d);
  34.                 k = 0x5A827999;
  35.             }
  36.             else if(j>=20&&j<40)
  37.             {
  38.                 f = b ^ c ^ d;
  39.                 k = 0x6ED9EBA1;
  40.             }
  41.             else if(j>=40&&j<60)
  42.             {
  43.                 f = (b & c) | (b & d) | (c & d);
  44.                 k = 0x8F1BBCDC;
  45.             }
  46.             else if(j>=60&&j<80)
  47.             {
  48.                 f = b ^ c ^ d;
  49.                 k = 0xCA62C1D6;
  50.             }
  51.             temp = ROTL(a, 5) + f + e + k + w[j];
  52.             e = d;
  53.             d = c;
  54.             c = ROTL(b, 30);
  55.             b = a;
  56.             a = temp;
  57.         }
  58.         h0 = h0 + a;
  59.         h1 = h1 + b;
  60.         h2 = h2 + c;
  61.         h3 = h3 + d;
  62.         h4 = h4 + e;
  63.     }
  64.     sprintf_s(sha, 512, "%u %u %u %u %u", h0, h1, h2, h3, h4);
  65. }
  66.  
Aug 14 '08 #7
Banfa
9,065 Recognized Expert Moderator Expert
Expand|Select|Wrap|Line Numbers
  1. for(j=i;j<i+64;j+=4)w[(j-i)/4] = *((long*)(buff+j));
How can I make a 32-bit big endian using 4 bytes? :-??
Do not use pointer casts, it doesn't work on little endian machines (I guess you are using a PC which is little endian).

Use the bitwise operators in this case | (or) and << (shift left) to locate each byte in the specific place you want it to hold in the 32 bit word. For instance the first byte should be the most significant byte of the word so

Expand|Select|Wrap|Line Numbers
  1. unsigned long word;
  2. unsigned char byte;
  3.  
  4. word = 0;
  5. word |= byte << 24;
  6.  
By using arithmetic operators rather than casts you ensure you code is portable because the operation with have the same result on all platforms but the cast (as you have seen) has different results on big and little endian platforms.


P.S. You now have a memory leak in you function because you do not delete buff.
Aug 14 '08 #8
Banfa
9,065 Recognized Expert Moderator Expert
long bitLength = length * sizeof(char);//size in bits
sizeof returns the size of a type (or variable) in bytes not bits. Since a char is always 1 byte sizeof(char) is guaranteed to be 1.

You could use the symbol CHAR_BITS defined in limits.h (or climits if your are using C++).

However I think the implementation as you have it will only work on machines with 8 bit bytes. This is because a machine with not 8 bit bytes (7 for example) would be unlike to have a 32 bit unsigned long and much more likely to have a 28bit unsigned long.
Aug 14 '08 #9
gulyan
11 New Member
thx again, I've made tha changes in the program

Expand|Select|Wrap|Line Numbers
  1. long bitLength = length * 8;
and
Expand|Select|Wrap|Line Numbers
  1. for(j=i;j<i+64;j+=4)
  2.         {
  3.             w[(j-i)/4] = buff[j] << 24;
  4.             w[(j-i)/4] |= buff[j+1] << 16;
  5.             w[(j-i)/4] |= buff[j+2] << 8;
  6.             w[(j-i)/4] |= buff[j+3];
  7.         }
  8.  
After the first run through the loop, w[0] is 1416127776 wich is 01010100 01101000 01100101 00100000 in binary, meaning 84, 104, 101, 32.
Using the ASCII table it means "The " so now it works fine but the final result is still not the right one :( i get this (afeter i convert to hex) :
12415579 DA38E2A2 98BADDEE 88325476 BD725B not this:
2fd4e1c6 7a2d28fc ed849ee1 bb76e739 1b93eb12

this is what I have so far:
Expand|Select|Wrap|Line Numbers
  1. #define ROTL( a , b ) ( ( ( b ) << a ) | ( ( b ) >> ( 32 - a ) ) )
  2.  
  3. void SHA1(const char *in, long length, char *sha)
  4. {
  5.     char *buff = new char[length + 64];
  6.     int i, j;
  7.     for(i = 0; i < length; i++)buff[i] = in[i];//copy to buffer
  8.     long bitLength = length * 8;//size in bits
  9.     long w[80], a, b, c, d, e, f, k, temp;
  10.     unsigned long h0 = 0x67452301;
  11.     unsigned long h1 = 0xEFCDAB89;
  12.     unsigned long h2 = 0x98BADCFE;
  13.     unsigned long h3 = 0x10325476;
  14.     unsigned long h4 = 0xC3D2E1F0;
  15.     buff[length++] = (char)128;//1 7x0
  16.     while(length%64 != 60)buff[length++] = 0;//8x0
  17.     cout<<bitLength<<endl;
  18.     buff[length] = char((bitLength >> 24));
  19.     buff[length+1] = char(255&(bitLength >> 16));
  20.     buff[length+2] = char(255&(bitLength >> 8));
  21.     buff[length+3] = char(255&(bitLength));
  22.     length+=4;
  23.     for(i=0;i<length;i+=64)
  24.     {
  25.         for(j=i;j<i+64;j+=4)
  26.         {
  27.             w[(j-i)/4] = buff[j] << 24;
  28.             w[(j-i)/4] |= buff[j+1] << 16;
  29.             w[(j-i)/4] |= buff[j+2] << 8;
  30.             w[(j-i)/4] |= buff[j+3];
  31.         }
  32.         if(i==0)cout<<w[0]<<endl;
  33.         for(j=16;j<80;j++)w[j] = ROTL((w[j-3]^w[j-8]^w[j-14]^w[j-16]), 1);
  34.         a = h0;
  35.         b = h1;
  36.         c = h2;
  37.         d = h3;
  38.         e = h4;
  39.         for(j=0;j<80;j++)
  40.         {
  41.             if(0<=j&&j<20)
  42.             {
  43.                 f = (b & c) | ((! b) & d);
  44.                 k = 0x5A827999;
  45.             }
  46.             else if(j>=20&&j<40)
  47.             {
  48.                 f = b ^ c ^ d;
  49.                 k = 0x6ED9EBA1;
  50.             }
  51.             else if(j>=40&&j<60)
  52.             {
  53.                 f = (b & c) | (b & d) | (c & d);
  54.                 k = 0x8F1BBCDC;
  55.             }
  56.             else if(j>=60&&j<80)
  57.             {
  58.                 f = b ^ c ^ d;
  59.                 k = 0xCA62C1D6;
  60.             }
  61.             temp = ROTL(a, 5) + f + e + k + w[j];
  62.             e = d;
  63.             d = c;
  64.             c = ROTL(b, 30);
  65.             b = a;
  66.             a = temp;
  67.         }
  68.         h0 = h0 + a;
  69.         h1 = h1 + b;
  70.         h2 = h2 + c;
  71.         h3 = h3 + d;
  72.         h4 = h4 + e;
  73.     }
  74.     delete [] buff;
  75.     sprintf_s(sha, 512, "%u %u %u %u %u", h0, h1, h2, h3, h4);
  76. }
  77.  
Aug 14 '08 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

28
3712
by: Paul Rubin | last post by:
http://www.nightsong.com/phr/python/sharandom.c This is intended to be less predicable/have fewer correlations than the default Mersenne Twister or Wichmann-Hill generators. Comments are appreciated.
4
1948
by: Florian Lindner | last post by:
Hello, I try to compute SHA hashes for different files: for root, dirs, files in os.walk(sys.argv): for file in files: path = os.path.join(root, file) print path f = open(path) sha = sha.new(f.read())
4
6778
by: Ravi Singh (UCSD) | last post by:
Hello all I am trying to compare the SHA 256 algorithm as implemented by Christophe Devine and on using the .NET "SHA256Managed" but they do not give me similar hashes. Here is the Christophes implementation .
2
8492
by: Augusto Rocha | last post by:
I have stored a password in a data base using the function HashPasswordForStoringInConfigFile, with the SHA method. How do I decrypt it? Augusto
0
3094
by: rene.rugerio | last post by:
I am developing an application using dot net fw 2.0 I am using the signedcms for the digital signature. I certainly do not understand why this generates long string as a result of the signing, because it is supposed to generate a string after SHA-1 hashing. Is this implemented as a part of the method for signedcms? I am asking because, lets say you want to sign the word "google" the output is 150 based 64 characters. If you wanted to sign...
3
4317
by: mirandacascade | last post by:
Operating system: Win XP Vsn of Python: 2.4 Situation is this: Required to calcluate a message digest. The process for calcluating the digest must use an SHA-256 algorithm. Questions: 1) Is it correct that the sha module comes with python 2.4? 2) Is it correct that the sha module that ships with python 2.4 does NOT have the SHA-256 capability as part of the module?
1
1931
by: David Rees | last post by:
The Forms-encryption module includes a handy (if long-winded) hash function: FormsAuthentication.HashPasswordForStoringInConfigFile It only supports MD5 and SHA1, but ages ago MD5 was torn apart, and more recently (http://it.slashdot.org/article.pl?sid=07/01/20/1936257&threshold=2) they've broken SHA-1, so obviously we're going to need something a little stronger. I was thinking SHA-256, but that's too similar to SHA-1. Fortunately I...
1
6516
Atli
by: Atli | last post by:
Hi. I've been looking for a function similar to MySQL's sha() function in Postgre and I can't seem to find anything. The reason is that I have a system that is written for MySQL and I've been asked to make it compatible with Postgre. Thanks.
0
2607
by: Antony Clements | last post by:
I can't find one anywhere on the net and my skills are lacking in that particular area of coding. The closest I can find is a truncated version of SHA-384 that someone is trying to pass off as SHA-1. The official SHA-1 standard has an output string of 160 bits, or 20 characters, the module that I have has an output string of 320 bits or 40 characters. Is anyone here a classy enough coder to write a properly working module of SHA-1 that...
18
2435
by: Tomás Ó hÉilidhe | last post by:
(SHA-1 is a cryptographic hash function. For info on what SHA-1 is: http://en.wikipedia.org/wiki/SHA-1) I'm writing fullportable C89 code that needs to make use of the SHA-1 algorithm. Does anyone know if there's been a fully-portable C89 implementation of the SHA-1 algorithm? If not, could someone please point me to a very good implementation of the algorithm, an implementation which is very portable (perhaps portable to machines...
0
9722
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10643
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10391
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10121
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6881
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5690
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3862
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3015
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.