annotate sha1.c @ 411:d25e027364d6 libavutil

Check for the presence of llrint(), lrint(), round() and roundf() and provide simple replacements if they are unavailable. patch by Michael Kostylev, mik niipt ru
author diego
date Thu, 27 Dec 2007 01:53:02 +0000
parents 7390e0fc2fd3
children 81f4d434dc96
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
351
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
1 /*
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
2 * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
3 * based on public domain SHA-1 code by Steve Reid <steve@edmweb.com>
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
4 *
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
5 * This file is part of FFmpeg.
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
6 *
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
9 * License as published by the Free Software Foundation; either
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
11 *
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
15 * Lesser General Public License for more details.
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
16 *
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
47335869d5f7 Add proper license header.
diego
parents: 332
diff changeset
20 */
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
21
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
22 #include "common.h"
332
88e453a0975d add missing include of bswap.h
attila
parents: 315
diff changeset
23 #include "bswap.h"
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
24 #include "sha1.h"
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
25
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
26 typedef struct AVSHA1 {
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
27 uint64_t count;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
28 uint8_t buffer[64];
309
0498b2f2851a put state[5] last so no padding is needed on arch where uint64_t needs 8byte alignment
michael
parents: 308
diff changeset
29 uint32_t state[5];
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
30 } AVSHA1;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
31
406
aedb9d18c7cf Provide sha1 to outside applications
lu_zero
parents: 404
diff changeset
32 const int av_sha1_size = sizeof(AVSHA1);
aedb9d18c7cf Provide sha1 to outside applications
lu_zero
parents: 404
diff changeset
33
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
34 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
35
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
36 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
307
c5ee81be1e16 dont memcpy() simpler and same speed
michael
parents: 306
diff changeset
37 #define blk0(i) (block[i] = be2me_32(((uint32_t*)buffer)[i]))
301
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
38 #define blk(i) (block[i] = rol(block[i-3]^block[i-8]^block[i-14]^block[i-16],1))
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
39
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
40 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y) +blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
41 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y) +blk (i)+0x5A827999+rol(v,5);w=rol(w,30);
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
42 #define R2(v,w,x,y,z,i) z+=( w^x ^y) +blk (i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
43 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk (i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
44 #define R4(v,w,x,y,z,i) z+=( w^x ^y) +blk (i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
45
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
46 /* Hash a single 512-bit block. This is the core of the algorithm. */
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
47
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
48 static void transform(uint32_t state[5], uint8_t buffer[64]){
291
78b11473f66a avoid silly ring buffer logic (faster with -O2, -O3 is always slower then -O2)
michael
parents: 290
diff changeset
49 uint32_t block[80];
308
66948d7cef8a cosmetic
michael
parents: 307
diff changeset
50 unsigned int i, a, b, c, d, e;
290
8f02801da0f8 its faster to copy the data to the stack it seems ...
michael
parents: 289
diff changeset
51
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
52 a = state[0];
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
53 b = state[1];
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
54 c = state[2];
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
55 d = state[3];
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
56 e = state[4];
310
9a876d28d480 use CONFIG_SMALL
michael
parents: 309
diff changeset
57 #ifdef CONFIG_SMALL
302
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
58 for(i=0; i<80; i++){
306
d66e1c3838d7 simplify
michael
parents: 305
diff changeset
59 int t;
d66e1c3838d7 simplify
michael
parents: 305
diff changeset
60 if(i<16) t= be2me_32(((uint32_t*)buffer)[i]);
d66e1c3838d7 simplify
michael
parents: 305
diff changeset
61 else t= rol(block[i-3]^block[i-8]^block[i-14]^block[i-16],1);
d66e1c3838d7 simplify
michael
parents: 305
diff changeset
62 block[i]= t;
d66e1c3838d7 simplify
michael
parents: 305
diff changeset
63 t+= e+rol(a,5);
302
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
64 if(i<40){
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
65 if(i<20) t+= ((b&(c^d))^d) +0x5A827999;
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
66 else t+= ( b^c ^d) +0x6ED9EBA1;
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
67 }else{
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
68 if(i<60) t+= (((b|c)&d)|(b&c))+0x8F1BBCDC;
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
69 else t+= ( b^c ^d) +0xCA62C1D6;
901256787a89 factorize VARIANT2 (smaller and slower)
michael
parents: 301
diff changeset
70 }
299
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
71 e= d;
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
72 d= c;
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
73 c= rol(b,30);
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
74 b= a;
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
75 a= t;
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
76 }
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
77 #else
301
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
78 for(i=0; i<15; i+=5){
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
79 R0(a,b,c,d,e,0+i); R0(e,a,b,c,d,1+i); R0(d,e,a,b,c,2+i); R0(c,d,e,a,b,3+i); R0(b,c,d,e,a,4+i);
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
80 }
301
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
81 R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
b1c6f2421786 revert 2% speed loss change (r8360)
michael
parents: 300
diff changeset
82 for(i=20; i<40; i+=5){
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
83 R2(a,b,c,d,e,0+i); R2(e,a,b,c,d,1+i); R2(d,e,a,b,c,2+i); R2(c,d,e,a,b,3+i); R2(b,c,d,e,a,4+i);
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
84 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
85 for(; i<60; i+=5){
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
86 R3(a,b,c,d,e,0+i); R3(e,a,b,c,d,1+i); R3(d,e,a,b,c,2+i); R3(c,d,e,a,b,3+i); R3(b,c,d,e,a,4+i);
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
87 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
88 for(; i<80; i+=5){
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
89 R4(a,b,c,d,e,0+i); R4(e,a,b,c,d,1+i); R4(d,e,a,b,c,2+i); R4(c,d,e,a,b,3+i); R4(b,c,d,e,a,4+i);
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
90 }
299
5c84cfeb69a9 2 other variants of how to implement the core part
michael
parents: 298
diff changeset
91 #endif
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
92 state[0] += a;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
93 state[1] += b;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
94 state[2] += c;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
95 state[3] += d;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
96 state[4] += e;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
97 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
98
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
99 void av_sha1_init(AVSHA1* ctx){
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
100 ctx->state[0] = 0x67452301;
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
101 ctx->state[1] = 0xEFCDAB89;
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
102 ctx->state[2] = 0x98BADCFE;
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
103 ctx->state[3] = 0x10325476;
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
104 ctx->state[4] = 0xC3D2E1F0;
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
105 ctx->count = 0;
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
106 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
107
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
108 void av_sha1_update(AVSHA1* ctx, uint8_t* data, unsigned int len){
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
109 unsigned int i, j;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
110
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
111 j = ctx->count & 63;
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
112 ctx->count += len;
311
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
113 #ifdef CONFIG_SMALL
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
114 for( i = 0; i < len; i++ ){
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
115 ctx->buffer[ j++ ] = data[i];
311
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
116 if( 64 == j ){
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
117 transform(ctx->state, ctx->buffer);
311
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
118 j = 0;
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
119 }
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
120 }
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
121 #else
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
122 if ((j + len) > 63) {
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
123 memcpy(&ctx->buffer[j], data, (i = 64-j));
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
124 transform(ctx->state, ctx->buffer);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
125 for ( ; i + 63 < len; i += 64) {
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
126 transform(ctx->state, &data[i]);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
127 }
304
michael
parents: 303
diff changeset
128 j=0;
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
129 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
130 else i = 0;
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
131 memcpy(&ctx->buffer[j], &data[i], len - i);
311
999cbf01173a smaller av_sha1_update()
michael
parents: 310
diff changeset
132 #endif
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
133 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
134
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
135 void av_sha1_final(AVSHA1* ctx, uint8_t digest[20]){
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
136 int i;
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
137 uint64_t finalcount= be2me_64(ctx->count<<3);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
138
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
139 av_sha1_update(ctx, "\200", 1);
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
140 while ((ctx->count & 63) != 56) {
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
141 av_sha1_update(ctx, "", 1);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
142 }
407
7390e0fc2fd3 kill a warning, av_sha1_update accepts uint8_t * not uint64_t *
lu_zero
parents: 406
diff changeset
143 av_sha1_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */
295
e96e6ae1c3fa very slightly smaller object file
michael
parents: 294
diff changeset
144 for(i=0; i<5; i++)
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
145 ((uint32_t*)digest)[i]= be2me_32(ctx->state[i]);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
146 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
147
289
18a98b19af3f explain how to test it
michael
parents: 288
diff changeset
148 // use the following to test
292
d1f03d9014cb dont recommand testing with -O3
michael
parents: 291
diff changeset
149 // gcc -DTEST -DHAVE_AV_CONFIG_H -I.. sha1.c -O2 -W -Wall -o sha1 && time ./sha1
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
150 #ifdef TEST
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
151 #include <stdio.h>
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
152 #undef printf
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
153
404
f9a4c04ebb0e main() --> main(void)
diego
parents: 351
diff changeset
154 int main(void){
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
155 int i, k;
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
156 AVSHA1 ctx;
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
157 unsigned char digest[20];
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
158
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
159 for(k=0; k<3; k++){
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
160 av_sha1_init(&ctx);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
161 if(k==0)
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
162 av_sha1_update(&ctx, "abc", 3);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
163 else if(k==1)
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
164 av_sha1_update(&ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
165 else
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
166 for(i=0; i<1000*1000; i++)
315
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
167 av_sha1_update(&ctx, "a", 1);
ef246cda0613 s/context/ctx/
michael
parents: 311
diff changeset
168 av_sha1_final(&ctx, digest);
288
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
169 for (i = 0; i < 20; i++)
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
170 printf("%02X", digest[i]);
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
171 putchar('\n');
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
172 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
173 //Test Vectors (from FIPS PUB 180-1)
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
174 printf("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n"
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
175 "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n"
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
176 "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n");
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
177
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
178 return 0;
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
179 }
c82b7b95e69d simple SHA-1 implementation
michael
parents:
diff changeset
180 #endif