xref: /isa-l_crypto/rolling_hash/chunking_with_mb_hash.c (revision 1e0b122e090c8ad3a8d8c56e182f754ea26fe70d)
153dc9fa0SGreg Tucker /**********************************************************************
253dc9fa0SGreg Tucker   Copyright(c) 2011-2017 Intel Corporation All rights reserved.
353dc9fa0SGreg Tucker 
453dc9fa0SGreg Tucker   Redistribution and use in source and binary forms, with or without
553dc9fa0SGreg Tucker   modification, are permitted provided that the following conditions
653dc9fa0SGreg Tucker   are met:
753dc9fa0SGreg Tucker     * Redistributions of source code must retain the above copyright
853dc9fa0SGreg Tucker       notice, this list of conditions and the following disclaimer.
953dc9fa0SGreg Tucker     * Redistributions in binary form must reproduce the above copyright
1053dc9fa0SGreg Tucker       notice, this list of conditions and the following disclaimer in
1153dc9fa0SGreg Tucker       the documentation and/or other materials provided with the
1253dc9fa0SGreg Tucker       distribution.
1353dc9fa0SGreg Tucker     * Neither the name of Intel Corporation nor the names of its
1453dc9fa0SGreg Tucker       contributors may be used to endorse or promote products derived
1553dc9fa0SGreg Tucker       from this software without specific prior written permission.
1653dc9fa0SGreg Tucker 
1753dc9fa0SGreg Tucker   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1853dc9fa0SGreg Tucker   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1953dc9fa0SGreg Tucker   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2053dc9fa0SGreg Tucker   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2153dc9fa0SGreg Tucker   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2253dc9fa0SGreg Tucker   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2353dc9fa0SGreg Tucker   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2453dc9fa0SGreg Tucker   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2553dc9fa0SGreg Tucker   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2653dc9fa0SGreg Tucker   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2753dc9fa0SGreg Tucker   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2853dc9fa0SGreg Tucker **********************************************************************/
2953dc9fa0SGreg Tucker 
3053dc9fa0SGreg Tucker #include <stdlib.h>
3153dc9fa0SGreg Tucker #include <stdint.h>
3253dc9fa0SGreg Tucker #include <stdarg.h>
3353dc9fa0SGreg Tucker #include <stdio.h>
3453dc9fa0SGreg Tucker #include <assert.h>
3577e513c6SMarcel Cornu #include "isal_crypto_api.h"
3653dc9fa0SGreg Tucker #include "rolling_hashx.h"
3753dc9fa0SGreg Tucker #include "sha256_mb.h"
3853dc9fa0SGreg Tucker #include "test.h"
3953dc9fa0SGreg Tucker 
4053dc9fa0SGreg Tucker #define MAX_BUFFER_SIZE 128 * 1024 * 1024
410a437795SPablo de Lara #define HASH_POOL_SIZE  ISAL_SHA256_MAX_LANES
4253dc9fa0SGreg Tucker 
4353dc9fa0SGreg Tucker #ifndef TEST_SEED
4453dc9fa0SGreg Tucker #define TEST_SEED 0x1234
4553dc9fa0SGreg Tucker #endif
4653dc9fa0SGreg Tucker 
4753dc9fa0SGreg Tucker #define FILTER_BITS 10
4853dc9fa0SGreg Tucker #define FILTER_SIZE (1 << FILTER_BITS)
4953dc9fa0SGreg Tucker #define FILTER_MASK (FILTER_SIZE - 1)
5053dc9fa0SGreg Tucker 
5153dc9fa0SGreg Tucker #define BITS_TO_INDEX_LONG 6
5253dc9fa0SGreg Tucker #define MASK_TO_INDEX_LONG ((1 << BITS_TO_INDEX_LONG) - 1)
5353dc9fa0SGreg Tucker 
5453dc9fa0SGreg Tucker // Globals
550a437795SPablo de Lara ISAL_SHA256_HASH_CTX ctxpool[ISAL_SHA256_MAX_LANES], *last_ctx;
560a437795SPablo de Lara ISAL_SHA256_HASH_CTX_MGR mb_hash_mgr;
5753dc9fa0SGreg Tucker uint64_t filter_table[FILTER_SIZE];
5853dc9fa0SGreg Tucker unsigned long chunks_created = 0;
5953dc9fa0SGreg Tucker unsigned long filter_hits = 0;
6053dc9fa0SGreg Tucker 
6153dc9fa0SGreg Tucker // Example function to run on each chunk
6253dc9fa0SGreg Tucker 
6359ca9063SMarcel Cornu void
run_fragment(ISAL_SHA256_HASH_CTX * ctx)640a437795SPablo de Lara run_fragment(ISAL_SHA256_HASH_CTX *ctx)
6553dc9fa0SGreg Tucker {
6653dc9fa0SGreg Tucker         uint64_t lookup, set_hash;
6753dc9fa0SGreg Tucker         unsigned int lookup_hash;
6853dc9fa0SGreg Tucker         uint32_t idx;
6953dc9fa0SGreg Tucker 
7053dc9fa0SGreg Tucker         chunks_created++;
7153dc9fa0SGreg Tucker 
7253dc9fa0SGreg Tucker         // Run a simple lookup filter on chunk using digest
7353dc9fa0SGreg Tucker         lookup_hash = ctx->job.result_digest[0] & FILTER_MASK;
7453dc9fa0SGreg Tucker         lookup = filter_table[lookup_hash];
7553dc9fa0SGreg Tucker 
7653dc9fa0SGreg Tucker         idx = ctx->job.result_digest[1];
7753dc9fa0SGreg Tucker 
7853dc9fa0SGreg Tucker         set_hash = 1 << (idx & MASK_TO_INDEX_LONG) |
7953dc9fa0SGreg Tucker                    1 << ((idx >> BITS_TO_INDEX_LONG) & MASK_TO_INDEX_LONG) |
8053dc9fa0SGreg Tucker                    1 << ((idx >> (2 * BITS_TO_INDEX_LONG)) & MASK_TO_INDEX_LONG);
8153dc9fa0SGreg Tucker 
8253dc9fa0SGreg Tucker         if ((lookup & set_hash) == set_hash)
8353dc9fa0SGreg Tucker                 filter_hits++;
8453dc9fa0SGreg Tucker         else
8553dc9fa0SGreg Tucker                 filter_table[lookup_hash] = lookup | set_hash;
8653dc9fa0SGreg Tucker }
8753dc9fa0SGreg Tucker 
88487b772bSPablo de Lara static int
setup_chunk_processing(void)8959ca9063SMarcel Cornu setup_chunk_processing(void)
9053dc9fa0SGreg Tucker {
9153dc9fa0SGreg Tucker         int i;
92487b772bSPablo de Lara         int ret = isal_sha256_ctx_mgr_init(&mb_hash_mgr);
9353dc9fa0SGreg Tucker 
94487b772bSPablo de Lara         if (ret)
95487b772bSPablo de Lara                 return -1;
9653dc9fa0SGreg Tucker 
9753dc9fa0SGreg Tucker         for (i = 0; i < HASH_POOL_SIZE; i++)
988cb7fe78SPablo de Lara                 isal_hash_ctx_init(&ctxpool[i]);
9953dc9fa0SGreg Tucker 
10053dc9fa0SGreg Tucker         last_ctx = &ctxpool[0];
101487b772bSPablo de Lara 
102487b772bSPablo de Lara         return 0;
10353dc9fa0SGreg Tucker }
10453dc9fa0SGreg Tucker 
105487b772bSPablo de Lara static ISAL_SHA256_HASH_CTX *
get_next_job_ctx(void)10659ca9063SMarcel Cornu get_next_job_ctx(void)
10753dc9fa0SGreg Tucker {
108487b772bSPablo de Lara         int i, ret;
1090a437795SPablo de Lara         ISAL_SHA256_HASH_CTX *ctx;
11053dc9fa0SGreg Tucker 
1118cb7fe78SPablo de Lara         if (last_ctx && isal_hash_ctx_complete(last_ctx))
11253dc9fa0SGreg Tucker                 return last_ctx;
11353dc9fa0SGreg Tucker 
11453dc9fa0SGreg Tucker         for (i = 0; i < HASH_POOL_SIZE; i++) {
1158cb7fe78SPablo de Lara                 if (isal_hash_ctx_complete(&ctxpool[i]))
11653dc9fa0SGreg Tucker                         return &ctxpool[i];
11753dc9fa0SGreg Tucker         }
118487b772bSPablo de Lara         ret = isal_sha256_ctx_mgr_flush(&mb_hash_mgr, &ctx);
119487b772bSPablo de Lara         if (ret)
120487b772bSPablo de Lara                 return NULL;
121487b772bSPablo de Lara 
12253dc9fa0SGreg Tucker         return ctx;
12353dc9fa0SGreg Tucker }
12453dc9fa0SGreg Tucker 
12559ca9063SMarcel Cornu void
put_next_job_ctx(ISAL_SHA256_HASH_CTX * ctx)1260a437795SPablo de Lara put_next_job_ctx(ISAL_SHA256_HASH_CTX *ctx)
12753dc9fa0SGreg Tucker {
1288cb7fe78SPablo de Lara         if (ctx && isal_hash_ctx_complete(ctx))
12953dc9fa0SGreg Tucker                 last_ctx = ctx;
13053dc9fa0SGreg Tucker 
13153dc9fa0SGreg Tucker         run_fragment(ctx);
13253dc9fa0SGreg Tucker }
13353dc9fa0SGreg Tucker 
134487b772bSPablo de Lara static int
process_chunk(uint8_t * buff,int len)13559ca9063SMarcel Cornu process_chunk(uint8_t *buff, int len)
13653dc9fa0SGreg Tucker {
1370a437795SPablo de Lara         ISAL_SHA256_HASH_CTX *ctx;
138487b772bSPablo de Lara         int ret;
13953dc9fa0SGreg Tucker 
14053dc9fa0SGreg Tucker         ctx = get_next_job_ctx();
141487b772bSPablo de Lara         if (ctx != NULL)
142487b772bSPablo de Lara                 return -1;
143487b772bSPablo de Lara 
144487b772bSPablo de Lara         ret = isal_sha256_ctx_mgr_submit(&mb_hash_mgr, ctx, &ctx, buff, len, ISAL_HASH_ENTIRE);
145487b772bSPablo de Lara         if (ret)
146487b772bSPablo de Lara                 return -1;
14753dc9fa0SGreg Tucker 
14853dc9fa0SGreg Tucker         if (ctx)
14953dc9fa0SGreg Tucker                 put_next_job_ctx(ctx);
150487b772bSPablo de Lara 
151487b772bSPablo de Lara         return 0;
15253dc9fa0SGreg Tucker }
15353dc9fa0SGreg Tucker 
154487b772bSPablo de Lara static int
finish_chunk_processing(void)15559ca9063SMarcel Cornu finish_chunk_processing(void)
15653dc9fa0SGreg Tucker {
1570a437795SPablo de Lara         ISAL_SHA256_HASH_CTX *ctx;
158487b772bSPablo de Lara         int ret;
15953dc9fa0SGreg Tucker 
160487b772bSPablo de Lara         do {
161487b772bSPablo de Lara                 ret = isal_sha256_ctx_mgr_flush(&mb_hash_mgr, &ctx);
162487b772bSPablo de Lara                 if (ret)
163487b772bSPablo de Lara                         return -1;
164487b772bSPablo de Lara                 if (ctx != NULL)
16553dc9fa0SGreg Tucker                         run_fragment(ctx);
166487b772bSPablo de Lara         } while (ctx != NULL);
167487b772bSPablo de Lara 
168487b772bSPablo de Lara         return 0;
16953dc9fa0SGreg Tucker }
17053dc9fa0SGreg Tucker 
17159ca9063SMarcel Cornu int
main(void)17259ca9063SMarcel Cornu main(void)
17353dc9fa0SGreg Tucker {
174487b772bSPablo de Lara         int i, w, match, ret, res = -1;
17553dc9fa0SGreg Tucker         uint8_t *buffer, *p;
17653dc9fa0SGreg Tucker         uint32_t mask, trigger, offset = 0;
17753dc9fa0SGreg Tucker         uint32_t min_chunk, max_chunk, mean_chunk;
17853dc9fa0SGreg Tucker         long remain;
179*1e0b122eSMarcel Cornu         struct isal_rh_state2 state;
18053dc9fa0SGreg Tucker         struct perf start, stop;
18153dc9fa0SGreg Tucker 
18253dc9fa0SGreg Tucker         // Chunking parameters
18353dc9fa0SGreg Tucker         w = 32;
18453dc9fa0SGreg Tucker         min_chunk = 1024;
18553dc9fa0SGreg Tucker         mean_chunk = 4 * 1024;
18653dc9fa0SGreg Tucker         max_chunk = 32 * 1024;
18777e513c6SMarcel Cornu         ret = isal_rolling_hashx_mask_gen(mean_chunk, 0, &mask);
18877e513c6SMarcel Cornu 
18977e513c6SMarcel Cornu         if (ret != ISAL_CRYPTO_ERR_NONE) {
19077e513c6SMarcel Cornu                 printf(" Error generating mask");
19177e513c6SMarcel Cornu                 return -1;
19277e513c6SMarcel Cornu         }
19377e513c6SMarcel Cornu 
19453dc9fa0SGreg Tucker         trigger = rand() & mask;
19553dc9fa0SGreg Tucker 
19653dc9fa0SGreg Tucker         printf("chunk and hash test w=%d, min=%d, target_ave=%d, max=%d:\n", w, min_chunk,
19753dc9fa0SGreg Tucker                mean_chunk, max_chunk);
19853dc9fa0SGreg Tucker 
19953dc9fa0SGreg Tucker         if (min_chunk < w || min_chunk > max_chunk) {
20053dc9fa0SGreg Tucker                 printf(" Improper parameters selected\n");
20153dc9fa0SGreg Tucker                 return -1;
20253dc9fa0SGreg Tucker         }
20353dc9fa0SGreg Tucker 
20453dc9fa0SGreg Tucker         if ((buffer = malloc(MAX_BUFFER_SIZE)) == NULL) {
20553dc9fa0SGreg Tucker                 printf("cannot allocate mem\n");
20653dc9fa0SGreg Tucker                 return -1;
20753dc9fa0SGreg Tucker         }
20853dc9fa0SGreg Tucker         // Initialize buffer with random data
20953dc9fa0SGreg Tucker         srand(TEST_SEED);
21053dc9fa0SGreg Tucker         for (i = 0; i < MAX_BUFFER_SIZE; i++)
21153dc9fa0SGreg Tucker                 buffer[i] = rand();
21253dc9fa0SGreg Tucker 
21353dc9fa0SGreg Tucker         // Start chunking test with multi-buffer hashing of results
21453dc9fa0SGreg Tucker         perf_start(&start);
21553dc9fa0SGreg Tucker 
21677e513c6SMarcel Cornu         isal_rolling_hash2_init(&state, w);
217487b772bSPablo de Lara         if (setup_chunk_processing() < 0) {
218487b772bSPablo de Lara                 printf("Setup chunk failed\n");
219487b772bSPablo de Lara                 goto end;
220487b772bSPablo de Lara         }
22153dc9fa0SGreg Tucker 
22253dc9fa0SGreg Tucker         p = buffer;
22353dc9fa0SGreg Tucker         remain = MAX_BUFFER_SIZE;
22453dc9fa0SGreg Tucker 
22553dc9fa0SGreg Tucker         while (remain > max_chunk) {
22653dc9fa0SGreg Tucker                 // Skip to min chunk
22777e513c6SMarcel Cornu                 isal_rolling_hash2_reset(&state, p + min_chunk - w);
22877e513c6SMarcel Cornu                 isal_rolling_hash2_run(&state, p + min_chunk, max_chunk - min_chunk, mask, trigger,
22977e513c6SMarcel Cornu                                        &offset, &match);
23053dc9fa0SGreg Tucker 
23153dc9fa0SGreg Tucker                 process_chunk(p, min_chunk + offset);
23253dc9fa0SGreg Tucker 
23353dc9fa0SGreg Tucker                 p += offset + min_chunk;
23453dc9fa0SGreg Tucker                 remain -= (offset + min_chunk);
23553dc9fa0SGreg Tucker         }
23653dc9fa0SGreg Tucker 
23753dc9fa0SGreg Tucker         while (remain > min_chunk) {
23877e513c6SMarcel Cornu                 isal_rolling_hash2_reset(&state, p + min_chunk - w);
23977e513c6SMarcel Cornu                 isal_rolling_hash2_run(&state, p + min_chunk, remain - min_chunk, mask, trigger,
24077e513c6SMarcel Cornu                                        &offset, &match);
24153dc9fa0SGreg Tucker 
24253dc9fa0SGreg Tucker                 process_chunk(p, min_chunk + offset);
24353dc9fa0SGreg Tucker 
24453dc9fa0SGreg Tucker                 p += offset + min_chunk;
24553dc9fa0SGreg Tucker                 remain -= (offset + min_chunk);
24653dc9fa0SGreg Tucker         }
24753dc9fa0SGreg Tucker 
24853dc9fa0SGreg Tucker         if (remain > 0)
24953dc9fa0SGreg Tucker                 process_chunk(p, remain);
25053dc9fa0SGreg Tucker 
251487b772bSPablo de Lara         if (finish_chunk_processing() < 0)
252487b772bSPablo de Lara                 goto end;
253487b772bSPablo de Lara 
25453dc9fa0SGreg Tucker         perf_stop(&stop);
25553dc9fa0SGreg Tucker 
25653dc9fa0SGreg Tucker         printf("chunking_with_mb_hash: ");
25753dc9fa0SGreg Tucker         perf_print(stop, start, MAX_BUFFER_SIZE);
25853dc9fa0SGreg Tucker 
25953dc9fa0SGreg Tucker         printf(" found %ld chunks, ave_len=%ld, filter hits=%ld\n", chunks_created,
26053dc9fa0SGreg Tucker                MAX_BUFFER_SIZE / chunks_created, filter_hits);
26153dc9fa0SGreg Tucker 
262487b772bSPablo de Lara         res = 0;
263487b772bSPablo de Lara end:
264487b772bSPablo de Lara         free(buffer);
265487b772bSPablo de Lara         return res;
26653dc9fa0SGreg Tucker }
267