Added hash DMA implementation.
This commit is contained in:
		
							parent
							
								
									1027530902
								
							
						
					
					
						commit
						72bbfec39d
					
				@ -1015,6 +1015,7 @@ fn main() {
 | 
				
			|||||||
        (("dac", "CH1"), quote!(crate::dac::DacDma1)),
 | 
					        (("dac", "CH1"), quote!(crate::dac::DacDma1)),
 | 
				
			||||||
        (("dac", "CH2"), quote!(crate::dac::DacDma2)),
 | 
					        (("dac", "CH2"), quote!(crate::dac::DacDma2)),
 | 
				
			||||||
        (("timer", "UP"), quote!(crate::timer::UpDma)),
 | 
					        (("timer", "UP"), quote!(crate::timer::UpDma)),
 | 
				
			||||||
 | 
					        (("hash", "IN"), quote!(crate::hash::Dma)),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    .into();
 | 
					    .into();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,11 +2,13 @@
 | 
				
			|||||||
use core::cmp::min;
 | 
					use core::cmp::min;
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
use core::marker::PhantomData;
 | 
					use core::marker::PhantomData;
 | 
				
			||||||
 | 
					use core::ptr;
 | 
				
			||||||
use core::task::Poll;
 | 
					use core::task::Poll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
					use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
				
			||||||
use embassy_sync::waitqueue::AtomicWaker;
 | 
					use embassy_sync::waitqueue::AtomicWaker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::dma::Transfer;
 | 
				
			||||||
use crate::peripherals::HASH;
 | 
					use crate::peripherals::HASH;
 | 
				
			||||||
use stm32_metapac::hash::regs::*;
 | 
					use stm32_metapac::hash::regs::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -18,7 +20,6 @@ use crate::{interrupt, pac, peripherals, Peripheral};
 | 
				
			|||||||
const NUM_CONTEXT_REGS: usize = 51;
 | 
					const NUM_CONTEXT_REGS: usize = 51;
 | 
				
			||||||
#[cfg(hash_v2)]
 | 
					#[cfg(hash_v2)]
 | 
				
			||||||
const NUM_CONTEXT_REGS: usize = 54;
 | 
					const NUM_CONTEXT_REGS: usize = 54;
 | 
				
			||||||
const HASH_BUFFER_LEN: usize = 68;
 | 
					 | 
				
			||||||
const DIGEST_BLOCK_SIZE: usize = 64;
 | 
					const DIGEST_BLOCK_SIZE: usize = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static HASH_WAKER: AtomicWaker = AtomicWaker::new();
 | 
					static HASH_WAKER: AtomicWaker = AtomicWaker::new();
 | 
				
			||||||
@ -74,8 +75,7 @@ pub enum DataType {
 | 
				
			|||||||
/// Stores the state of the HASH peripheral for suspending/resuming
 | 
					/// Stores the state of the HASH peripheral for suspending/resuming
 | 
				
			||||||
/// digest calculation.
 | 
					/// digest calculation.
 | 
				
			||||||
pub struct Context {
 | 
					pub struct Context {
 | 
				
			||||||
    first_word_sent: bool,
 | 
					    buffer: [u8; DIGEST_BLOCK_SIZE],
 | 
				
			||||||
    buffer: [u8; HASH_BUFFER_LEN],
 | 
					 | 
				
			||||||
    buflen: usize,
 | 
					    buflen: usize,
 | 
				
			||||||
    algo: Algorithm,
 | 
					    algo: Algorithm,
 | 
				
			||||||
    format: DataType,
 | 
					    format: DataType,
 | 
				
			||||||
@ -86,17 +86,19 @@ pub struct Context {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// HASH driver.
 | 
					/// HASH driver.
 | 
				
			||||||
pub struct Hash<'d, T: Instance> {
 | 
					pub struct Hash<'d, T: Instance, D: Dma<T>> {
 | 
				
			||||||
    _peripheral: PeripheralRef<'d, T>,
 | 
					    _peripheral: PeripheralRef<'d, T>,
 | 
				
			||||||
 | 
					    dma: PeripheralRef<'d, D>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance> Hash<'d, T> {
 | 
					impl<'d, T: Instance, D: Dma<T>> Hash<'d, T, D> {
 | 
				
			||||||
    /// Instantiates, resets, and enables the HASH peripheral.
 | 
					    /// Instantiates, resets, and enables the HASH peripheral.
 | 
				
			||||||
    pub fn new(peripheral: impl Peripheral<P = T> + 'd) -> Self {
 | 
					    pub fn new(peripheral: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = D> + 'd) -> Self {
 | 
				
			||||||
        HASH::enable_and_reset();
 | 
					        HASH::enable_and_reset();
 | 
				
			||||||
        into_ref!(peripheral);
 | 
					        into_ref!(peripheral, dma);
 | 
				
			||||||
        let instance = Self {
 | 
					        let instance = Self {
 | 
				
			||||||
            _peripheral: peripheral,
 | 
					            _peripheral: peripheral,
 | 
				
			||||||
 | 
					            dma: dma,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        T::Interrupt::unpend();
 | 
					        T::Interrupt::unpend();
 | 
				
			||||||
@ -109,8 +111,7 @@ impl<'d, T: Instance> Hash<'d, T> {
 | 
				
			|||||||
    pub async fn start(&mut self, algorithm: Algorithm, format: DataType) -> Context {
 | 
					    pub async fn start(&mut self, algorithm: Algorithm, format: DataType) -> Context {
 | 
				
			||||||
        // Define a context for this new computation.
 | 
					        // Define a context for this new computation.
 | 
				
			||||||
        let mut ctx = Context {
 | 
					        let mut ctx = Context {
 | 
				
			||||||
            first_word_sent: false,
 | 
					            buffer: [0; DIGEST_BLOCK_SIZE],
 | 
				
			||||||
            buffer: [0; 68],
 | 
					 | 
				
			||||||
            buflen: 0,
 | 
					            buflen: 0,
 | 
				
			||||||
            algo: algorithm,
 | 
					            algo: algorithm,
 | 
				
			||||||
            format: format,
 | 
					            format: format,
 | 
				
			||||||
@ -134,6 +135,11 @@ impl<'d, T: Instance> Hash<'d, T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        T::regs().cr().modify(|w| w.set_algo0(algo0));
 | 
					        T::regs().cr().modify(|w| w.set_algo0(algo0));
 | 
				
			||||||
        T::regs().cr().modify(|w| w.set_algo1(algo1));
 | 
					        T::regs().cr().modify(|w| w.set_algo1(algo1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Enable multiple DMA transfers.
 | 
				
			||||||
 | 
					        T::regs().cr().modify(|w| w.set_mdmat(true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Set init to load the context registers. Necessary before storing context.
 | 
				
			||||||
        T::regs().cr().modify(|w| w.set_init(true));
 | 
					        T::regs().cr().modify(|w| w.set_init(true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Store and return the state of the peripheral.
 | 
					        // Store and return the state of the peripheral.
 | 
				
			||||||
@ -145,8 +151,8 @@ impl<'d, T: Instance> Hash<'d, T> {
 | 
				
			|||||||
    /// then updates the state with the provided data.
 | 
					    /// then updates the state with the provided data.
 | 
				
			||||||
    /// Peripheral state is saved upon return.
 | 
					    /// Peripheral state is saved upon return.
 | 
				
			||||||
    pub async fn update(&mut self, ctx: &mut Context, input: &[u8]) {
 | 
					    pub async fn update(&mut self, ctx: &mut Context, input: &[u8]) {
 | 
				
			||||||
        let mut data_waiting = input.len() + ctx.buflen;
 | 
					        let data_waiting = input.len() + ctx.buflen;
 | 
				
			||||||
        if data_waiting < DIGEST_BLOCK_SIZE || (data_waiting < ctx.buffer.len() && !ctx.first_word_sent) {
 | 
					        if data_waiting < DIGEST_BLOCK_SIZE {
 | 
				
			||||||
            // There isn't enough data to digest a block, so append it to the buffer.
 | 
					            // There isn't enough data to digest a block, so append it to the buffer.
 | 
				
			||||||
            ctx.buffer[ctx.buflen..ctx.buflen + input.len()].copy_from_slice(input);
 | 
					            ctx.buffer[ctx.buflen..ctx.buflen + input.len()].copy_from_slice(input);
 | 
				
			||||||
            ctx.buflen += input.len();
 | 
					            ctx.buflen += input.len();
 | 
				
			||||||
@ -159,65 +165,35 @@ impl<'d, T: Instance> Hash<'d, T> {
 | 
				
			|||||||
        let mut ilen_remaining = input.len();
 | 
					        let mut ilen_remaining = input.len();
 | 
				
			||||||
        let mut input_start = 0;
 | 
					        let mut input_start = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Handle first block.
 | 
					        // First ingest the data in the buffer.
 | 
				
			||||||
        if !ctx.first_word_sent {
 | 
					        let empty_len = DIGEST_BLOCK_SIZE - ctx.buflen;
 | 
				
			||||||
            let empty_len = ctx.buffer.len() - ctx.buflen;
 | 
					        if empty_len > 0 {
 | 
				
			||||||
            let copy_len = min(empty_len, ilen_remaining);
 | 
					            let copy_len = min(empty_len, ilen_remaining);
 | 
				
			||||||
            // Fill the buffer.
 | 
					            ctx.buffer[ctx.buflen..ctx.buflen + copy_len].copy_from_slice(&input[input_start..input_start + copy_len]);
 | 
				
			||||||
            if copy_len > 0 {
 | 
					            ctx.buflen += copy_len;
 | 
				
			||||||
                ctx.buffer[ctx.buflen..ctx.buflen + copy_len].copy_from_slice(&input[0..copy_len]);
 | 
					            ilen_remaining -= copy_len;
 | 
				
			||||||
                ctx.buflen += copy_len;
 | 
					            input_start += copy_len;
 | 
				
			||||||
                ilen_remaining -= copy_len;
 | 
					 | 
				
			||||||
                input_start += copy_len;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            assert_eq!(ctx.buflen, HASH_BUFFER_LEN);
 | 
					 | 
				
			||||||
            self.accumulate(ctx.buffer.as_slice());
 | 
					 | 
				
			||||||
            data_waiting -= ctx.buflen;
 | 
					 | 
				
			||||||
            ctx.buflen = 0;
 | 
					 | 
				
			||||||
            ctx.first_word_sent = true;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        self.accumulate(&ctx.buffer).await;
 | 
				
			||||||
 | 
					        ctx.buflen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if data_waiting < 64 {
 | 
					        // Move any extra data to the now-empty buffer.
 | 
				
			||||||
            // There isn't enough data remaining to process another block, so store it.
 | 
					        let leftovers = ilen_remaining % DIGEST_BLOCK_SIZE;
 | 
				
			||||||
            assert_eq!(ctx.buflen, 0);
 | 
					        if leftovers > 0 {
 | 
				
			||||||
            ctx.buffer[0..ilen_remaining].copy_from_slice(&input[input_start..input_start + ilen_remaining]);
 | 
					            assert!(ilen_remaining >= leftovers);
 | 
				
			||||||
            ctx.buflen += ilen_remaining;
 | 
					            ctx.buffer[0..leftovers].copy_from_slice(&input[input.len() - leftovers..input.len()]);
 | 
				
			||||||
 | 
					            ctx.buflen += leftovers;
 | 
				
			||||||
 | 
					            ilen_remaining -= leftovers;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            let mut total_data_sent = 0;
 | 
					            ctx.buffer
 | 
				
			||||||
 | 
					                .copy_from_slice(&input[input.len() - DIGEST_BLOCK_SIZE..input.len()]);
 | 
				
			||||||
            // First ingest the data in the buffer.
 | 
					            ctx.buflen += DIGEST_BLOCK_SIZE;
 | 
				
			||||||
            let empty_len = DIGEST_BLOCK_SIZE - ctx.buflen;
 | 
					            ilen_remaining -= DIGEST_BLOCK_SIZE;
 | 
				
			||||||
            if empty_len > 0 {
 | 
					 | 
				
			||||||
                let copy_len = min(empty_len, ilen_remaining);
 | 
					 | 
				
			||||||
                ctx.buffer[ctx.buflen..ctx.buflen + copy_len]
 | 
					 | 
				
			||||||
                    .copy_from_slice(&input[input_start..input_start + copy_len]);
 | 
					 | 
				
			||||||
                ctx.buflen += copy_len;
 | 
					 | 
				
			||||||
                ilen_remaining -= copy_len;
 | 
					 | 
				
			||||||
                input_start += copy_len;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            assert_eq!(ctx.buflen % 64, 0);
 | 
					 | 
				
			||||||
            self.accumulate(&ctx.buffer[0..64]);
 | 
					 | 
				
			||||||
            total_data_sent += ctx.buflen;
 | 
					 | 
				
			||||||
            ctx.buflen = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Move any extra data to the now-empty buffer.
 | 
					 | 
				
			||||||
            let leftovers = ilen_remaining % 64;
 | 
					 | 
				
			||||||
            if leftovers > 0 {
 | 
					 | 
				
			||||||
                assert!(ilen_remaining >= leftovers);
 | 
					 | 
				
			||||||
                ctx.buffer[0..leftovers].copy_from_slice(&input[input.len() - leftovers..input.len()]);
 | 
					 | 
				
			||||||
                ctx.buflen += leftovers;
 | 
					 | 
				
			||||||
                ilen_remaining -= leftovers;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            assert_eq!(ilen_remaining % 64, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Hash the remaining data.
 | 
					 | 
				
			||||||
            self.accumulate(&input[input_start..input_start + ilen_remaining]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            total_data_sent += ilen_remaining;
 | 
					 | 
				
			||||||
            assert_eq!(total_data_sent % 64, 0);
 | 
					 | 
				
			||||||
            assert!(total_data_sent >= 64);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Hash the remaining data.
 | 
				
			||||||
 | 
					        self.accumulate(&input[input_start..input_start + ilen_remaining]).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Save the peripheral context.
 | 
					        // Save the peripheral context.
 | 
				
			||||||
        self.store_context(ctx).await;
 | 
					        self.store_context(ctx).await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -228,12 +204,12 @@ impl<'d, T: Instance> Hash<'d, T> {
 | 
				
			|||||||
        // Restore the peripheral state.
 | 
					        // Restore the peripheral state.
 | 
				
			||||||
        self.load_context(&ctx);
 | 
					        self.load_context(&ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Hash the leftover bytes, if any.
 | 
					        // Must be cleared prior to the last DMA transfer.
 | 
				
			||||||
        self.accumulate(&ctx.buffer[0..ctx.buflen]);
 | 
					        T::regs().cr().modify(|w| w.set_mdmat(false));
 | 
				
			||||||
        ctx.buflen = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Start the digest calculation.
 | 
					        // Hash the leftover bytes, if any.
 | 
				
			||||||
        T::regs().str().write(|w| w.set_dcal(true));
 | 
					        self.accumulate(&ctx.buffer[0..ctx.buflen]).await;
 | 
				
			||||||
 | 
					        ctx.buflen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Wait for completion.
 | 
					        // Wait for completion.
 | 
				
			||||||
        poll_fn(|cx| {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
@ -272,19 +248,30 @@ impl<'d, T: Instance> Hash<'d, T> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Push data into the hash core.
 | 
					    /// Push data into the hash core.
 | 
				
			||||||
    fn accumulate(&mut self, input: &[u8]) {
 | 
					    async fn accumulate(&mut self, input: &[u8]) {
 | 
				
			||||||
 | 
					        // Ignore an input length of 0.
 | 
				
			||||||
 | 
					        if input.len() == 0 {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Set the number of valid bits.
 | 
					        // Set the number of valid bits.
 | 
				
			||||||
        let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8;
 | 
					        let num_valid_bits: u8 = (8 * (input.len() % 4)) as u8;
 | 
				
			||||||
        T::regs().str().modify(|w| w.set_nblw(num_valid_bits));
 | 
					        T::regs().str().modify(|w| w.set_nblw(num_valid_bits));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut i = 0;
 | 
					        // Configure DMA to transfer input to hash core.
 | 
				
			||||||
        while i < input.len() {
 | 
					        let dma_request = self.dma.request();
 | 
				
			||||||
            let mut word: [u8; 4] = [0; 4];
 | 
					        let dst_ptr = T::regs().din().as_ptr();
 | 
				
			||||||
            let copy_idx = min(i + 4, input.len());
 | 
					        let mut num_words = input.len() / 4;
 | 
				
			||||||
            word[0..copy_idx - i].copy_from_slice(&input[i..copy_idx]);
 | 
					        if input.len() % 4 > 0 {
 | 
				
			||||||
            T::regs().din().write_value(u32::from_ne_bytes(word));
 | 
					            num_words += 1;
 | 
				
			||||||
            i += 4;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        let src_ptr = ptr::slice_from_raw_parts(input.as_ptr().cast(), num_words);
 | 
				
			||||||
 | 
					        let dma_transfer =
 | 
				
			||||||
 | 
					            unsafe { Transfer::new_write_raw(&mut self.dma, dma_request, src_ptr, dst_ptr, Default::default()) };
 | 
				
			||||||
 | 
					        T::regs().cr().modify(|w| w.set_dmae(true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Wait for the transfer to complete.
 | 
				
			||||||
 | 
					        dma_transfer.await;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Save the peripheral state to a context.
 | 
					    /// Save the peripheral state to a context.
 | 
				
			||||||
@ -361,3 +348,5 @@ foreach_interrupt!(
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dma_trait!(Dma, Instance);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,27 +4,30 @@
 | 
				
			|||||||
use defmt::info;
 | 
					use defmt::info;
 | 
				
			||||||
use embassy_executor::Spawner;
 | 
					use embassy_executor::Spawner;
 | 
				
			||||||
use embassy_stm32::Config;
 | 
					use embassy_stm32::Config;
 | 
				
			||||||
use embassy_time::{Duration, Instant};
 | 
					use embassy_time::Instant;
 | 
				
			||||||
use {defmt_rtt as _, panic_probe as _};
 | 
					use {defmt_rtt as _, panic_probe as _};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_stm32::hash::*;
 | 
					use embassy_stm32::hash::*;
 | 
				
			||||||
use sha2::{Digest, Sha256};
 | 
					use sha2::{Digest, Sha256};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TEST_STRING_1: &[u8] = b"hello world";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[embassy_executor::main]
 | 
					#[embassy_executor::main]
 | 
				
			||||||
async fn main(_spawner: Spawner) -> ! {
 | 
					async fn main(_spawner: Spawner) -> ! {
 | 
				
			||||||
    let config = Config::default();
 | 
					    let config = Config::default();
 | 
				
			||||||
    let p = embassy_stm32::init(config);
 | 
					    let p = embassy_stm32::init(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh";
 | 
				
			||||||
 | 
					    let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut hw_hasher = Hash::new(p.HASH, p.DMA2_CH7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let hw_start_time = Instant::now();
 | 
					    let hw_start_time = Instant::now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Compute a digest in hardware.
 | 
					    // Compute a digest in hardware.
 | 
				
			||||||
    let mut hw_hasher = Hash::new(p.HASH);
 | 
					    let mut context = hw_hasher.start(Algorithm::SHA256, DataType::Width8).await;
 | 
				
			||||||
    let mut context = hw_hasher.start(Algorithm::SHA256, DataType::Width8);
 | 
					    hw_hasher.update(&mut context, test_1).await;
 | 
				
			||||||
    hw_hasher.update(&mut context, TEST_STRING_1);
 | 
					    hw_hasher.update(&mut context, test_2).await;
 | 
				
			||||||
    let mut buffer: [u8; 32] = [0; 32];
 | 
					    let mut buffer: [u8; 32] = [0; 32];
 | 
				
			||||||
    let hw_digest = hw_hasher.finish(context, &mut buffer);
 | 
					    let hw_digest = hw_hasher.finish(context, &mut buffer).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let hw_end_time = Instant::now();
 | 
					    let hw_end_time = Instant::now();
 | 
				
			||||||
    let hw_execution_time = hw_end_time - hw_start_time;
 | 
					    let hw_execution_time = hw_end_time - hw_start_time;
 | 
				
			||||||
@ -33,7 +36,8 @@ async fn main(_spawner: Spawner) -> ! {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Compute a digest in software.
 | 
					    // Compute a digest in software.
 | 
				
			||||||
    let mut sw_hasher = Sha256::new();
 | 
					    let mut sw_hasher = Sha256::new();
 | 
				
			||||||
    sw_hasher.update(TEST_STRING_1);
 | 
					    sw_hasher.update(test_1);
 | 
				
			||||||
 | 
					    sw_hasher.update(test_2);
 | 
				
			||||||
    let sw_digest = sw_hasher.finalize();
 | 
					    let sw_digest = sw_hasher.finalize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let sw_end_time = Instant::now();
 | 
					    let sw_end_time = Instant::now();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user