@@ -134,6 +134,83 @@ proc sha256*(data: openarray[byte]): array[32, uint8] {.inline.} =
134
134
proc sha256 * (data: string ): array [32 , uint8 ] {.inline .} =
135
135
sha256 (data.cstring , data.len)
136
136
137
+ proc hmacSha256 * (key, data: openarray [uint8 ]): array [32 , uint8 ] =
138
+ const
139
+ blockSize = 64
140
+ ipad = 0x 36
141
+ opad = 0x 5c
142
+
143
+ var blockSizeKey: array [blockSize, uint8 ]
144
+ if key.len > blockSize:
145
+ let hash = sha256 (key)
146
+ copyMem (blockSizeKey[0 ].addr , hash[0 ].unsafeAddr, hash.len)
147
+ else :
148
+ copyMem (blockSizeKey[0 ].addr , key[0 ].unsafeAddr, key.len)
149
+
150
+ proc applyXor (s: array [64 , uint8 ], value: uint8 ): array [64 , uint8 ] =
151
+ result = s
152
+ for c in result .mitems:
153
+ c = (c xor value)
154
+
155
+ let ipadXor = applyXor (blockSizeKey, ipad)
156
+
157
+ let h1 =
158
+ if data.len > 0 :
159
+ var s = newString (ipadXor.len + data.len)
160
+ copyMem (s[0 ].addr , ipadXor[0 ].unsafeAddr, ipadXor.len)
161
+ copyMem (s[ipadXor.len].addr , data[0 ].unsafeAddr, data.len)
162
+ sha256 (s)
163
+ else :
164
+ sha256 (ipadXor)
165
+
166
+ let opadXor = applyXor (blockSizeKey, opad)
167
+
168
+ var s2 = newString (opadXor.len + 32 )
169
+ copyMem (s2[0 ].addr , opadXor[0 ].unsafeAddr, opadXor.len)
170
+ copyMem (s2[opadXor.len].addr , h1[0 ].unsafeAddr, 32 )
171
+
172
+ sha256 (s2)
173
+
174
+ proc hmacSha256 * (
175
+ key, data: string
176
+ ): array [32 , uint8 ] {.inline .} =
177
+ hmacSha256 (
178
+ key.toOpenArrayByte (0 , key.high),
179
+ data.toOpenArrayByte (0 , data.high)
180
+ )
181
+
182
+ proc hmacSha256 * (
183
+ key: string ,
184
+ data: openarray [byte ]
185
+ ): array [32 , uint8 ] {.inline .} =
186
+ hmacSha256 (
187
+ key.toOpenArrayByte (0 , key.high),
188
+ data
189
+ )
190
+
191
+ proc hmacSha256 * (
192
+ key: openarray [byte ],
193
+ data: string
194
+ ): array [32 , uint8 ] {.inline .} =
195
+ hmacSha256 (
196
+ key,
197
+ data.toOpenArrayByte (0 , data.high)
198
+ )
199
+
200
+ proc pbkdf2 * (password, salt: string , iterations: int ): array [32 , uint8 ] =
201
+ # # PBKDF2-HMAC-SHA256
202
+
203
+ result = hmacSha256 (password, salt & " \0\0\0\1 " )
204
+
205
+ var
206
+ buf1 = result
207
+ buf2: array [32 , uint8 ]
208
+ for _ in 1 ..< iterations:
209
+ swap (buf1, buf2)
210
+ buf1 = hmacSha256 (password, buf2)
211
+ for i in 0 ..< 32 :
212
+ result [i] = result [i] xor buf1[i]
213
+
137
214
proc toHex * (a: array [32 , uint8 ]): string =
138
215
result = newStringOfCap (64 )
139
216
for i in 0 ..< a.len:
0 commit comments