1 /* test_crc32.cc -- crc32 unit test
2  * Copyright (C) 2019-2021 IBM Corporation
3  * Authors: Rogerio Alves    <[email protected]>
4  *          Matheus Castanho <[email protected]>
5  * For conditions of distribution and use, see copyright notice in zlib.h
6  */
7 
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 
12 extern "C" {
13 #  include "zbuild.h"
14 #  include "zutil_p.h"
15 #  include "cpu_features.h"
16 }
17 
18 #include <gtest/gtest.h>
19 
20 typedef struct {
21     unsigned long crc;
22     const uint8_t *buf;
23     size_t len;
24     unsigned long expect;
25 } crc32_test;
26 
27 static const crc32_test tests[] = {
28   {0x0, (const uint8_t *)0x0, 0, 0x0},
29   {0xffffffff, (const uint8_t *)0x0, 0, 0x0},
30   {0x0, (const uint8_t *)0x0, 255, 0x0}, /*  BZ 174799.  */
31   {0x0, (const uint8_t *)0x0, 256, 0x0},
32   {0x0, (const uint8_t *)0x0, 257, 0x0},
33   {0x0, (const uint8_t *)0x0, 32767, 0x0},
34   {0x0, (const uint8_t *)0x0, 32768, 0x0},
35   {0x0, (const uint8_t *)0x0, 32769, 0x0},
36   {0x0, (const uint8_t *)"", 0, 0x0},
37   {0xffffffff, (const uint8_t *)"", 0, 0xffffffff},
38   {0x0, (const uint8_t *)"abacus", 6, 0xc3d7115b},
39   {0x0, (const uint8_t *)"backlog", 7, 0x269205},
40   {0x0, (const uint8_t *)"campfire", 8, 0x22a515f8},
41   {0x0, (const uint8_t *)"delta", 5, 0x9643fed9},
42   {0x0, (const uint8_t *)"executable", 10, 0xd68eda01},
43   {0x0, (const uint8_t *)"file", 4, 0x8c9f3610},
44   {0x0, (const uint8_t *)"greatest", 8, 0xc1abd6cd},
45   {0x0, (const uint8_t *)"hello", 5, 0x3610a686},
46   {0x0, (const uint8_t *)"inverter", 8, 0xc9e962c9},
47   {0x0, (const uint8_t *)"jigsaw", 6, 0xce4e3f69},
48   {0x0, (const uint8_t *)"karate", 6, 0x890be0e2},
49   {0x0, (const uint8_t *)"landscape", 9, 0xc4e0330b},
50   {0x0, (const uint8_t *)"machine", 7, 0x1505df84},
51   {0x0, (const uint8_t *)"nanometer", 9, 0xd4e19f39},
52   {0x0, (const uint8_t *)"oblivion", 8, 0xdae9de77},
53   {0x0, (const uint8_t *)"panama", 6, 0x66b8979c},
54   {0x0, (const uint8_t *)"quest", 5, 0x4317f817},
55   {0x0, (const uint8_t *)"resource", 8, 0xbc91f416},
56   {0x0, (const uint8_t *)"secret", 6, 0x5ca2e8e5},
57   {0x0, (const uint8_t *)"test", 4, 0xd87f7e0c},
58   {0x0, (const uint8_t *)"ultimate", 8, 0x3fc79b0b},
59   {0x0, (const uint8_t *)"vector", 6, 0x1b6e485b},
60   {0x0, (const uint8_t *)"walrus", 6, 0xbe769b97},
61   {0x0, (const uint8_t *)"xeno", 4, 0xe7a06444},
62   {0x0, (const uint8_t *)"yelling", 7, 0xfe3944e5},
63   {0x0, (const uint8_t *)"zlib", 4, 0x73887d3a},
64   {0x0, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1},
65   {0x0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e},
66   {0x0, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76},
67   {0x0, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a},
68   {0x0, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d},
69   {0x0, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5},
70   {0x0, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11},
71   {0x0, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac},
72   {0x0, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x625437bb},
73   {0x0, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9},
74   {0x0, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37},
75   {0x0, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0},
76   {0x0, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29},
77   {0x0, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8},
78   {0x0, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192},
79   {0x0, (const uint8_t *)"70684206568419061514", 20, 0x59a179f0},
80   {0x0, (const uint8_t *)"42015093765128581010", 20, 0xcd1013d7},
81   {0x0, (const uint8_t *)"88214814356148806939", 20, 0xab927546},
82   {0x0, (const uint8_t *)"43472694284527343838", 20, 0x11f3b20c},
83   {0x0, (const uint8_t *)"49769333513942933689", 20, 0xd562d4ca},
84   {0x0, (const uint8_t *)"54979784887993251199", 20, 0x233395f7},
85   {0x0, (const uint8_t *)"58360544869206793220", 20, 0x2d167fd5},
86   {0x0, (const uint8_t *)"27347953487840714234", 20, 0x8b5108ba},
87   {0x0, (const uint8_t *)"07650690295365319082", 20, 0xc46b3cd8},
88   {0x0, (const uint8_t *)"42655507906821911703", 20, 0xc10b2662},
89   {0x0, (const uint8_t *)"29977409200786225655", 20, 0xc9a0f9d2},
90   {0x0, (const uint8_t *)"85181542907229116674", 20, 0x9341357b},
91   {0x0, (const uint8_t *)"87963594337989416799", 20, 0xf0424937},
92   {0x0, (const uint8_t *)"21395988329504168551", 20, 0xd7c4c31f},
93   {0x0, (const uint8_t *)"51991013580943379423", 20, 0xf11edcc4},
94   {0x0, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4},
95   {0x0, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631},
96   {0x0, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99},
97   {0x0, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac},
98   {0x0, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9},
99   {0x0, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf},
100   {0x0, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac},
101   {0x0, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388},
102   {0x0, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d},
103   {0x0, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5},
104   {0x0, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9},
105   {0x0, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[[email protected]@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777},
106   {0x0, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048},
107   {0x7a30360d, (const uint8_t *)"abacus", 6, 0xf8655a84},
108   {0x6fd767ee, (const uint8_t *)"backlog", 7, 0x1ed834b1},
109   {0xefeb7589, (const uint8_t *)"campfire", 8, 0x686cfca},
110   {0x61cf7e6b, (const uint8_t *)"delta", 5, 0x1554e4b1},
111   {0xdc712e2,  (const uint8_t *)"executable", 10, 0x761b4254},
112   {0xad23c7fd, (const uint8_t *)"file", 4, 0x7abdd09b},
113   {0x85cb2317, (const uint8_t *)"greatest", 8, 0x4ba91c6b},
114   {0x9eed31b0, (const uint8_t *)"inverter", 8, 0xd5e78ba5},
115   {0xb94f34ca, (const uint8_t *)"jigsaw", 6, 0x23649109},
116   {0xab058a2,  (const uint8_t *)"karate", 6, 0xc5591f41},
117   {0x5bff2b7a, (const uint8_t *)"landscape", 9, 0xf10eb644},
118   {0x605c9a5f, (const uint8_t *)"machine", 7, 0xbaa0a636},
119   {0x51bdeea5, (const uint8_t *)"nanometer", 9, 0x6af89afb},
120   {0x85c21c79, (const uint8_t *)"oblivion", 8, 0xecae222b},
121   {0x97216f56, (const uint8_t *)"panama", 6, 0x47dffac4},
122   {0x18444af2, (const uint8_t *)"quest", 5, 0x70c2fe36},
123   {0xbe6ce359, (const uint8_t *)"resource", 8, 0x1471d925},
124   {0x843071f1, (const uint8_t *)"secret", 6, 0x50c9a0db},
125   {0xf2480c60, (const uint8_t *)"ultimate", 8, 0xf973daf8},
126   {0x2d2feb3d, (const uint8_t *)"vector", 6, 0x344ac03d},
127   {0x7490310a, (const uint8_t *)"walrus", 6, 0x6d1408ef},
128   {0x97d247d4, (const uint8_t *)"xeno", 4, 0xe62670b5},
129   {0x93cf7599, (const uint8_t *)"yelling", 7, 0x1b36da38},
130   {0x73c84278, (const uint8_t *)"zlib", 4, 0x6432d127},
131   {0x228a87d1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0},
132   {0xa7a048d0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274},
133   {0x1f0ded40, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870},
134   {0xa804a62f, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd},
135   {0x508fae6a, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc},
136   {0xe5adaf4f, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178},
137   {0x67136a40, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xc5213070},
138   {0xb00c4a10, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0},
139   {0x2e0c84b5, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72},
140   {0x81238d44, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620},
141   {0xf853aa92, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d},
142   {0x5a692325, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24},
143   {0x3275b9f,  (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df},
144   {0x38371feb, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30},
145   {0xafc8bf62, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9},
146   {0x9b07db73, (const uint8_t *)"70684206568419061514", 20, 0xae1fb7b7},
147   {0xe75b214,  (const uint8_t *)"42015093765128581010", 20, 0xd4eecd2d},
148   {0x72d0fe6f, (const uint8_t *)"88214814356148806939", 20, 0x4660ec7},
149   {0xf857a4b1, (const uint8_t *)"43472694284527343838", 20, 0xfd8afdf7},
150   {0x54b8e14,  (const uint8_t *)"49769333513942933689", 20, 0xc6d1b5f2},
151   {0xd6aa5616, (const uint8_t *)"54979784887993251199", 20, 0x32476461},
152   {0x11e63098, (const uint8_t *)"58360544869206793220", 20, 0xd917cf1a},
153   {0xbe92385,  (const uint8_t *)"27347953487840714234", 20, 0x4ad14a12},
154   {0x49511de0, (const uint8_t *)"07650690295365319082", 20, 0xe37b5c6c},
155   {0x3db13bc1, (const uint8_t *)"42655507906821911703", 20, 0x7cc497f1},
156   {0xbb899bea, (const uint8_t *)"29977409200786225655", 20, 0x99781bb2},
157   {0xf6cd9436, (const uint8_t *)"85181542907229116674", 20, 0x132256a1},
158   {0x9109e6c3, (const uint8_t *)"87963594337989416799", 20, 0xbfdb2c83},
159   {0x75770fc,  (const uint8_t *)"21395988329504168551", 20, 0x8d9d1e81},
160   {0x69b1d19b, (const uint8_t *)"51991013580943379423", 20, 0x7b6d4404},
161   {0xc6132975, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010},
162   {0xd58cb00c, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3},
163   {0xb63b8caa, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f},
164   {0x8a45a2b8, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de},
165   {0xcbe95b78, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59},
166   {0x4ef8a54b, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f},
167   {0x76ad267a, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac},
168   {0x569e613c, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66},
169   {0x36aa61da, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7},
170   {0xf67222df, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a},
171   {0x74b34fd3, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060},
172   {0x351fd770, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[[email protected]@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312},
173   {0xc45aef77, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912},
174   {0xc45aef77, (const uint8_t *)
175     "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
176     "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
177     "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
178     "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
179     "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
180     "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B}
181 };
182 
183 class crc32_variant : public ::testing::TestWithParam<crc32_test> {
184 public:
hash(crc32_test param,crc32_func crc32)185     void hash(crc32_test param, crc32_func crc32) {
186         uint32_t crc = 0;
187         if (param.buf != NULL) {
188             if (param.len) {
189                 crc = crc32(param.crc, param.buf, param.len);
190             } else {
191                 crc = param.crc;
192             }
193         }
194         EXPECT_EQ(crc, param.expect);
195     }
196 };
197 
198 INSTANTIATE_TEST_SUITE_P(crc32, crc32_variant, testing::ValuesIn(tests));
199 
200 #define TEST_CRC32(name, func, support_flag) \
201     TEST_P(crc32_variant, name) { \
202         if (!support_flag) { \
203             GTEST_SKIP(); \
204             return; \
205         } \
206         hash(GetParam(), func); \
207     }
208 
209 TEST_CRC32(braid, crc32_braid, 1)
210 
211 #ifdef ARM_ACLE_CRC_HASH
212 TEST_CRC32(acle, crc32_acle, arm_cpu_has_crc32)
213 #elif defined(POWER8_VSX_CRC32)
214 TEST_CRC32(power8, crc32_power8, power_cpu_has_arch_2_07)
215 #elif defined(S390_CRC32_VX)
216 TEST_CRC32(vx, PREFIX(s390_crc32_vx), PREFIX(s390_cpu_has_vx))
217 #elif defined(X86_PCLMULQDQ_CRC)
218 TEST_CRC32(pclmulqdq, crc32_pclmulqdq, x86_cpu_has_pclmulqdq)
219 #endif
220