mirror of
https://github.com/status-im/nim-eth-keys.git
synced 2025-02-13 09:46:44 +00:00
59 lines
2.3 KiB
Nim
59 lines
2.3 KiB
Nim
|
|
# Nim Eth-keyfile
|
|
# Copyright (c) 2018 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
#
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
#
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
# Nim Implementation of HMAC
|
|
# https://tools.ietf.org/html/rfc2104.html
|
|
|
|
# TODO: this is a duplicate of https://github.com/status-im/nim-eth-keys/blob/master/src/backend_native/hmac.nim
|
|
# It should be replaced by a common crypto library in the future like https://github.com/cheatfate/nimcrypto
|
|
|
|
import nimSHA2 # TODO: For SHA-256, use nimcrypto instead? (see https://github.com/cheatfate/nimcrypto/blob/master/tests/testhmac.nim)
|
|
|
|
proc hmac_sha256*[N: static[int]](key: array[N, byte|char],
|
|
data: string|seq[byte|char]): SHA256Digest =
|
|
# Note: due to https://github.com/nim-lang/Nim/issues/7208
|
|
# blockSize cannot be a compile-time parameter with a default value
|
|
const
|
|
opad: byte = 0x5c
|
|
ipad: byte = 0x36
|
|
blockSize = 64
|
|
|
|
var k, k_ipad{.noInit.}, k_opad{.noInit.}: array[blockSize, byte]
|
|
|
|
when N > blockSize:
|
|
k[0 ..< 32] = key.computeSHA256
|
|
else:
|
|
k[0 ..< N] = cast[array[N, byte]](key)
|
|
|
|
for i in 0 ..< blockSize:
|
|
k_ipad[i] = k[i] xor ipad
|
|
k_opad[i] = k[i] xor opad
|
|
|
|
# computeSHA256 requires a string input output a SHA256Digest* = array[0..31, char]
|
|
# but using $digest creates a string with its ex representation meaning it's a pain to chain
|
|
# The fact that arrays are now printable in Nim 0.18 doesn't help
|
|
# As a workaround we seqify arrays with @ and then convert to string with $
|
|
# TODO Continuous integration
|
|
|
|
# inner pass
|
|
result = computeSHA256($cast[array[blockSize,char]](k_ipad) & cast[string](data))
|
|
# outer pass
|
|
result = computeSHA256($cast[array[blockSize,char]](k_opad) & $result)
|
|
|
|
|
|
when isMainModule:
|
|
# From https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
|
|
let
|
|
key = ['k','e','y']
|
|
data = "The quick brown fox jumps over the lazy dog"
|
|
|
|
import strutils
|
|
doAssert hmac_sha256(key, data).toHex == "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8".toUpperAscii
|