Here's an implementation of the hmac algorithm which supports using an
somewhat arbitrary hash function (I have assumed that the hash
produces a literal result, as opposed to a bit stream, a large
arbitrary precision integer or a sequence of integers representing
bytes), but other than that optimized for simplicity:

a2b=: ((8#2)#:a.&i.) :.(a.{~#.)

hmac=: {{ NB. https://en.wikipedia.org/wiki/HMAC
  NB. y: message
  NB. n: key
  NB. u: hash function
  NB. x: block size, in bytes (default: 64)
  64 u hmac n y
:
  if. 0=#(u'')-.,hfd i.16 do.
    raw=. a. {~ _2 dfh\ u
  else.
    raw=. u
  end.
  k=. x{.(raw^:(x<#n) n), x#{.a.
  okey=. k ~:&.a2b x# 16b5c{a.
  ikey=. k ~:&.a2b x# 16b36{a.
  u okey, raw ikey, y
}}

This hmac implementation requires the user to specify the block size
(there does not seem to be any algorithmic way of determining the
block size, given an arbitrary hash function).

But, we can determine whether the hash function produces a hexadecimal
result (by hashing an arbitrary string -- the empty string is fine) --
and seeing if the result has any non-hexadecimal characters. And, when
we have a hash which produces a hexadecimal result, for the
intermediate stages we need a 'raw' version of that hash.

I hope this makes sense,

-- 
Raul

On Wed, Feb 2, 2022 at 7:58 AM Raul Miller <[email protected]> wrote:
>
> The algorithm works with raw binary -- it will not be the case that
> all bytes will have ascii graphics.
>
> And, that relates to the other problem with your implementation: you
> are using a hexadecimal representation of a binary result as if it
> were equivalent to that binary result.
>
> I hope this makes sense,
>
> --
> Raul
>
> On Wed, Feb 2, 2022 at 7:45 AM 'Viktor Grigorov' via Programming
> <[email protected]> wrote:
> >
> > I tried padding with 0 0 1 1 0 0 0 0 ('0') and with 0 0 0 0 0 0 0, and with 
> > your padkey function, but I don't get the proper results. Also, the 0x5c 
> > and 0x36 from the ascii table correspond to '/' and '6', yours results in 
> > ungraphable members.
> > You said other issues exist as well, I would appreciate it if you could 
> > point them out.
> > Feb 2, 2022, 17:32 by [email protected]:
> >
> > > Actually, for the general case, the hash function may have an output
> > > size smaller than the block size.
> > >
> > > So:
> > >
> > > padkey=: {{
> > >  if.x < # y do. y=. u y end.
> > >  x{.y,x#{.a.
> > > }}
> > >
> > > FYI,
> > >
> > > --
> > > Raul
> > >
> > > On Wed, Feb 2, 2022 at 6:51 AM Raul Miller <[email protected]> wrote:
> > >
> > >>
> > >> On Wed, Feb 2, 2022 at 4:41 AM 'Viktor Grigorov' via Programming
> > >> <[email protected]> wrote:
> > >> > I wanted to see if J could be faster than bespoke C programs 
> > >> > (specifically aircrack-ng, ~10k/s on my machine).
> > >> > From the wiki pages for SHA1 (turns outs there exists a foreign so I 
> > >> > dropped it), HMAC, and PBKDF2I assembled:
> > >> > sha1=:1&(128!:6)
> > >> > bs=:512%8 NB. block size in bytes for md5, sha1, sha224, sha256
> > >> > opad=:bs(([,(#@]))$])0 1 0 1 1 1 0 0 NB. 0x5c, outer padding byte up 
> > >> > to block size
> > >> > ipad=:bs(([,(#@]))$])0 0 1 1 0 1 1 0 NB. 0x36, inner padding byte up 
> > >> > to block size
> > >> >
> > >> > hmac=:{{)a NB. assuming y of form 'key';'msg'
> > >> > if.bs&<@#key=.{.>y do.key=.u key end. NB. use hash of key as key, if 
> > >> > greater than block size
> > >> > key=.((],(((bs&-@#),8:)$0:))@((8:#2:)#:(a.&i.)))key NB. pad 0s to 
> > >> > right up to block size; do 8 bits of ascii
> > >> > u(({&a.@#.(key~:opad)),u(({&a.@#.(key~:ipad)),{:>y))
> > >> > }}
> > >> >
> > >> > sha1 hmac 'key';';msg'
> > >> > I am getting the wrong hashes back with examples from the wiki 
> > >> > examples, ones generated from https://cryptotools.net/hmac What 
> > >> > exactly am I missing?
> > >>
> > >> One issue (not the only issue) I think has to do with how you pad the 
> > >> key.
> > >>
> > >> If I understand https://en.wikipedia.org/wiki/HMAC correctly, this
> > >> will pad the key:
> > >>
> > >> padkey=: {{
> > >>  if.x < # y do. u y
> > >>  else. x{.y,x#{.a.
> > >>  end.
> > >> }}
> > >>
> > >> And,  I should expect that sha1 hmac (bs sha1 padkey 'key');';msg'
> > >> would have the same result as sha1 hmac 'key';';msg'
> > >>
> > >> I haven't looked any deeper than this, here.
> > >>
> > >> Good luck,
> > >>
> > >> --
> > >> Raul
> > >>
> > > ----------------------------------------------------------------------
> > > For information about J forums see http://www.jsoftware.com/forums.htm
> > >
> >
> > ----------------------------------------------------------------------
> > For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to