2e: Insecure Hashing

    ++fnv

    FNV scrambler

    Hashes an atom with the 32-bit FNV non-cryptographic hash algorithm. Multiplies a by the prime number 16,777,619 and then takes the block of size 5 off the product's end, producing an atom.

    Accepts

    a is an atom.

    Produces

    An atom.

    Source

        ++  fnv  |=(a=@ (end 5 1 (mul 16.777.619 a)))
    

    Examples

        > (fnv 10.000)
        272.465.456
    
        > (fnv 10.001)
        289.243.075
    
        > (fnv 1)
        16.777.619
    

    ++mug

    FNV-1a scrambler

    Hashes a with the 31-bit nonzero FNV-1a non-cryptographic hash algorithm, producing an atom.

    Accepts

    a is a noun.

    Produces

    An atom.

    Source

        ++  mug
          ~/  %mug
          |=  a=*
          ?^  a
            =+  b=[p=$(a -.a) q=$(a +.a)]
            |-  ^-  @
            =+  c=(fnv (mix p.b (fnv q.b)))
            =+  d=(mix (rsh 0 31 c) (end 0 31 c))
            ?.  =(0 d)  d
            $(q.b +(q.b))
          =+  b=2.166.136.261
          |-  ^-  @
          =+  c=b
          =+  [d=0 e=(met 3 a)]
          |-  ^-  @
          ?:  =(d e)
            =+  f=(mix (rsh 0 31 c) (end 0 31 c))
            ?.  =(0 f)  f
            ^$(b +(b))
          $(c (fnv (mix c (cut 3 [d 1] a))), d +(d))
    

    Examples

        > (mug 10.000)
        178.152.889
    
        > (mug 10.001)
        714.838.017
    
        > (mug 1)
        67.918.732
    
        > (mug (some 10))
        1.872.403.737
    
        > (mug [1 2 3 4 5 ~])
        1.067.931.605
    

    ++muk

    Standard MurmurHash3

    Implementation of the 32-bit MurmurHash3 non-cryptographic hash algorithm. Takes a as the seed, b as the key length in blocks of size 3, and c as the key, producing an atom.

    Accepts

    a is an atom.

    b is an atom.

    c is an atom.

    Produces

    An atom.

    Source

        ++  muk
          ~%  %muk  ..muk  ~
          =+  ~(. fe 5)
          |=  [syd=@ len=@ key=@]
          ?>  &((lte (met 5 syd) 1) (lte (met 0 len) 31))
          =/  pad      (sub len (met 3 key))
          =/  data     (weld (rip 3 key) (reap pad 0))
          =/  nblocks  (div len 4)                             ::  intentionally off-by-one
          =/  h1  syd
          =+  [c1=0xcc9e.2d51 c2=0x1b87.3593]
          =/  blocks  (rip 5 key)
          =/  i  nblocks
          =.  h1  =/  hi  h1  |-
            ?:  =(0 i)  hi                                     ::  negative array index
            =/  k1  (snag (sub nblocks i) blocks)
            =.  k1  (sit (mul k1 c1))
            =.  k1  (rol 0 15 k1)
            =.  k1  (sit (mul k1 c2))
            =.  hi  (mix hi k1)
            =.  hi  (rol 0 13 hi)
            =.  hi  (sum (sit (mul hi 5)) 0xe654.6b64)
            $(i (dec i))
          =/  tail  (slag (mul 4 nblocks) data)
          =/  k1    0
          =/  tlen  (dis len 3)
          =.  h1
            ?+  tlen  h1                                       ::  fallthrough switch
              $3  =.  k1  (mix k1 (lsh 0 16 (snag 2 tail)))
                  =.  k1  (mix k1 (lsh 0 8 (snag 1 tail)))
                  =.  k1  (mix k1 (snag 0 tail))
                  =.  k1  (sit (mul k1 c1))
                  =.  k1  (rol 0 15 k1)
                  =.  k1  (sit (mul k1 c2))
                  (mix h1 k1)
              $2  =.  k1  (mix k1 (lsh 0 8 (snag 1 tail)))
                  =.  k1  (mix k1 (snag 0 tail))
                  =.  k1  (sit (mul k1 c1))
                  =.  k1  (rol 0 15 k1)
                  =.  k1  (sit (mul k1 c2))
                  (mix h1 k1)
              $1  =.  k1  (mix k1 (snag 0 tail))
                  =.  k1  (sit (mul k1 c1))
                  =.  k1  (rol 0 15 k1)
                  =.  k1  (sit (mul k1 c2))
                  (mix h1 k1)
            ==
          =.  h1  (mix h1 len)
          |^  (fmix32 h1)
          ++  fmix32
            |=  h=@
            =.  h  (mix h (rsh 0 16 h))
            =.  h  (sit (mul h 0x85eb.ca6b))
            =.  h  (mix h (rsh 0 13 h))
            =.  h  (sit (mul h 0xc2b2.ae35))
            =.  h  (mix h (rsh 0 16 h))
            h
          --
    

    Examples

        > (muk 6 1 3)
        3.427.677.118
    
        > (muk 6 2 'jerry')
        ! exit
    
        > (muk 6 2 'je')
        3.602.081.716
    
        > (met 3 'jerry')
        5
    
        > (met 3 'je')
        2
    
        > (muk 6 5 'jerry')
        1.276.447.489
    
        > (muk 6 15 'jerry')
        2.881.503.571
    
        > =e (cut 3 [0 2] eny)                            :: `eny` is 512 bits of entropy (a random number).
        > e
        44.228
    
        > (muk e 11 10.000)
        246.077.549
    

    ++mum

    31-bit MurmurHash3 scrambler

    Hashes a with the 31-bit MurmurHash3 non-cryptographic hash algorithm, producing an atom.

    Accepts

    a is a noun.

    Produces

    An atom.

    Source

        ++  mum
          ~/  %mum
          |=  a=*
          |^  (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
          ++  trim
            |=  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)))
    

    Examples

        > (mum 10.000)
        795.713.195
    
        > (mum 10.001)
        420.521.697
    
        > (mum 'jerry')
        1.540.161.753
    
        > (mum 1)
        1.901.865.568
    
        > (mum (some 10))
        2.099.076.946
    
        > (mum [1 2 3 4 5 ~])
        1.719.833.228