in Sources/Tensor/TensorUtilities.swift [59:151]
func sha1() -> SIMD32<UInt8> {
let blockSize = 64
var accumulated = self
let lengthInBits = accumulated.count * 8
let lengthBytes = lengthInBits.bytes(count: blockSize / 8)
// Step 1: Append padding.
let msgLength = accumulated.count
// Append one bit (`UInt8` with one bit) to the message.
accumulated.append(0x80)
// Append `0` bits until the length of `accumulated` in bits is 448 (mod 512).
let max = blockSize * 7 / 8
accumulated += [UInt8](
repeating: 0,
count: msgLength % blockSize < max
? max - 1 - (msgLength % blockSize) : blockSize + max - 1 - (msgLength % blockSize))
// Step 2: Append the message length as a 64-bit representation of `lengthInBits`.
accumulated += lengthBytes
// Step 3: Process the array bytes.
var accumulatedHash = SIMD8<UInt32>([
0x6745_2301, 0xefcd_ab89, 0x98ba_dcfe, 0x1032_5476, 0xc3d2_e1f0, 0x00, 0x00, 0x00,
])
var index = 0
while index < accumulated.count {
let chunk = accumulated[index..<(index + blockSize)]
index += blockSize
// Break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15, in big-endian format.
// Extend the sixteen 32-bit words into eighty 32-bit words:
var w = [UInt32](repeating: 0, count: 80)
for x in w.indices {
switch x {
case 0...15:
let start = chunk.startIndex.advanced(by: x * 4)
w[x] = UInt32(bytes: chunk, startingAt: start)
break
default:
let term = w[x - 3] ^ w[x - 8] ^ w[x - 14] ^ w[x - 16]
w[x] = term << 1 ^ term >> 31
break
}
}
var hashCopy = accumulatedHash
for j in w.indices {
var f: UInt32 = 0
var k: UInt32 = 0
switch j {
case 0...19:
f = (hashCopy[1] & hashCopy[2]) | (~hashCopy[1] & hashCopy[3])
k = 0x5a82_7999
break
case 20...39:
f = hashCopy[1] ^ hashCopy[2] ^ hashCopy[3]
k = 0x6ed9_eba1
break
case 40...59:
f =
(hashCopy[1] & hashCopy[2]) | (hashCopy[1] & hashCopy[3]) | (hashCopy[2] & hashCopy[3])
k = 0x8f1b_bcdc
break
default:
f = hashCopy[1] ^ hashCopy[2] ^ hashCopy[3]
k = 0xca62_c1d6
break
}
let temp = hashCopy[0] << 5 ^ hashCopy[0] >> 27
let t0 = temp &+ f &+ hashCopy[4] &+ w[j] &+ k
hashCopy[4] = hashCopy[3]
hashCopy[3] = hashCopy[2]
hashCopy[2] = hashCopy[1] << 30 ^ hashCopy[1] >> 2
hashCopy[1] = hashCopy[0]
hashCopy[0] = t0
}
accumulatedHash &+= hashCopy
}
// Step 4: Return the computed hash.
var result = SIMD32<UInt8>()
var position = 0
for index in accumulatedHash.indices {
let h = accumulatedHash[index]
result[position + 0] = UInt8((h >> 24) & 0xff)
result[position + 1] = UInt8((h >> 16) & 0xff)
result[position + 2] = UInt8((h >> 8) & 0xff)
result[position + 3] = UInt8(h & 0xff)
position += 4
}
return result
}