/** * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include // Include sys/types.h before inttypes.h to work around issue with // certain versions of GCC and newlib which causes omission of PRIu64 #include #include #include #include "pico/stdlib.h" #include "pico/sha256.h" // This was generated by cmake from sample.txt.inc #include "sample.txt.inc" static void sha_example() { printf("Text: %d bytes\n", sizeof(sample_txt) - 1); for(int i = 0; i < sizeof(sample_txt) - 1; i++) { if (i > 0 && i % 128 == 0) printf("\n"); putchar(sample_txt[i]); } printf("\n"); // Allocate a state object and start the calculation pico_sha256_state_t state; int rc = pico_sha256_start_blocking(&state, SHA256_BIG_ENDIAN, true); // using some DMA system resources hard_assert(rc == PICO_OK); pico_sha256_update_blocking(&state, (const uint8_t*)sample_txt, sizeof(sample_txt) - 1); // Get the result of the sha256 calculation sha256_result_t result; pico_sha256_finish(&state, &result); // print resulting sha256 result printf("Result:\n"); for(int i = 0; i < SHA256_RESULT_BYTES; i++) { printf("%02x ", result.bytes[i]); if ((i+1) % 16 == 0) printf("\n"); } // check it's what we expect from "sha256sum sample.txt" const uint8_t sha_expected[SHA256_RESULT_BYTES] = { 0x2d, 0x8c, 0x2f, 0x6d, 0x97, 0x8c, 0xa2, 0x17, 0x12, 0xb5, 0xf6, 0xde, 0x36, 0xc9, 0xd3, 0x1f, 0xa8, 0xe9, 0x6a, 0x4f, 0xa5, 0xd8, 0xff, 0x8b, 0x01, 0x88, 0xdf, 0xb9, 0xe7, 0xc1, 0x71, 0xbb }; hard_assert(memcmp(sha_expected, &result, SHA256_RESULT_BYTES) == 0); } #define BUFFER_SIZE 10000 // A performance test with a large amount of data static void nist_test(bool use_dma) { // nist 3 uint8_t *buffer = malloc(BUFFER_SIZE); memset(buffer, 0x61, BUFFER_SIZE); const uint8_t nist_3_expected[] = { \ 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67, 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 }; uint64_t start = time_us_64(); pico_sha256_state_t state; int rc = pico_sha256_start_blocking(&state, SHA256_BIG_ENDIAN, use_dma); // call start once hard_assert(rc == PICO_OK); for(int i = 0; i < 1000000; i += BUFFER_SIZE) { pico_sha256_update_blocking(&state, buffer, BUFFER_SIZE); // call update as many times as required } sha256_result_t result; pico_sha256_finish(&state, &result); // Call finish when done to get the result // Display the time taken uint64_t pico_time = time_us_64() - start; printf("Time for sha256 of 1M bytes %s DMA %"PRIu64"ms\n", use_dma ? "with" : "without", pico_time / 1000); hard_assert(memcmp(nist_3_expected, result.bytes, SHA256_RESULT_BYTES) == 0); } int main() { stdio_init_all(); sha_example(); // performance test with and without DMA nist_test(false); nist_test(true); printf("Success\n"); }