| 364 | /// If suffix length is bigger than block size. |
| 365 | #[inline(always)] |
| 366 | pub fn digest_pad( |
| 367 | &mut self, |
| 368 | delim: u8, |
| 369 | suffix: &[u8], |
| 370 | mut compress: impl FnMut(&Array<u8, BS>), |
| 371 | ) { |
| 372 | let pos = self.get_pos(); |
| 373 | let size = self.size(); |
| 374 | // Number of bytes remaining in the buffer after `delim` is written to it |
| 375 | // This never underflows since for eager buffers `size` is always greater than `pos`. |
| 376 | let pad_len = size - pos - 1; |
| 377 | |
| 378 | let suffix_dst_pos = size |
| 379 | .checked_sub(suffix.len()) |
| 380 | .expect("suffix must be smaller than buffer block size"); |
| 381 | |
| 382 | let g = ResetGuard(self); |
| 383 | // SAFETY: we fully initialize the buffer. Note that we may temporarily break |
| 384 | // the buffer invariant, but we restore it using `ResetGuard`, |
| 385 | // which works even if `compress` panics. |
| 386 | let buf = unsafe { |
| 387 | let p: *mut u8 = g.0.buffer.as_mut_ptr().cast::<u8>().add(pos); |
| 388 | ptr::write(p, delim); |
| 389 | ptr::write_bytes(p.add(1), 0, pad_len); |
| 390 | g.0.buffer.assume_init_mut() |
| 391 | }; |
| 392 | |
| 393 | if pad_len < suffix.len() { |
| 394 | compress(buf); |
| 395 | buf.fill(0); |
| 396 | } |
| 397 | |
| 398 | buf[suffix_dst_pos..].copy_from_slice(suffix); |
| 399 | compress(buf); |
| 400 | } |
| 401 | |
| 402 | /// Pad message with 0x80, zeros and 64-bit message length using |
| 403 | /// big-endian byte order. |