libluna/SHA: Reuse the m_message buffer to avoid duplicating the data to hash
All checks were successful
Build and test / build (push) Successful in 2m14s
All checks were successful
Build and test / build (push) Successful in 2m14s
This change is almost insignificant in most cases, but it avoids using 4GB of memory to hash a 2GB file.
This commit is contained in:
parent
c97876bba0
commit
d10cb10404
@ -45,29 +45,26 @@ Result<void> SHA256::append(const u8* data, usize size)
|
||||
// implement it!
|
||||
Result<SHA256::Digest> SHA256::digest()
|
||||
{
|
||||
usize message_block_length = m_message.size() + 1 + sizeof(u64);
|
||||
usize original_size = m_message.size();
|
||||
usize message_block_length = original_size + 1 + sizeof(u64);
|
||||
usize message_block_chunks = ceil_div(message_block_length, 64ul);
|
||||
usize num_zeros = message_block_chunks * 64 - message_block_length;
|
||||
|
||||
// Prepare a message block and add the data into it.
|
||||
Buffer message_block;
|
||||
TRY(message_block.append_data(m_message.data(), m_message.size()));
|
||||
|
||||
// Add one bit at the end.
|
||||
u8 one = 0b10000000;
|
||||
TRY(message_block.append_data(&one, 1));
|
||||
TRY(m_message.append_data(&one, 1));
|
||||
|
||||
// Fill with zeros.
|
||||
u8* slice = TRY(message_block.slice_at_end(num_zeros));
|
||||
u8* slice = TRY(m_message.slice_at_end(num_zeros));
|
||||
memset(slice, 0, num_zeros);
|
||||
|
||||
// Add the length of the original message (in bits), this has to be big-endian.
|
||||
usize message_length = m_message.size() * 8;
|
||||
usize message_length = original_size * 8;
|
||||
message_length = htobe64(message_length);
|
||||
TRY(message_block.append_data((const u8*)&message_length, sizeof(usize)));
|
||||
TRY(m_message.append_data((const u8*)&message_length, sizeof(usize)));
|
||||
|
||||
// The length of the message block should now be a multiple of 512 bits (64 bytes).
|
||||
check(is_aligned<64>(message_block.size()));
|
||||
check(is_aligned<64>(m_message.size()));
|
||||
|
||||
u32 a, b, c, d, e, f, g, h; // working variables
|
||||
u32 h0, h1, h2, h3, h4, h5, h6, h7; // hash values
|
||||
@ -88,7 +85,7 @@ Result<SHA256::Digest> SHA256::digest()
|
||||
// Create a message schedule of 64 dwords, and copy the current chunk into the first 16 dwords.
|
||||
u32 message_schedule[64];
|
||||
|
||||
memcpy(message_schedule, &message_block.data()[i * 64], 64);
|
||||
memcpy(message_schedule, &m_message.data()[i * 64], 64);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
for (int j = 0; j < 16; j++)
|
||||
|
Loading…
Reference in New Issue
Block a user