int main(void) { SHA1_HASH_CTX_MGR *mgr = NULL; SHA1_HASH_CTX ctxpool[TEST_BUFS]; uint32_t i, j, fail = 0; unsigned char *bufs[TEST_BUFS]; uint32_t lens[TEST_BUFS]; unsigned int jobs, t; uint8_t *tmp_buf; printf("multibinary_sha1 test, %d sets of %dx%d max: ", RANDOMS, TEST_BUFS, TEST_LEN); posix_memalign((void *)&mgr, 16, sizeof(SHA1_HASH_CTX_MGR)); sha1_ctx_mgr_init(mgr); srand(TEST_SEED); for (i = 0; i < TEST_BUFS; i++) { // Allocate and fill buffer bufs[i] = (unsigned char *)malloc(TEST_LEN); if (bufs[i] == NULL) { printf("malloc failed test aborted\n"); return 1; } rand_buffer(bufs[i], TEST_LEN); // Init ctx contexts hash_ctx_init(&ctxpool[i]); ctxpool[i].user_data = (void *)((uint64_t) i); // Run reference test sha1_ref(bufs[i], digest_ref[i], TEST_LEN); // Run sb_sha1 test sha1_ctx_mgr_submit(mgr, &ctxpool[i], bufs[i], TEST_LEN, HASH_ENTIRE); } while (sha1_ctx_mgr_flush(mgr)) ; for (i = 0; i < TEST_BUFS; i++) { for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) { fail++; printf("Test%d fixed size, digest%d " "fail 0x%08X <=> 0x%08X \n", i, j, ctxpool[i].job.result_digest[j], digest_ref[i][j]); } } } if (fail) { printf("Test failed function check %d\n", fail); return fail; } // Run tests with random size and number of jobs for (t = 0; t < RANDOMS; t++) { jobs = rand() % (TEST_BUFS); sha1_ctx_mgr_init(mgr); for (i = 0; i < jobs; i++) { // Use buffer with random len and contents lens[i] = rand() % (TEST_LEN); rand_buffer(bufs[i], lens[i]); // Run reference test sha1_ref(bufs[i], digest_ref[i], lens[i]); // Run sha1_mb test sha1_ctx_mgr_submit(mgr, &ctxpool[i], bufs[i], lens[i], HASH_ENTIRE); } while (sha1_ctx_mgr_flush(mgr)) ; for (i = 0; i < jobs; i++) { for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) { fail++; printf("Test%d, digest%d fail " "0x%08X <=> 0x%08X\n", i, j, ctxpool[i].job.result_digest[j], digest_ref[i][j]); } } } if (fail) { printf("Test failed function check %d\n", fail); return fail; } putchar('.'); fflush(0); } // random test t // Test at the end of buffer jobs = rand() % TEST_BUFS; tmp_buf = (uint8_t *) malloc(sizeof(uint8_t) * jobs); if (!tmp_buf) { printf("malloc failed, end test aborted.\n"); return 1; } rand_buffer(tmp_buf, jobs); sha1_ctx_mgr_init(mgr); // Extend to the end of allocated buffer to construct jobs for (i = 0; i < jobs; i++) { bufs[i] = (uint8_t *) & tmp_buf[i]; lens[i] = jobs - i; // Reference test sha1_ref(bufs[i], digest_ref[i], lens[i]); // sb_sha1 test sha1_ctx_mgr_submit(mgr, &ctxpool[i], bufs[i], lens[i], HASH_ENTIRE); } while (sha1_ctx_mgr_flush(mgr)) ; for (i = 0; i < jobs; i++) { for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) { fail++; printf("End test failed at offset %d - result: 0x%08X" ", ref: 0x%08X\n", i, ctxpool[i].job.result_digest[j], digest_ref[i][j]); } } } putchar('.'); if (fail) printf("Test failed function check %d\n", fail); else printf(" multibinary_sha1 rand: Pass\n"); return fail; }
int main(void) { SHA256_HASH_CTX_MGR *mgr = NULL; SHA256_HASH_CTX ctxpool[TEST_BUFS], *ctx = NULL; uint32_t i, j, fail = 0; int len_done, len_rem, len_rand; unsigned char *bufs[TEST_BUFS]; unsigned char *buf_ptr[TEST_BUFS]; uint32_t lens[TEST_BUFS]; unsigned int joblen, jobs, t; printf("multibinary_sha256_update test, %d sets of %dx%d max: ", RANDOMS, TEST_BUFS, TEST_LEN); srand(TEST_SEED); posix_memalign((void *)&mgr, 16, sizeof(SHA256_HASH_CTX_MGR)); sha256_ctx_mgr_init(mgr); for (i = 0; i < TEST_BUFS; i++) { // Allocte and fill buffer bufs[i] = (unsigned char *)malloc(TEST_LEN); buf_ptr[i] = bufs[i]; if (bufs[i] == NULL) { printf("malloc failed test aborted\n"); return 1; } rand_buffer(bufs[i], TEST_LEN); // Init ctx contents hash_ctx_init(&ctxpool[i]); ctxpool[i].user_data = (void *)((uint64_t) i); // Run reference test sha256_ref(bufs[i], digest_ref[i], TEST_LEN); } // Run sb_sha256 tests for (i = 0; i < TEST_BUFS;) { len_done = (int)((unsigned long)buf_ptr[i] - (unsigned long)bufs[i]); len_rem = TEST_LEN - len_done; if (len_done == 0) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], UPDATE_SIZE, HASH_FIRST); else if (len_rem <= UPDATE_SIZE) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rem, HASH_LAST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], UPDATE_SIZE, HASH_UPDATE); // Add jobs while available or finished if ((ctx == NULL) || hash_ctx_complete(ctx)) { i++; continue; } // Resubmit unfinished job i = (unsigned long)(ctx->user_data); buf_ptr[i] += UPDATE_SIZE; } // Start flushing finished jobs, end on last flushed ctx = sha256_ctx_mgr_flush(mgr); while (ctx) { if (hash_ctx_complete(ctx)) { debug_char('-'); ctx = sha256_ctx_mgr_flush(mgr); continue; } // Resubmit unfinished job i = (unsigned long)(ctx->user_data); buf_ptr[i] += UPDATE_SIZE; len_done = (int)((unsigned long)buf_ptr[i] - (unsigned long)bufs[i]); len_rem = TEST_LEN - len_done; if (len_rem <= UPDATE_SIZE) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rem, HASH_LAST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], UPDATE_SIZE, HASH_UPDATE); if (ctx == NULL) ctx = sha256_ctx_mgr_flush(mgr); } // Check digests for (i = 0; i < TEST_BUFS; i++) { for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) { fail++; printf("Test%d fixed size, digest%d fail %8X <=> %8X", i, j, ctxpool[i].job.result_digest[j], digest_ref[i][j]); } } } putchar('.'); // Run tests with random size and number of jobs for (t = 0; t < RANDOMS; t++) { jobs = rand() % (TEST_BUFS); for (i = 0; i < jobs; i++) { joblen = rand() % (TEST_LEN); rand_buffer(bufs[i], joblen); lens[i] = joblen; buf_ptr[i] = bufs[i]; sha256_ref(bufs[i], digest_ref[i], lens[i]); } sha256_ctx_mgr_init(mgr); // Run sha256_sb jobs i = 0; while (i < jobs) { // Submit a new job len_rand = SHA256_BLOCK_SIZE + SHA256_BLOCK_SIZE * (rand() % MAX_RAND_UPDATE_BLOCKS); if (lens[i] > len_rand) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rand, HASH_FIRST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], lens[i], HASH_ENTIRE); // Returned ctx could be: // - null context (we are just getting started and lanes aren't full yet), or // - finished already (an ENTIRE we submitted or a previous LAST is returned), or // - an unfinished ctx, we will resubmit if ((ctx == NULL) || hash_ctx_complete(ctx)) { i++; continue; } else { // unfinished ctx returned, choose another random update length and submit either // UPDATE or LAST depending on the amount of buffer remaining while ((ctx != NULL) && !(hash_ctx_complete(ctx))) { j = (unsigned long)(ctx->user_data); // Get index of the returned ctx buf_ptr[j] = bufs[j] + ctx->total_length; len_rand = (rand() % SHA256_BLOCK_SIZE) * (rand() % MAX_RAND_UPDATE_BLOCKS); len_rem = lens[j] - ctx->total_length; if (len_rem <= len_rand) // submit the rest of the job as LAST ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[j], buf_ptr[j], len_rem, HASH_LAST); else // submit the random update length as UPDATE ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[j], buf_ptr[j], len_rand, HASH_UPDATE); } // Either continue submitting any contexts returned here as UPDATE/LAST, or // go back to submitting new jobs using the index i. i++; } } // Start flushing finished jobs, end on last flushed ctx = sha256_ctx_mgr_flush(mgr); while (ctx) { if (hash_ctx_complete(ctx)) { debug_char('-'); ctx = sha256_ctx_mgr_flush(mgr); continue; } // Resubmit unfinished job i = (unsigned long)(ctx->user_data); buf_ptr[i] = bufs[i] + ctx->total_length; // update buffer pointer len_rem = lens[i] - ctx->total_length; len_rand = (rand() % SHA256_BLOCK_SIZE) * (rand() % MAX_RAND_UPDATE_BLOCKS); debug_char('+'); if (len_rem <= len_rand) ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rem, HASH_LAST); else ctx = sha256_ctx_mgr_submit(mgr, &ctxpool[i], buf_ptr[i], len_rand, HASH_UPDATE); if (ctx == NULL) ctx = sha256_ctx_mgr_flush(mgr); } // Check result digest for (i = 0; i < jobs; i++) { for (j = 0; j < SHA256_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != digest_ref[i][j]) { fail++; printf("Test%d, digest%d fail %8X <=> %8X\n", i, j, ctxpool[i].job.result_digest[j], digest_ref[i][j]); } } } if (fail) { printf("Test failed function check %d\n", fail); return fail; } putchar('.'); fflush(0); } // random test t if (fail) printf("Test failed function check %d\n", fail); else printf(" multibinary_sha256_update rand: Pass\n"); return fail; }
int main(void) { MD5_HASH_CTX_MGR *mgr = NULL; MD5_HASH_CTX ctxpool[TEST_BUFS]; unsigned char *bufs[TEST_BUFS]; uint32_t i, j, t, fail = 0; struct perf start, stop; for (i = 0; i < TEST_BUFS; i++) { bufs[i] = (unsigned char *)calloc((size_t) TEST_LEN, 1); if (bufs[i] == NULL) { printf("calloc failed test aborted\n"); return 1; } // Init ctx contents hash_ctx_init(&ctxpool[i]); ctxpool[i].user_data = (void *)((uint64_t) i); } posix_memalign((void *)&mgr, 16, sizeof(MD5_HASH_CTX_MGR)); md5_ctx_mgr_init(mgr); // Start OpenSSL tests perf_start(&start); for (t = 0; t < TEST_LOOPS; t++) { for (i = 0; i < TEST_BUFS; i++) MD5(bufs[i], TEST_LEN, digest_ssl[i]); } perf_stop(&stop); printf("md5_openssl" TEST_TYPE_STR ": "); perf_print(stop, start, (long long)TEST_LEN * i * t); // Start mb tests perf_start(&start); for (t = 0; t < TEST_LOOPS; t++) { for (i = 0; i < TEST_BUFS; i++) md5_ctx_mgr_submit(mgr, &ctxpool[i], bufs[i], TEST_LEN, HASH_ENTIRE); while (md5_ctx_mgr_flush(mgr)) ; } perf_stop(&stop); printf("multibinary_md5" TEST_TYPE_STR ": "); perf_print(stop, start, (long long)TEST_LEN * i * t); for (i = 0; i < TEST_BUFS; i++) { for (j = 0; j < MD5_DIGEST_NWORDS; j++) { if (ctxpool[i].job.result_digest[j] != ((uint32_t *) digest_ssl[i])[j]) { fail++; printf("Test%d, digest%d fail %08X <=> %08X\n", i, j, ctxpool[i].job.result_digest[j], ((uint32_t *) digest_ssl[i])[j]); } } } printf("Multi-buffer md5 test complete %d buffers of %d B with " "%d iterations\n", TEST_BUFS, TEST_LEN, TEST_LOOPS); if (fail) printf("Test failed function check %d\n", fail); else printf(" multibinary_md5_ossl_perf: Pass\n"); return fail; }
int main(void) { SHA1_HASH_CTX_MGR *mgr = NULL; SHA1_HASH_CTX ctxpool[NUM_JOBS], *ctx = NULL; uint32_t i, j, k, t, checked = 0; uint32_t *good; posix_memalign((void *)&mgr, 16, sizeof(SHA1_HASH_CTX_MGR)); sha1_ctx_mgr_init(mgr); // Init contexts before first use for (i = 0; i < MSGS; i++) { hash_ctx_init(&ctxpool[i]); ctxpool[i].user_data = (void *)((uint64_t) i); } for (i = 0; i < MSGS; i++) { ctx = sha1_ctx_mgr_submit(mgr, &ctxpool[i], msgs[i], strlen((char *)msgs[i]), HASH_ENTIRE); if (ctx) { t = (unsigned long)(ctx->user_data); good = expResultDigest[t]; checked++; for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { if (good[j] != ctxpool[t].job.result_digest[j]) { printf("Test %d, digest %d is %08X, should be %08X\n", t, j, ctxpool[t].job.result_digest[j], good[j]); return -1; } } if (ctx->error) { printf("Something bad happened during the submit." " Error code: %d", ctx->error); return -1; } } } while (1) { ctx = sha1_ctx_mgr_flush(mgr); if (ctx) { t = (unsigned long)(ctx->user_data); good = expResultDigest[t]; checked++; for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { if (good[j] != ctxpool[t].job.result_digest[j]) { printf("Test %d, digest %d is %08X, should be %08X\n", t, j, ctxpool[t].job.result_digest[j], good[j]); return -1; } } if (ctx->error) { printf("Something bad happened during the submit." " Error code: %d", ctx->error); return -1; } } else { break; } } // do larger test in pseudo-random order // Init contexts before first use for (i = 0; i < NUM_JOBS; i++) { hash_ctx_init(&ctxpool[i]); ctxpool[i].user_data = (void *)((uint64_t) i); } checked = 0; for (i = 0; i < NUM_JOBS; i++) { j = PSEUDO_RANDOM_NUM(i); ctx = sha1_ctx_mgr_submit(mgr, &ctxpool[i], msgs[j], strlen((char *)msgs[j]), HASH_ENTIRE); if (ctx) { t = (unsigned long)(ctx->user_data); k = PSEUDO_RANDOM_NUM(t); good = expResultDigest[k]; checked++; for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { if (good[j] != ctxpool[t].job.result_digest[j]) { printf("Test %d, digest %d is %08X, should be %08X\n", t, j, ctxpool[t].job.result_digest[j], good[j]); return -1; } } if (ctx->error) { printf("Something bad happened during the" " submit. Error code: %d", ctx->error); return -1; } t = (unsigned long)(ctx->user_data); k = PSEUDO_RANDOM_NUM(t); } } while (1) { ctx = sha1_ctx_mgr_flush(mgr); if (ctx) { t = (unsigned long)(ctx->user_data); k = PSEUDO_RANDOM_NUM(t); good = expResultDigest[k]; checked++; for (j = 0; j < SHA1_DIGEST_NWORDS; j++) { if (good[j] != ctxpool[t].job.result_digest[j]) { printf("Test %d, digest %d is %08X, should be %08X\n", t, j, ctxpool[t].job.result_digest[j], good[j]); return -1; } } if (ctx->error) { printf("Something bad happened during the submit." " Error code: %d", ctx->error); return -1; } } else { break; } } if (checked != NUM_JOBS) { printf("only tested %d rather than %d\n", checked, NUM_JOBS); return -1; } printf(" multibinary_sha1 test: Pass\n"); return 0; }