import { flattenBinArray } from '../format/hex' ; import { Sha256 } from './sha256' ; import { Sha512 } from './sha512' ; param hashFunction param blockByteLength export const instantiateHmacFunction = ( hashFunction , blockByteLength ) => ( secret , message ) => { const key = new Uint8Array ( blockByteLength ) . fill ( 0 ) ; key . set ( secret . length > blockByteLength ? hashFunction ( secret ) : secret , 0 ) ; const innerPaddingFill = 0x36 ; const innerPadding = new Uint8Array ( blockByteLength ) . fill ( innerPaddingFill ) ; const innerPrefix = innerPadding . map ( ( pad , index ) => pad ^ key [ index ] ) ; const innerContent = flattenBinArray ( [ innerPrefix , message ] ) ; const innerResult = hashFunction ( innerContent ) ; const outerPaddingFill = 0x5c ; const outerPadding = new Uint8Array ( blockByteLength ) . fill ( outerPaddingFill ) ; const outerPrefix = outerPadding . map ( ( pad , index ) => pad ^ key [ index ] ) ; return hashFunction ( flattenBinArray ( [ outerPrefix , innerResult ] ) ) ; } ; const sha256BlockByteLength = 64 ; param sha256 param secret param message export const hmacSha256 = ( sha256 , secret , message ) => instantiateHmacFunction ( sha256 . hash , sha256BlockByteLength ) ( secret , message ) ; const sha512BlockByteLength = 128 ; param sha512 param secret param message export const hmacSha512 = ( sha512 , secret , message ) => instantiateHmacFunction ( sha512 . hash , sha512BlockByteLength ) ( secret , message ) ;