X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fsha1.C;fp=cinelerra-5.1%2Fcinelerra%2Fsha1.C;h=ad5becf899edc142b129c13658b6741a0a9a6be8;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/sha1.C b/cinelerra-5.1/cinelerra/sha1.C new file mode 100644 index 00000000..ad5becf8 --- /dev/null +++ b/cinelerra-5.1/cinelerra/sha1.C @@ -0,0 +1,119 @@ +// see copyright notice in sha1.h +#include "sha1.h" + +void SHA1::addBytes(const uint8_t* input, size_t length) +{ + while (length--) { + m_buffer[m_cursor++] = *input++; + ++m_totalBytes; + if (m_cursor == 64) processBlock(); + } +} + +void SHA1::computeHash(uint8_t *digest) +{ + finalize(); + memset(digest, 0, 20); + for (size_t i = 0; i < 5; ++i) { + // Treat hashValue as a big-endian value. + uint32_t hashValue = m_hash[i]; + for (int j = 0; j < 4; ++j) { + digest[4*i + (3-j)] = hashValue & 0xFF; + hashValue >>= 8; + } + } + + reset(); +} + +void SHA1::finalize() +{ + m_buffer[m_cursor++] = 0x80; + if (m_cursor > 56) { + while (m_cursor < 64) m_buffer[m_cursor++] = 0x00; + processBlock(); + } + + for (size_t i = m_cursor; i < 56; ++i) + m_buffer[i] = 0x00; + + uint64_t bits = m_totalBytes*8; + for (int i = 0; i < 8; ++i) { + m_buffer[56 + (7-i)] = bits & 0xFF; + bits >>= 8; + } + m_cursor = 64; + processBlock(); +} + +void SHA1::processBlock() +{ + uint32_t w[80] = { 0 }; + for (int t = 0; t < 16; ++t) + w[t] = (m_buffer[t*4] << 24) | + (m_buffer[t*4 + 1] << 16) | + (m_buffer[t*4 + 2] << 8) | + (m_buffer[t*4 + 3]); + for (int t = 16; t < 80; ++t) + w[t] = rotateLeft(1, w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16]); + + uint32_t a = m_hash[0], b = m_hash[1]; + uint32_t c = m_hash[2], d = m_hash[3]; + uint32_t e = m_hash[4]; + + for (int t = 0; t < 80; ++t) { + uint32_t temp = rotateLeft(5, a) + f(t, b, c, d) + e + w[t] + k(t); + e = d; d = c; + c = rotateLeft(30, b); + b = a; a = temp; + } + + m_hash[0] += a; m_hash[1] += b; + m_hash[2] += c; m_hash[3] += d; + m_hash[4] += e; + + m_cursor = 0; +} + +void SHA1::reset() +{ + m_cursor = 0; + m_totalBytes = 0; + m_hash[0] = 0x67452301; m_hash[1] = 0xefcdab89; + m_hash[2] = 0x98badcfe; m_hash[3] = 0x10325476; + m_hash[4] = 0xc3d2e1f0; + memset(m_buffer, 0, sizeof(m_buffer)); +} + +#ifdef TEST +static void expectSHA1(const char *input, int repeat, const char *expected) +{ + SHA1 sha1; + const uint8_t *inp = (const uint8_t *)input; + int len = strlen(input); + for (int i = 0; i < repeat; ++i) sha1.addBytes(inp, len); + uint8_t digest[20]; sha1.computeHash(digest); + char actual[64], *buffer = actual; + for (size_t i = 0; i < 20; ++i) { + snprintf(buffer, 3, "%02X", digest[i]); + buffer += 2; + } + if( !strcmp(actual, expected) ) return; + printf("input: %s, repeat: %d, actual: %s, expected: %s\n", + input, repeat, actual, expected); +} + +int main(int ac, char **av) +{ + // Examples taken from sample code in RFC 3174. + expectSHA1("abc", 1, "A9993E364706816ABA3E25717850C26C9CD0D89D"); + expectSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + 1, "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"); + expectSHA1("a", + 1000000, "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F"); + expectSHA1("0123456701234567012345670123456701234567012345670123456701234567", + 10, "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452"); + return 0; +} +#endif +