13
13
14
14
/// SHA-256 implementation from Secure Hash Algorithm 2 (SHA-2) set of
15
15
/// cryptographic hash functions (FIPS PUB 180-2).
16
- struct SHA256 {
16
+ enum SHA256 {
17
17
/// The length of the output digest (in bits).
18
- private static let digestLength = 256
18
+ private static let _digestLength = 256
19
19
20
20
/// The size of each blocks (in bits).
21
- private static let blockBitSize = 512
21
+ private static let _blockBitSize = 512
22
22
23
23
/// The initial hash value.
24
- private static let initalHashValue : [ UInt32 ] = [
24
+ private static let _initialHashValue : [ UInt32 ] = [
25
25
0x6a09e667 , 0xbb67ae85 , 0x3c6ef372 , 0xa54ff53a , 0x510e527f , 0x9b05688c , 0x1f83d9ab , 0x5be0cd19
26
26
]
27
27
28
28
/// The constants in the algorithm (K).
29
- private static let konstants : [ UInt32 ] = [
29
+ private static let _konstants : [ UInt32 ] = [
30
30
0x428a2f98 , 0x71374491 , 0xb5c0fbcf , 0xe9b5dba5 , 0x3956c25b , 0x59f111f1 , 0x923f82a4 , 0xab1c5ed5 ,
31
31
0xd807aa98 , 0x12835b01 , 0x243185be , 0x550c7dc3 , 0x72be5d74 , 0x80deb1fe , 0x9bdc06a7 , 0xc19bf174 ,
32
32
0xe49b69c1 , 0xefbe4786 , 0x0fc19dc6 , 0x240ca1cc , 0x2de92c6f , 0x4a7484aa , 0x5cb0a9dc , 0x76f988da ,
@@ -37,28 +37,25 @@ struct SHA256 {
37
37
0x748f82ee , 0x78a5636f , 0x84c87814 , 0x8cc70208 , 0x90befffa , 0xa4506ceb , 0xbef9a3f7 , 0xc67178f2
38
38
]
39
39
40
- public init ( ) {
41
- }
42
-
43
- public func hash( _ bytes: [ UInt8 ] ) -> [ UInt8 ] {
44
- var input = bytes
40
+ public static func hash( _ bytes: some Sequence < UInt8 > ) -> [ UInt8 ] {
41
+ var input = Array ( bytes)
45
42
46
43
// Pad the input.
47
- pad ( & input)
44
+ _pad ( & input)
48
45
49
46
// Break the input into N 512-bit blocks.
50
- let messageBlocks = input. blocks ( size: Self . blockBitSize / 8 )
47
+ let messageBlocks = input. blocks ( size: _blockBitSize / 8 )
51
48
52
49
/// The hash that is being computed.
53
- var hash = Self . initalHashValue
50
+ var hash = _initialHashValue
54
51
55
52
// Process each block.
56
53
for block in messageBlocks {
57
- process ( block, hash: & hash)
54
+ _process ( block, hash: & hash)
58
55
}
59
56
60
57
// Finally, compute the result.
61
- var result = [ UInt8] ( repeating: 0 , count: Self . digestLength / 8 )
58
+ var result = [ UInt8] ( repeating: 0 , count: _digestLength / 8 )
62
59
for (idx, element) in hash. enumerated ( ) {
63
60
let pos = idx * 4
64
61
result [ pos + 0 ] = UInt8 ( ( element >> 24 ) & 0xff )
@@ -71,10 +68,10 @@ struct SHA256 {
71
68
}
72
69
73
70
/// Process and compute hash from a block.
74
- private func process ( _ block: ArraySlice < UInt8 > , hash: inout [ UInt32 ] ) {
71
+ private static func _process ( _ block: ArraySlice < UInt8 > , hash: inout [ UInt32 ] ) {
75
72
76
73
// Compute message schedule.
77
- var W = [ UInt32] ( repeating: 0 , count: Self . konstants . count)
74
+ var W = [ UInt32] ( repeating: 0 , count: _konstants . count)
78
75
for t in 0 ..< W . count {
79
76
switch t {
80
77
case 0 ... 15 :
@@ -101,10 +98,10 @@ struct SHA256 {
101
98
var h = hash [ 7 ]
102
99
103
100
// Run the main algorithm.
104
- for t in 0 ..< Self . konstants . count {
101
+ for t in 0 ..< _konstants . count {
105
102
let Σ1 = e. rotateRight ( by: 6 ) ^ e. rotateRight ( by: 11 ) ^ e. rotateRight ( by: 25 )
106
103
let ch = ( e & f) ^ ( ~ e & g)
107
- let t1 = h &+ Σ1 &+ ch &+ Self . konstants [ t] &+ W [ t]
104
+ let t1 = h &+ Σ1 &+ ch &+ _konstants [ t] &+ W [ t]
108
105
109
106
let Σ0 = a. rotateRight ( by: 2 ) ^ a. rotateRight ( by: 13 ) ^ a. rotateRight ( by: 22 )
110
107
let maj = ( a & b) ^ ( a & c) ^ ( b & c)
@@ -131,7 +128,7 @@ struct SHA256 {
131
128
}
132
129
133
130
/// Pad the given byte array to be a multiple of 512 bits.
134
- private func pad ( _ input: inout [ UInt8 ] ) {
131
+ private static func _pad ( _ input: inout [ UInt8 ] ) {
135
132
// Find the bit count of input.
136
133
let inputBitLength = input. count * 8
137
134
@@ -157,24 +154,24 @@ struct SHA256 {
157
154
158
155
// MARK:- Helpers
159
156
160
- private extension UInt64 {
157
+ extension UInt64 {
161
158
/// Converts the 64 bit integer into an array of single byte integers.
162
- func toByteArray( ) -> [ UInt8 ] {
159
+ fileprivate func toByteArray( ) -> [ UInt8 ] {
163
160
var value = self . littleEndian
164
161
return withUnsafeBytes ( of: & value, Array . init)
165
162
}
166
163
}
167
164
168
- private extension UInt32 {
165
+ extension UInt32 {
169
166
/// Rotates self by given amount.
170
- func rotateRight( by amount: UInt32 ) -> UInt32 {
167
+ fileprivate func rotateRight( by amount: UInt32 ) -> UInt32 {
171
168
return ( self >> amount) | ( self << ( 32 - amount) )
172
169
}
173
170
}
174
171
175
- private extension Array {
172
+ extension Array {
176
173
/// Breaks the array into the given size.
177
- func blocks( size: Int ) -> AnyIterator < ArraySlice < Element > > {
174
+ fileprivate func blocks( size: Int ) -> AnyIterator < ArraySlice < Element > > {
178
175
var currentIndex = startIndex
179
176
return AnyIterator {
180
177
if let nextIndex = self . index ( currentIndex, offsetBy: size, limitedBy: self . endIndex) {
@@ -185,18 +182,3 @@ private extension Array {
185
182
}
186
183
}
187
184
}
188
-
189
- // MARK: - 64-bit hash value
190
-
191
- /// Compute a 64-bit hash value of a sequence of bytes by computing its SHA-256
192
- /// hash and truncating the result.
193
- ///
194
- /// - Parameters:
195
- /// - bytes: The bytes for which a hash value should be computed.
196
- ///
197
- /// - Returns: The hash value computed for `bytes`.
198
- func make64BitHash( _ bytes: some Sequence < UInt8 > ) -> UInt64 {
199
- SHA256 ( ) . hash ( Array ( bytes) ) . withUnsafeBytes { hashBuffer in
200
- hashBuffer. loadUnaligned ( as: UInt64 . self)
201
- }
202
- }
0 commit comments