add bluray dv, misc fixes
[goodguy/history.git] / cinelerra-5.1 / cinelerra / sha1.C
1 // see copyright notice in sha1.h
2 #include "sha1.h"
3
4 void SHA1::addBytes(const uint8_t* input, size_t length)
5 {
6         m_totalBytes += length;
7         while (length > 0) {
8 #if 1
9 // allow unaliged access
10                 uint64_t *buf = (uint64_t*)&m_buffer[m_cursor];
11                 const uint64_t *inp = (const uint64_t*)input;
12                 while (length >= sizeof(uint64_t) && m_cursor < 64) {
13                         *buf++ = *inp++;
14                         m_cursor += sizeof(uint64_t);
15                         length -= sizeof(uint64_t);
16                 }
17                 input = (const uint8_t *)inp;
18 #endif
19                 while (length > 0 && m_cursor < 64) {
20                         m_buffer[m_cursor++] = *input++;
21                         --length;
22                 }
23                 if( m_cursor >= 64 ) processBlock();
24         }
25 }
26
27 void SHA1::computeHash(uint8_t *digest)
28 {
29         finalize();
30         memset(digest, 0, 20);
31         for (size_t i = 0; i < 5; ++i) {
32                 // Treat hashValue as a big-endian value.
33                 uint32_t hashValue = m_hash[i];
34                 for (int j = 0; j < 4; ++j) {
35                         digest[4*i + (3-j)] = hashValue & 0xFF;
36                         hashValue >>= 8;
37                 }
38         }
39
40         reset();
41 }
42
43 void SHA1::finalize()
44 {
45         m_buffer[m_cursor++] = 0x80;
46         if (m_cursor > 56) {
47                 while (m_cursor < 64) m_buffer[m_cursor++] = 0x00;
48                 processBlock();
49         }
50
51         for (size_t i = m_cursor; i < 56; ++i)
52                 m_buffer[i] = 0x00;
53
54         uint64_t bits = m_totalBytes*8;
55         for (int i = 0; i < 8; ++i) {
56                 m_buffer[56 + (7-i)] = bits & 0xFF;
57                 bits >>= 8;
58         }
59         m_cursor = 64;
60         processBlock();
61 }
62
63 void SHA1::processBlock()
64 {
65         uint32_t w[80] = { 0 };
66         for (int t = 0; t < 16; ++t)
67                 w[t] =  (m_buffer[t*4] << 24) |
68                 (m_buffer[t*4 + 1] << 16) |
69                 (m_buffer[t*4 + 2] << 8) |
70                 (m_buffer[t*4 + 3]);
71         for (int t = 16; t < 80; ++t)
72                 w[t] = rotateLeft(1, w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16]);
73
74         uint32_t a = m_hash[0], b = m_hash[1];
75         uint32_t c = m_hash[2], d = m_hash[3];
76         uint32_t e = m_hash[4];
77
78         for (int t = 0; t < 80; ++t) {
79                 uint32_t temp = rotateLeft(5, a) + f(t, b, c, d) + e + w[t] + k(t);
80                 e = d;  d = c;
81                 c = rotateLeft(30, b);
82                 b = a;  a = temp;
83         }
84
85         m_hash[0] += a;  m_hash[1] += b;
86         m_hash[2] += c;  m_hash[3] += d;
87         m_hash[4] += e;
88
89         m_cursor = 0;
90 }
91
92 void SHA1::reset()
93 {
94         m_cursor = 0;
95         m_totalBytes = 0;
96         m_hash[0] = 0x67452301;  m_hash[1] = 0xefcdab89;
97         m_hash[2] = 0x98badcfe;  m_hash[3] = 0x10325476;
98         m_hash[4] = 0xc3d2e1f0;
99         memset(m_buffer, 0, sizeof(m_buffer));
100 }
101
102 #ifdef TEST
103 static void expectSHA1(const char *input, int repeat, const char *expected)
104 {
105         SHA1 sha1;
106         const uint8_t *inp = (const uint8_t *)input;
107         int len = strlen(input);
108         for (int i = 0; i < repeat; ++i) sha1.addBytes(inp, len);
109         uint8_t digest[20];  sha1.computeHash(digest);
110         char actual[64], *buffer = actual;
111         for (size_t i = 0; i < 20; ++i) {
112                 snprintf(buffer, 3, "%02X", digest[i]);
113                 buffer += 2;
114         }
115         if( !strcmp(actual, expected) ) return;
116         printf("input: %s, repeat: %d, actual: %s, expected: %s\n",
117                 input, repeat, actual, expected);
118 }
119
120 int main(int ac, char **av)
121 {
122         // Examples taken from sample code in RFC 3174.
123         expectSHA1("abc", 1, "A9993E364706816ABA3E25717850C26C9CD0D89D");
124         expectSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
125                 1, "84983E441C3BD26EBAAE4AA1F95129E5E54670F1");
126         expectSHA1("a",
127                 1000000, "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F");
128         expectSHA1("0123456701234567012345670123456701234567012345670123456701234567",
129                 10, "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452");
130         return 0;
131 }
132 #endif
133