@@ -30,8 +30,29 @@ extension HashAlgorithm {
3030
3131/// SHA-256 implementation from Secure Hash Algorithm 2 (SHA-2) set of
3232/// cryptographic hash functions (FIPS PUB 180-2).
33+ /// Uses CryptoKit where available
3334public struct SHA256 : HashAlgorithm {
35+ private let underlying : HashAlgorithm
3436
37+ public init ( ) {
38+ #if canImport(CryptoKit)
39+ if #available( macOS 10 . 15 , iOS 13 , tvOS 13 , watchOS 6 , * ) {
40+ self . underlying = _CryptoKitSHA256 ( )
41+ } else {
42+ self . underlying = InternalSHA256 ( )
43+ }
44+ #else
45+ self . underlying = InternalSHA256 ( )
46+ #endif
47+ }
48+ public func hash( _ bytes: ByteString ) -> ByteString {
49+ self . underlying. hash ( bytes)
50+ }
51+ }
52+
53+ /// SHA-256 implementation from Secure Hash Algorithm 2 (SHA-2) set of
54+ /// cryptographic hash functions (FIPS PUB 180-2).
55+ struct InternalSHA256 : HashAlgorithm {
3556 /// The length of the output digest (in bits).
3657 private static let digestLength = 256
3758
@@ -65,18 +86,18 @@ public struct SHA256: HashAlgorithm {
6586 pad ( & input)
6687
6788 // Break the input into N 512-bit blocks.
68- let messageBlocks = input. blocks ( size: SHA256 . blockBitSize / 8 )
89+ let messageBlocks = input. blocks ( size: Self . blockBitSize / 8 )
6990
7091 /// The hash that is being computed.
71- var hash = SHA256 . initalHashValue
92+ var hash = Self . initalHashValue
7293
7394 // Process each block.
7495 for block in messageBlocks {
7596 process ( block, hash: & hash)
7697 }
7798
7899 // Finally, compute the result.
79- var result = [ UInt8] ( repeating: 0 , count: SHA256 . digestLength / 8 )
100+ var result = [ UInt8] ( repeating: 0 , count: Self . digestLength / 8 )
80101 for (idx, element) in hash. enumerated ( ) {
81102 let pos = idx * 4
82103 result [ pos + 0 ] = UInt8 ( ( element >> 24 ) & 0xff )
@@ -92,7 +113,7 @@ public struct SHA256: HashAlgorithm {
92113 private func process( _ block: ArraySlice < UInt8 > , hash: inout [ UInt32 ] ) {
93114
94115 // Compute message schedule.
95- var W = [ UInt32] ( repeating: 0 , count: SHA256 . konstants. count)
116+ var W = [ UInt32] ( repeating: 0 , count: Self . konstants. count)
96117 for t in 0 ..< W . count {
97118 switch t {
98119 case 0 ... 15 :
@@ -119,10 +140,10 @@ public struct SHA256: HashAlgorithm {
119140 var h = hash [ 7 ]
120141
121142 // Run the main algorithm.
122- for t in 0 ..< SHA256 . konstants. count {
143+ for t in 0 ..< Self . konstants. count {
123144 let Σ1 = e. rotateRight ( by: 6 ) ^ e. rotateRight ( by: 11 ) ^ e. rotateRight ( by: 25 )
124145 let ch = ( e & f) ^ ( ~ e & g)
125- let t1 = h &+ Σ1 &+ ch &+ SHA256 . konstants [ t] &+ W [ t]
146+ let t1 = h &+ Σ1 &+ ch &+ Self . konstants [ t] &+ W [ t]
126147
127148 let Σ0 = a. rotateRight ( by: 2 ) ^ a. rotateRight ( by: 13 ) ^ a. rotateRight ( by: 22 )
128149 let maj = ( a & b) ^ ( a & c) ^ ( b & c)
@@ -173,23 +194,30 @@ public struct SHA256: HashAlgorithm {
173194 }
174195}
175196
176- /// Wraps CryptoKit.SHA256 to provide a HashAlgorithm conformance to it.
197+ #if canImport(CryptoKit)
198+ @available ( * , deprecated, message: " use SHA256 which abstract over platform differences " )
177199@available ( macOS 10 . 15 , iOS 13 , tvOS 13 , watchOS 6 , * )
178200public struct CryptoKitSHA256 : HashAlgorithm {
179- public init ( ) {
201+ let underlying = _CryptoKitSHA256 ( )
202+ public init ( ) { }
203+ public func hash( _ bytes: ByteString ) -> ByteString {
204+ self . underlying. hash ( bytes)
180205 }
206+ }
181207
208+ /// Wraps CryptoKit.SHA256 to provide a HashAlgorithm conformance to it.
209+ @available ( macOS 10 . 15 , iOS 13 , tvOS 13 , watchOS 6 , * )
210+ struct _CryptoKitSHA256 : HashAlgorithm {
211+ public init ( ) {
212+ }
182213 public func hash( _ bytes: ByteString ) -> ByteString {
183- #if canImport(CryptoKit)
184214 return bytes. withData { data in
185215 let digest = CryptoKit . SHA256. hash ( data: data)
186216 return ByteString ( digest)
187217 }
188- #else
189- fatalError ( " not supported on this platform " )
190- #endif
191218 }
192219}
220+ #endif
193221
194222// MARK:- Helpers
195223
0 commit comments