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!
|
// implement it!
|
||||||
Result<SHA256::Digest> SHA256::digest()
|
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 message_block_chunks = ceil_div(message_block_length, 64ul);
|
||||||
usize num_zeros = message_block_chunks * 64 - message_block_length;
|
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.
|
// Add one bit at the end.
|
||||||
u8 one = 0b10000000;
|
u8 one = 0b10000000;
|
||||||
TRY(message_block.append_data(&one, 1));
|
TRY(m_message.append_data(&one, 1));
|
||||||
|
|
||||||
// Fill with zeros.
|
// 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);
|
memset(slice, 0, num_zeros);
|
||||||
|
|
||||||
// Add the length of the original message (in bits), this has to be big-endian.
|
// 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);
|
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).
|
// 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 a, b, c, d, e, f, g, h; // working variables
|
||||||
u32 h0, h1, h2, h3, h4, h5, h6, h7; // hash values
|
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.
|
// Create a message schedule of 64 dwords, and copy the current chunk into the first 16 dwords.
|
||||||
u32 message_schedule[64];
|
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
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
for (int j = 0; j < 16; j++)
|
for (int j = 0; j < 16; j++)
|
||||||
|
Loading…
Reference in New Issue
Block a user