I tried adding a CommonCrypto-based implementation:
import CommonCrypto
public func sha256sha256(of data: Data) -> Data {
var buffer = UnsafeMutableRawPointer.allocate(byteCount: Int(CC_SHA256_DIGEST_LENGTH), alignment: 8)
var buffer2 = UnsafeMutablePointer<UInt8>.allocate(capacity: Int(CC_SHA256_DIGEST_LENGTH))
defer {
buffer.deallocate()
buffer2.deallocate()
}
data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> () in
CC_SHA256(ptr.baseAddress!, CC_LONG(data.count), buffer.assumingMemoryBound(to: UInt8.self))
}
CC_SHA256(buffer, CC_LONG(CC_SHA256_DIGEST_LENGTH), buffer2)
return Data(buffer: UnsafeBufferPointer(start: buffer2, count: Int(CC_SHA256_DIGEST_LENGTH)))
}
It ran in 1.094s compared 3.847 for CryptoSwift on my computer (I'm still on 10.14 so I couldn't test the CryptoKit one)
Worse, according to Instruments, only 279ms of that was actually spent in CC_SHA256, the rest was spent allocating and throwing away buffers, so if you spent a bit of time optimizing you should be able to do things much faster.
Based on this, I think that your issues are just as likely to be caused by you making a few extra data copies (for example when you call Data(digest)) or other things. I would recommend profiling your code in Instruments to see how much of this time is due to the library compared to how much of the time is due to your handling of its results.
Also you should probably turn on Whole Module Optimization
1 Like