Skip to content

Commit 1ecc0ea

Browse files
author
git apple-llvm automerger
committed
Merge commit '43ff63477256' from llvm.org/master into apple/master
2 parents 0ea3865 + 43ff634 commit 1ecc0ea

File tree

2 files changed

+55
-15
lines changed

2 files changed

+55
-15
lines changed

llvm/lib/Support/SHA1.cpp

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/Support/SHA1.h"
1818
#include "llvm/ADT/ArrayRef.h"
19+
#include "llvm/Support/Endian.h"
1920
#include "llvm/Support/Host.h"
2021
using namespace llvm;
2122

@@ -26,45 +27,45 @@ using namespace llvm;
2627
#define SHA_BIG_ENDIAN
2728
#endif
2829

29-
static uint32_t rol(uint32_t Number, int Bits) {
30+
static inline uint32_t rol(uint32_t Number, int Bits) {
3031
return (Number << Bits) | (Number >> (32 - Bits));
3132
}
3233

33-
static uint32_t blk0(uint32_t *Buf, int I) { return Buf[I]; }
34+
static inline uint32_t blk0(uint32_t *Buf, int I) { return Buf[I]; }
3435

35-
static uint32_t blk(uint32_t *Buf, int I) {
36+
static inline uint32_t blk(uint32_t *Buf, int I) {
3637
Buf[I & 15] = rol(Buf[(I + 13) & 15] ^ Buf[(I + 8) & 15] ^ Buf[(I + 2) & 15] ^
3738
Buf[I & 15],
3839
1);
3940
return Buf[I & 15];
4041
}
4142

42-
static void r0(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
43-
int I, uint32_t *Buf) {
43+
static inline void r0(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D,
44+
uint32_t &E, int I, uint32_t *Buf) {
4445
E += ((B & (C ^ D)) ^ D) + blk0(Buf, I) + 0x5A827999 + rol(A, 5);
4546
B = rol(B, 30);
4647
}
4748

48-
static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
49-
int I, uint32_t *Buf) {
49+
static inline void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D,
50+
uint32_t &E, int I, uint32_t *Buf) {
5051
E += ((B & (C ^ D)) ^ D) + blk(Buf, I) + 0x5A827999 + rol(A, 5);
5152
B = rol(B, 30);
5253
}
5354

54-
static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
55-
int I, uint32_t *Buf) {
55+
static inline void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D,
56+
uint32_t &E, int I, uint32_t *Buf) {
5657
E += (B ^ C ^ D) + blk(Buf, I) + 0x6ED9EBA1 + rol(A, 5);
5758
B = rol(B, 30);
5859
}
5960

60-
static void r3(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
61-
int I, uint32_t *Buf) {
61+
static inline void r3(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D,
62+
uint32_t &E, int I, uint32_t *Buf) {
6263
E += (((B | C) & D) | (B & C)) + blk(Buf, I) + 0x8F1BBCDC + rol(A, 5);
6364
B = rol(B, 30);
6465
}
6566

66-
static void r4(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
67-
int I, uint32_t *Buf) {
67+
static inline void r4(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D,
68+
uint32_t &E, int I, uint32_t *Buf) {
6869
E += (B ^ C ^ D) + blk(Buf, I) + 0xCA62C1D6 + rol(A, 5);
6970
B = rol(B, 30);
7071
}
@@ -210,8 +211,31 @@ void SHA1::writebyte(uint8_t Data) {
210211
}
211212

212213
void SHA1::update(ArrayRef<uint8_t> Data) {
213-
for (auto &C : Data)
214-
writebyte(C);
214+
InternalState.ByteCount += Data.size();
215+
216+
// Finish the current block.
217+
if (InternalState.BufferOffset > 0) {
218+
const size_t Remainder = std::min<size_t>(
219+
Data.size(), BLOCK_LENGTH - InternalState.BufferOffset);
220+
for (size_t I = 0; I < Remainder; ++I)
221+
addUncounted(Data[I]);
222+
Data = Data.drop_front(Remainder);
223+
}
224+
225+
// Fast buffer filling for large inputs.
226+
while (Data.size() >= BLOCK_LENGTH) {
227+
assert(InternalState.BufferOffset == 0);
228+
assert(BLOCK_LENGTH % 4 == 0);
229+
constexpr size_t BLOCK_LENGTH_32 = BLOCK_LENGTH / 4;
230+
for (size_t I = 0; I < BLOCK_LENGTH_32; ++I)
231+
InternalState.Buffer.L[I] = support::endian::read32be(&Data[I * 4]);
232+
hashBlock();
233+
Data = Data.drop_front(BLOCK_LENGTH);
234+
}
235+
236+
// Finish the remainder.
237+
for (uint8_t C : Data)
238+
addUncounted(C);
215239
}
216240

217241
void SHA1::pad() {

llvm/unittests/Support/raw_sha1_ostream_test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ TEST(sha1_hash_test, Basic) {
4343
ASSERT_EQ("2EF7BDE608CE5404E97D5F042F95F89F1C232871", Hash);
4444
}
4545

46+
TEST(sha1_hash_test, Update) {
47+
SHA1 sha1;
48+
std::string Input = "123456789012345678901234567890";
49+
ASSERT_EQ(Input.size(), 30UL);
50+
// 3 short updates.
51+
sha1.update(Input);
52+
sha1.update(Input);
53+
sha1.update(Input);
54+
// Long update that gets into the optimized loop with prefix/suffix.
55+
sha1.update(Input + Input + Input + Input);
56+
// 18 bytes buffered now.
57+
58+
std::string Hash = toHex(sha1.final());
59+
ASSERT_EQ("3E4A614101AD84985AB0FE54DC12A6D71551E5AE", Hash);
60+
}
61+
4662
// Check that getting the intermediate hash in the middle of the stream does
4763
// not invalidate the final result.
4864
TEST(raw_sha1_ostreamTest, Intermediate) {

0 commit comments

Comments
 (0)