Merge branch 'jb/re-mug-pre' into jb/candidate

* jb/re-mug-pre:
  arvo: temporary, build +brass out of /not-sys
  hoon: switches to new +mug
  u3: adds new +mug (as u3r_gum_*)
  hoon: adds new +mug (as +gum)
  u3: updates +muk to truncate seed and removes spurious assertion
  hoon: updates +muk to truncate seed and removes spurious assertion
This commit is contained in:
Joe Bryan 2020-11-26 01:20:28 -08:00
commit 76451b54a3
7 changed files with 237 additions and 67 deletions

View File

@ -160,7 +160,7 @@
::
:: compiler-source: hoon source file producing compiler, `sys/hoon`
::
=+ compiler-source=.^(@t %cx (welp sys /hoon/hoon))
=+ compiler-source=.^(@t %cx /(scot %p p.bec)/[q.bec]/(scot %da now)/not-sys/hoon/hoon)
::
:: compiler-twig: compiler as hoon expression
::

View File

@ -1030,8 +1030,8 @@
++ muk :: standard murmur3
~% %muk ..muk ~
=+ ~(. fe 5)
|= {syd/@ len/@ key/@}
?> &((lte (met 5 syd) 1) (lte (met 0 len) 31))
|= [syd=@ len=@ key=@]
=. syd (end 5 1 syd)
=/ pad (sub len (met 3 key))
=/ data (weld (rip 3 key) (reap pad 0))
=/ nblocks (div len 4) :: intentionally off-by-one
@ -1087,15 +1087,20 @@
::
++ mug :: mug with murmur3
~/ %mug
|= a/*
|^ (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
++ trim :: 31-bit nonzero
|= key/@
=+ syd=0xcafe.babe
|- ^- @
=+ haz=(muk syd (met 3 key) key)
=+ ham=(mix (rsh 0 31 haz) (end 0 31 haz))
?.(=(0 ham) ham $(syd +(syd)))
|= a=*
|^ ?@ a (mum 0xcafe.babe 0x7fff a)
=/ b (cat 5 $(a -.a) $(a +.a))
(mum 0xdead.beef 0xfffe b)
::
++ mum
|= [syd=@uxF fal=@F key=@]
=/ wyd (met 3 key)
=| i=@ud
|- ^- @F
?: =(8 i) fal
=/ haz=@F (muk syd wyd key)
=/ ham=@F (mix (rsh 0 31 haz) (end 0 31 haz))
?.(=(0 ham) ham $(i +(i), syd +(syd)))
--
:: ::
:::: 2f: noun ordering ::

View File

@ -33,26 +33,39 @@
!> 0x79ff.04e8
!> (mug 0)
::
%+ expect-eq
!> 0x715c.2a60
!> (mug 1)
::
%+ expect-eq
!> 0x64df.da5c
!> (mug (crip (reap 28 'x')))
::
%+ expect-eq
!> 0x389c.a03a
!> 0x192f.5588
!> (mug [0 0])
::
%+ expect-eq
!> 0x389c.a03a
!> 0x6b32.ec46
!> (mug [1 1])
::
%+ expect-eq
!> 0x5258.a6c0
!> 0x2ef.fe10
!> (mug [2 2])
::
%+ expect-eq
!> 0x3a81.1aec
!> (mug [1 2 3])
::
%+ expect-eq
!> 0x7ce.fb7f
!> (mug [0 (bex 32)])
::
%+ expect-eq
!> 0x2ad3.9968
!> 0x2aa0.6bfc
!> (mug [(dec (bex 128)) 1])
==
::
:: SHA tests
:: For references see FIPS180-4 and related test vectors
:: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

View File

@ -34,6 +34,22 @@
c3_o
u3r_mean(u3_noun a, ...);
/* u3r_gum_both(): Join two mugs.
*/
c3_l
u3r_gum_both(c3_l lef_l, c3_l rit_l);
/* u3r_gum_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_l
u3r_gum_bytes(const c3_y *buf_y,
c3_w len_w);
/* u3r_gum_c(): Compute the mug of `a`, LSB first.
*/
c3_l
u3r_gum_c(const c3_c* a_c);
/* u3r_mug_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_w

View File

@ -7,76 +7,70 @@
/* functions
*/
u3_noun
u3qc_muk(u3_atom seed,
u3qc_muk(u3_atom sed,
u3_atom len,
u3_atom key)
{
c3_w key_w = u3r_met(3, key);
// XX revisit
//
// the first two conditions are explicitly asserted in +muk;
// the third is implicit in the pad subtraction.
//
// the first assertion is semantically required for murmur32,
// the latter two are particular to our hoon implementation.
//
// +muk (via +mug) is routinely "called" on samples that
// violate these assertions.
// are all three necessary for the rest of +muk to be correct?
//
if ( (u3r_met(5, seed) > 1) ||
(u3r_met(0, len) > 31) ||
(key_w > len) )
{
return u3m_bail(c3__exit);
if ( c3n == u3a_is_cat(len) ) {
return u3m_bail(c3__fail);
}
else {
c3_w seed_w = u3r_word(0, seed);
c3_w len_w = u3r_word(0, len);
c3_o loc_o = c3n;
c3_y* key_y = 0;
c3_w out_w;
c3_w len_w = (c3_w)len;
c3_w key_w = u3r_met(3, key);
// if we're hashing more bytes than we have, allocate and copy
// to ensure trailing null bytes
// NB: this condition is implicit in the pad subtraction
//
if ( len_w > key_w ) {
loc_o = c3y;
key_y = u3a_calloc(sizeof(c3_y), len_w);
u3r_bytes(0, len_w, key_y, key);
if ( key_w > len_w ) {
return u3m_bail(c3__exit);
}
else if ( len_w > 0 ) {
key_y = ( c3y == u3a_is_cat(key) )
? (c3_y*)&key
: (c3_y*)((u3a_atom*)u3a_to_ptr(key))->buf_w;
else {
c3_w sed_w = u3r_word(0, sed);
c3_o loc_o = c3n;
c3_y* key_y = 0;
c3_w out_w;
// if we're hashing more bytes than we have, allocate and copy
// to ensure trailing null bytes
//
if ( len_w > key_w ) {
loc_o = c3y;
key_y = u3a_calloc(sizeof(c3_y), len_w);
u3r_bytes(0, len_w, key_y, key);
}
else if ( len_w > 0 ) {
// XX assumes little-endian
//
key_y = ( c3y == u3a_is_cat(key) )
? (c3_y*)&key
: (c3_y*)((u3a_atom*)u3a_to_ptr(key))->buf_w;
}
MurmurHash3_x86_32(key_y, len_w, sed_w, &out_w);
if ( c3y == loc_o ) {
u3a_free(key_y);
}
return u3i_words(1, &out_w);
}
MurmurHash3_x86_32(key_y, len_w, seed_w, &out_w);
if ( c3y == loc_o ) {
u3a_free(key_y);
}
return u3i_words(1, &out_w);
}
}
u3_noun
u3wc_muk(u3_noun cor)
{
u3_noun seed, len, key;
u3_noun sed, len, key;
u3x_mean(cor, u3x_sam_2, &sed,
u3x_sam_6, &len,
u3x_sam_7, &key, 0);
if ( (c3n == u3r_mean(cor, u3x_sam_2, &seed,
u3x_sam_6, &len,
u3x_sam_7, &key, 0)) ||
(c3n == u3ud(seed)) ||
(c3n == u3ud(len)) ||
(c3n == u3ud(key)) )
if ( (c3n == u3ud(sed))
|| (c3n == u3ud(len))
|| (c3n == u3ud(key)) )
{
return u3m_bail(c3__exit);
}
else {
return u3qc_muk(seed, len, key);
return u3qc_muk(sed, len, key);
}
}

View File

@ -1479,6 +1479,78 @@ u3r_tape(u3_noun a)
return a_y;
}
/* u3r_gum_both(): Join two mugs.
*/
c3_l
u3r_gum_both(c3_l lef_l, c3_l rit_l)
{
c3_y len_y = 4 + ((c3_bits_word(rit_l) + 0x7) >> 3);
c3_w syd_w = 0xdeadbeef;
c3_w i_w = 0;
c3_y buf_y[8];
buf_y[0] = lef_l & 0xff;
buf_y[1] = (lef_l >> 8) & 0xff;
buf_y[2] = (lef_l >> 16) & 0xff;
buf_y[3] = (lef_l >> 24) & 0xff;
buf_y[4] = rit_l & 0xff;
buf_y[5] = (rit_l >> 8) & 0xff;
buf_y[6] = (rit_l >> 16) & 0xff;
buf_y[7] = (rit_l >> 24) & 0xff;
while ( i_w < 8 ) {
c3_w haz_w;
c3_l ham_l;
MurmurHash3_x86_32(buf_y, len_y, syd_w, &haz_w);
ham_l = (haz_w >> 31) ^ (haz_w & 0x7fffffff);
if ( 0 == ham_l ) {
syd_w++; i_w++;
}
else {
return ham_l;
}
}
return 0xfffe;
}
/* u3r_gum_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_l
u3r_gum_bytes(const c3_y *buf_y,
c3_w len_w)
{
c3_w syd_w = 0xcafebabe;
c3_w i_w = 0;
while ( i_w < 8 ) {
c3_w haz_w;
c3_l ham_l;
MurmurHash3_x86_32(buf_y, len_w, syd_w, &haz_w);
ham_l = (haz_w >> 31) ^ (haz_w & 0x7fffffff);
if ( 0 == ham_l ) {
syd_w++; i_w++;
}
else {
return ham_l;
}
}
return 0x7fff;
}
/* u3r_gum_c(): Compute the mug of `a`, LSB first.
*/
c3_l
u3r_gum_c(const c3_c* a_c)
{
return u3r_gum_bytes((c3_y*)a_c, strlen(a_c));
}
/* u3r_mug_bytes(): Compute the mug of `buf`, `len`, LSW first.
*/
c3_w

View File

@ -192,6 +192,71 @@ _test_mug(void)
return ret_i;
}
/* _test_mug(): spot check u3r_mug hashes.
*/
static c3_i
_test_gum(void)
{
c3_i ret_i = 1;
if ( 0x4d441035 != u3r_gum_c("Hello, world!") ) {
fprintf(stderr, "fail (a)\r\n");
ret_i = 0;
}
if ( 0x79ff04e8 != u3r_mug_bytes(0, 0) ) {
fprintf(stderr, "fail (c)\r\n");
ret_i = 0;
}
{
c3_y byt_y[1] = {1};
if ( 0x715c2a60 != u3r_mug_bytes(byt_y, 1) ) {
fprintf(stderr, "fail (c)\r\n");
ret_i = 0;
}
byt_y[0] = 2;
if ( 0x718b9468 != u3r_mug_bytes(byt_y, 1) ) {
fprintf(stderr, "fail (c)\r\n");
ret_i = 0;
}
}
{
if ( 0x64dfda5c != u3r_gum_c("xxxxxxxxxxxxxxxxxxxxxxxxxxxx") ) {
fprintf(stderr, "fail (d)\r\n");
ret_i = 0;
}
}
// [0 0]
//
if ( 0x192f5588 != u3r_gum_both(0x79ff04e8, 0x79ff04e8) ) {
fprintf(stderr, "fail (e)\r\n");
ret_i = 0;
}
// [1 1]
//
if ( 0x6b32ec46 != u3r_gum_both(0x715c2a60, 0x715c2a60) ) {
fprintf(stderr, "fail (f)\r\n");
ret_i = 0;
}
// [2 2]
//
if ( 0x2effe10 != u3r_gum_both(0x718b9468, 0x718b9468) ) {
fprintf(stderr, "fail (f)\r\n");
ret_i = 0;
}
return ret_i;
}
/* main(): run all test cases.
*/
int
@ -204,6 +269,11 @@ main(int argc, char* argv[])
exit(1);
}
if ( !_test_gum() ) {
fprintf(stderr, "test_mug: failed\r\n");
exit(1);
}
// GC
//
u3m_grab(u3_none);