For what it's worth, here's an hmac with a more production-oriented design:
hmac=: {{ NB. https://en.wikipedia.org/wiki/HMAC
NB. u: hash function (on literal sequence)
NB. n: block size for hash
if. 0=#(u'')-.,hfd i.16 do.
v=. a. {~ _2 dfh\ u
else.
v=. u
end.{{
NB. m: key (literal sequence)
NB. y: value (literal sequence)
bs=. [email protected]''
u=. [email protected]
v=. [email protected]
k=. bs (] , ({.a.) #~ 0 >. (- #)) v^:(bs<#m) m
assert. bs-:#k
okey=. k 22 b.&.(a.&i.) bs#'\' NB. 0x5c
ikey=. k 22 b.&.(a.&i.) bs#'6' NB. 0x36
[: u okey, [: v ikey, ]
}} (n"_`u`v)
}}
Example use:
'key' 128!:6 hmac 64 ';msg'
8933faa484de1517ea205ace40f9af46aebd9658
Here, I have discarded the concept of a default block size. In return,
this version pre-calculates first the raw version of the hash, and
then the key material. So 128!:6 hmac 64 is an adverb (which is
waiting for a key), and 'key' 128!:6 hmac 64 is a verb (waiting for
the value to be hashed).
I have also made some very minor concessions to allow my comments to
be somewhat comprehensible. (And, I am limiting myself to u and v for
local verb names to work around an unfortunate limitation in the
current handling of local verb names in results from adverbs and
conjunctions.)
FYI,
--
Raul
On Wed, Feb 2, 2022 at 12:19 PM Raul Miller <[email protected]> wrote:
>
> Hmm...
>
> https://wiki.jsoftware.com/wiki/Guides/UnicodeGettingStarted mentions
> hfd and dfh.
>
> At one point, dfh and hfd were part of the 'convert' addon. This has
> since been incorporated into the base library (and require'convert'
> succeeds, for backwards compatibility purposes, but does nothing).
>
> We definitely need to do a better job of documenting the base library
> (and, probably, we will need to be doing a good job, in the future, of
> maintaining its interfaces -- it's all too easy to drop something
> people found useful, thinking that it was unnecessary).
>
> As for the arbitrary base constants -- that's not quite as arbitrary
> as one might like. The digits are limited to base 36, and the result
> is limited to the implementation's integer and floating point
> representations.
>
> The numeric constant language is documented at
> https://www.jsoftware.com/help/dictionary/dcons.htm and the numeric
> type hierarchy is documented at
> https://www.jsoftware.com/help/dictionary/dictg.htm (it's designed to
> favor fixed precision results, for efficiency reasons).
>
> So if you try something like
>
> 1000bhello
> 17014021021024
>
> you get a fixed precision integer result. But if you try something like
>
> 1000bhellothere
> 1.7014e28
>
> fixed precision integers get "promoted" to a floating point
> representation, when the values would overflow that integer
> representation.
>
> Did this answer your questions?
>
> Thanks,
>
> --
> Raul
>
> On Wed, Feb 2, 2022 at 11:32 AM 'Viktor Grigorov' via Programming
> <[email protected]> wrote:
> >
> > Thank you for that, I see the issues in my attempt.
> >
> > Two comments perhaps more pertinent to the people attempting to revitalize
> > the wiki: how is one to know:
> > - that arbitrary(?) base numberal to decimal exist, matching the regex
> > '\d+b_?\w+'?
> > - how is one to know of the existence of hdf/dfh?---I didn't even know
> > there was a standard library. The jhelp and jwiki zips have '\b(hfd|dfh)\b'
> > mentioned a total of 12 times, and not on commonly visited pages (I would
> > think).
> >
> >
> > Feb 2, 2022, 18:18 by [email protected]:
> >
> > > 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
> > >
> >
> > ----------------------------------------------------------------------
> > For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm