Urbit / Docs

3d: SHA hash family

++shad

Double SHA-256

Produces an atom that is twice-hashed with shax, the SHA-256 cryptographic hash algorithm.

Accepts

ruz is an atom.

Produces

An atom.

Source

    ++  shad  |=([email protected] (shax (shax ruz)))

Examples

    > (shad 11)
    \/20.519.637.820.582.103.109.435.907.615.585.653.479.776.629.591.855.451.248.\/
      718.295.626.625.655.417.234

*

++shaf

Half SHA-256

Produces a 128-bit atom by performing the bitwise XOR on the first and last halves of the 256-bit salted hash shas.

Accepts

sal is an atom.

ruz is an atom.

Source

    ++  shaf                                                ::  half sha-256
      |=  [[email protected] [email protected]]
      =+  haz=(shas sal ruz)
      (mix (end 7 1 haz) (rsh 7 1 haz))

Examples

    > (shaf 17 8)
    52.667.672.807.485.289.251.324.336.639.183.409.041

    > `@ub`(shaf 17 8)
    \/0b1011.1111.1101.0110.1110.1000.0100.1110.1100.1000.0010.0100.1111.0001.0010.0010\/
      .0100.1110.1110.0011.1100.1111.0001.1101.1101.1100.1110.1111.0100.0101.0001.0100
    \/

*

++shal

SHA-512 with length

Produces an atom by hashing an atom ruz with SHA-512. Another atom, len, is the byte-length of the theoretical buffer represented by the atom.

Accepts

len is an atom.

ruz is an atom.

Produces

An atom.

Source

    ++  shal
      ~/  %shal
      |=  [[email protected] [email protected]]  ^-  @
      =>  .(ruz (cut 3 [0 len] ruz))
      =+  [few==>(fe .(a 6)) wac=|=([[email protected] b/@] (cut 6 [a 1] b))]
      =+  [sum=sum.few ror=ror.few net=net.few inv=inv.few]
      =+  ral=(lsh 0 3 len)
      =+  ^=  ful
          %+  can  0
          :~  [ral ruz]
              [8 128]
              [(mod (sub 1.920 (mod (add 8 ral) 1.024)) 1.024) 0]
              [128 (~(net fe 7) ral)]
          ==
      =+  lex=(met 10 ful)
      =+  ^=  kbx  0x6c44.198c.4a47.5817.5fcb.6fab.3ad6.faec.
                     597f.299c.fc65.7e2a.4cc5.d4be.cb3e.42b6.
                     431d.67c4.9c10.0d4c.3c9e.be0a.15c9.bebc.
                     32ca.ab7b.40c7.2493.28db.77f5.2304.7d84.
                     1b71.0b35.131c.471b.113f.9804.bef9.0dae.
                     0a63.7dc5.a2c8.98a6.06f0.67aa.7217.6fba.
                     f57d.4f7f.ee6e.d178.eada.7dd6.cde0.eb1e.
                     d186.b8c7.21c0.c207.ca27.3ece.ea26.619c.
                     c671.78f2.e372.532b.bef9.a3f7.b2c6.7915.
                     a450.6ceb.de82.bde9.90be.fffa.2363.1e28.
                     8cc7.0208.1a64.39ec.84c8.7814.a1f0.ab72.
                     78a5.636f.4317.2f60.748f.82ee.5def.b2fc.
                     682e.6ff3.d6b2.b8a3.5b9c.ca4f.7763.e373.
                     4ed8.aa4a.e341.8acb.391c.0cb3.c5c9.5a63.
                     34b0.bcb5.e19b.48a8.2748.774c.df8e.eb99.
                     1e37.6c08.5141.ab53.19a4.c116.b8d2.d0c8.
                     106a.a070.32bb.d1b8.f40e.3585.5771.202a.
                     d699.0624.5565.a910.d192.e819.d6ef.5218.
                     c76c.51a3.0654.be30.c24b.8b70.d0f8.9791.
                     a81a.664b.bc42.3001.a2bf.e8a1.4cf1.0364.
                     9272.2c85.1482.353b.81c2.c92e.47ed.aee6.
                     766a.0abb.3c77.b2a8.650a.7354.8baf.63de.
                     5338.0d13.9d95.b3df.4d2c.6dfc.5ac4.2aed.
                     2e1b.2138.5c26.c926.27b7.0a85.46d2.2ffc.
                     1429.2967.0a0e.6e70.06ca.6351.e003.826f.
                     d5a7.9147.930a.a725.c6e0.0bf3.3da8.8fc2.
                     bf59.7fc7.beef.0ee4.b003.27c8.98fb.213f.
                     a831.c66d.2db4.3210.983e.5152.ee66.dfab.
                     76f9.88da.8311.53b5.5cb0.a9dc.bd41.fbd4.
                     4a74.84aa.6ea6.e483.2de9.2c6f.592b.0275.
                     240c.a1cc.77ac.9c65.0fc1.9dc6.8b8c.d5b5.
                     efbe.4786.384f.25e3.e49b.69c1.9ef1.4ad2.
                     c19b.f174.cf69.2694.9bdc.06a7.25c7.1235.
                     80de.b1fe.3b16.96b1.72be.5d74.f27b.896f.
                     550c.7dc3.d5ff.b4e2.2431.85be.4ee4.b28c.
                     1283.5b01.4570.6fbe.d807.aa98.a303.0242.
                     ab1c.5ed5.da6d.8118.923f.82a4.af19.4f9b.
                     59f1.11f1.b605.d019.3956.c25b.f348.b538.
                     e9b5.dba5.8189.dbbc.b5c0.fbcf.ec4d.3b2f.
                     7137.4491.23ef.65cd.428a.2f98.d728.ae22
      =+  ^=  hax  0x5be0.cd19.137e.2179.1f83.d9ab.fb41.bd6b.
                     9b05.688c.2b3e.6c1f.510e.527f.ade6.82d1.
                     a54f.f53a.5f1d.36f1.3c6e.f372.fe94.f82b.
                     bb67.ae85.84ca.a73b.6a09.e667.f3bc.c908
      =+  i=0
      |-  ^-  @
      ?:  =(i lex)
        (rep 6 (turn (rip 6 hax) net))
      =+  ^=  wox
          =+  dux=(cut 10 [i 1] ful)
          =+  wox=(rep 6 (turn (rip 6 dux) net))
          =+  j=16
          |-  ^-  @
          ?:  =(80 j)
            wox
          =+  :*  l=(wac (sub j 15) wox)
                  m=(wac (sub j 2) wox)
                  n=(wac (sub j 16) wox)
                  o=(wac (sub j 7) wox)
              ==
          =+  x=:(mix (ror 0 1 l) (ror 0 8 l) (rsh 0 7 l))
          =+  y=:(mix (ror 0 19 m) (ror 0 61 m) (rsh 0 6 m))
          =+  z=:(sum n x o y)
          $(wox (con (lsh 6 j z) wox), j +(j))
      =+  j=0
      =+  :*  a=(wac 0 hax)
              b=(wac 1 hax)
              c=(wac 2 hax)
              d=(wac 3 hax)
              e=(wac 4 hax)
              f=(wac 5 hax)
              g=(wac 6 hax)
              h=(wac 7 hax)
          ==
      |-  ^-  @
      ?:  =(80 j)
        %=  ^$
          i  +(i)
          hax  %+  rep  6
               :~  (sum a (wac 0 hax))
                   (sum b (wac 1 hax))
                   (sum c (wac 2 hax))
                   (sum d (wac 3 hax))
                   (sum e (wac 4 hax))
                   (sum f (wac 5 hax))
                   (sum g (wac 6 hax))
                   (sum h (wac 7 hax))
               ==
        ==
      =+  l=:(mix (ror 0 28 a) (ror 0 34 a) (ror 0 39 a))   ::  S0
      =+  m=:(mix (dis a b) (dis a c) (dis b c))            ::  maj
      =+  n=(sum l m)                                       ::  t2
      =+  o=:(mix (ror 0 14 e) (ror 0 18 e) (ror 0 41 e))   ::  S1
      =+  p=(mix (dis e f) (dis (inv e) g))                 ::  ch
      =+  q=:(sum h o p (wac j kbx) (wac j wox))            ::  t1
      $(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)

Examples

    > (shal 1 'hello')
    \/7.956.615.373.791.575.273.027.009.123.631.914.645.972.441.264.528.176.292.399.908\/
      .424.469.676.078.106.561.839.264.176.650.109.335.825.608.088.511.266.620.100.157.
      847.055.280.028.606.252.747.432.021.213.474
    \/

    > (shal 1 'hello')
    \/7.956.615.373.791.575.273.027.009.123.631.914.645.972.441.264.528.176.292.399.908\/
      .424.469.676.078.106.561.839.264.176.650.109.335.825.608.088.511.266.620.100.157.
      847.055.280.028.606.252.747.432.021.213.474
    \/

Discussion

Because byte-strings can have leading zeros, but atoms cannot, we use len as a way of saying that the atom ruz is shorter than its representative byte-string.

*

++sham

128-bit noun hash

Produces a 128-bit atom by hashing a noun yux with the shah function. If that noun is a cell, then it is passed to the jam function to produce an atom to be hashed.

Accepts

yux is a noun.

Produces

An atom.

Source

    ++  sham
      |=  yux=*  ^-  @uvH  ^-  @
      [email protected]  yux
        (shaf %mash yux)
      (shaf %sham (jam yux))
    ::

Examples

    > (sham [2 4])
    0v3.71s52.4bqnp.ki2b8.9hhsp.2ufgg

    > (sham "hello")
    0v1.hg8mv.t7s3f.u4f8a.q5noe.dvqvh

*

++shan

SHA-1

Produces an atom by hashing an atom ruz with SHA-1.

Accepts

ruz is an atom.

Produces

An atom.

Source

    ++  shan
      |=  [email protected]
      =+  [few==>(fe .(a 5)) wac=|=([[email protected] [email protected]] (cut 5 [a 1] b))]
      =+  [sum=sum.few ror=ror.few rol=rol.few net=net.few inv=inv.few]
      =+  ral=(lsh 0 3 (met 3 ruz))
      =+  ^=  ful
          %+  can  0
          :~  [ral ruz]
              [8 128]
              [(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
              [64 (~(net fe 6) ral)]
          ==
      =+  lex=(met 9 ful)
      =+  kbx=0xca62.c1d6.8f1b.bcdc.6ed9.eba1.5a82.7999
      =+  hax=0xc3d2.e1f0.1032.5476.98ba.dcfe.efcd.ab89.6745.2301
      =+  i=0
      |-
      ?:  =(i lex)
        (rep 5 (flop (rip 5 hax)))
      =+  ^=  wox
          =+  dux=(cut 9 [i 1] ful)
          =+  wox=(rep 5 (turn (rip 5 dux) net))
          =+  j=16
          |-  ^-  @
          ?:  =(80 j)
            wox
          =+  :*  l=(wac (sub j 3) wox)
                  m=(wac (sub j 8) wox)
                  n=(wac (sub j 14) wox)
                  o=(wac (sub j 16) wox)
              ==
          =+  z=(rol 0 1 :(mix l m n o))
          $(wox (con (lsh 5 j z) wox), j +(j))
      =+  j=0
      =+  :*  a=(wac 0 hax)
              b=(wac 1 hax)
              c=(wac 2 hax)
              d=(wac 3 hax)
              e=(wac 4 hax)
          ==
      |-  ^-  @
      ?:  =(80 j)
        %=  ^$
          i  +(i)
          hax  %+  rep  5
               :~
                   (sum a (wac 0 hax))
                   (sum b (wac 1 hax))
                   (sum c (wac 2 hax))
                   (sum d (wac 3 hax))
                   (sum e (wac 4 hax))
               ==
        ==
      =+  fx=(con (dis b c) (dis (not 5 1 b) d))
      =+  fy=:(mix b c d)
      =+  fz=:(con (dis b c) (dis b d) (dis c d))
      =+  ^=  tem
          ?:  &((gte j 0) (lte j 19))
            :(sum (rol 0 5 a) fx e (wac 0 kbx) (wac j wox))
          ?:  &((gte j 20) (lte j 39))
            :(sum (rol 0 5 a) fy e (wac 1 kbx) (wac j wox))
          ?:  &((gte j 40) (lte j 59))
            :(sum (rol 0 5 a) fz e (wac 2 kbx) (wac j wox))
          :(sum (rol 0 5 a) fy e (wac 3 kbx) (wac j wox))
      $(j +(j), a tem, b a, c (rol 0 30 b), d c, e d)

Examples

    > (shan 'hello')
    975.987.071.262.755.080.377.722.350.727.279.193.143.145.743.181

Discussion

SHA-1 is a deprecated function; it is not considered secure.

*

++shas

Salted hash

Produces an atom by using SHA-256 plus a salt input. The bitwise XOR is performed on sal and the product of ruz hashed with SHA-256. The product of that logical operation is then itself hashed with SHA-256.

Accepts

sal is an atom.

ruz is an atom.

Source

    ++  shas
      |=  [[email protected] [email protected]]
      (shax (mix sal (shax ruz)))

Examples

    > (shas 12.845 6)
    \/111.115.941.493.032.291.043.932.789.632.248.509.108.945.255.494.251.860.287\/
      .707.279.709.200.349.471.936
    \/

*

++shaw

Hash to nbits

Produces an atom of len random bits by hashing ruz with the salted SHA-256 hash algorithm, where sal is the cryptographic salt.

Accepts

sal is an atom.

len is an atom.

ruz is an atom.

Produces

An atom.

Source

    ++  shaw
      |=  [[email protected] [email protected] [email protected]]
      (~(raw og (shas sal (mix len ruz))) len)

Examples

    > `@ub`(shaw 3 6 98)
    0b11.0111

    > `@ub`(shaw 2 6 98)
    0b11

*

++shax

SHA-256

Produces an atom by hashing an atom ruz with SHA-256.

Sources

    ++  shax
          ~/  %shax
          |=  [email protected]  ^-  @
          (shay [(met 3 ruz) ruz])

Examples

    > (shax 'hello')
    \/16.552.786.619.039.860.277.601.417.878.457.384.195.409.020.923.835.016.617.984.82\/
      0.774.431.701.725.740
    \/

*

++shay

SHA-256 with length

Produces an atom by hashing an atom ruz with SHA-512. Another atom, len, is the byte-length of the theoretical buffer represented by the atom.

Accepts

len is an atom.

ruz is an atom.

Source

    ++  shay
      ~/  %shay
      |=  [[email protected] [email protected]]  ^-  @
      =>  .(ruz (cut 3 [0 len] ruz))
      =+  [few==>(fe .(a 5)) wac=|=([[email protected] [email protected]] (cut 5 [a 1] b))]
      =+  [sum=sum.few ror=ror.few net=net.few inv=inv.few]
      =+  ral=(lsh 0 3 len)
      =+  ^=  ful
          %+  can  0
          :~  [ral ruz]
              [8 128]
              [(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
              [64 (~(net fe 6) ral)]
          ==
      =+  lex=(met 9 ful)
      =+  ^=  kbx  0xc671.78f2.bef9.a3f7.a450.6ceb.90be.fffa.
                     8cc7.0208.84c8.7814.78a5.636f.748f.82ee.
                     682e.6ff3.5b9c.ca4f.4ed8.aa4a.391c.0cb3.
                     34b0.bcb5.2748.774c.1e37.6c08.19a4.c116.
                     106a.a070.f40e.3585.d699.0624.d192.e819.
                     c76c.51a3.c24b.8b70.a81a.664b.a2bf.e8a1.
                     9272.2c85.81c2.c92e.766a.0abb.650a.7354.
                     5338.0d13.4d2c.6dfc.2e1b.2138.27b7.0a85.
                     1429.2967.06ca.6351.d5a7.9147.c6e0.0bf3.
                     bf59.7fc7.b003.27c8.a831.c66d.983e.5152.
                     76f9.88da.5cb0.a9dc.4a74.84aa.2de9.2c6f.
                     240c.a1cc.0fc1.9dc6.efbe.4786.e49b.69c1.
                     c19b.f174.9bdc.06a7.80de.b1fe.72be.5d74.
                     550c.7dc3.2431.85be.1283.5b01.d807.aa98.
                     ab1c.5ed5.923f.82a4.59f1.11f1.3956.c25b.
                     e9b5.dba5.b5c0.fbcf.7137.4491.428a.2f98
      =+  ^=  hax  0x5be0.cd19.1f83.d9ab.9b05.688c.510e.527f.
                     a54f.f53a.3c6e.f372.bb67.ae85.6a09.e667
      =+  i=0
      |-  ^-  @
      ?:  =(i lex)
        (rep 5 (turn (rip 5 hax) net))
      =+  ^=  wox
          =+  dux=(cut 9 [i 1] ful)
          =+  wox=(rep 5 (turn (rip 5 dux) net))
          =+  j=16
          |-  ^-  @
          ?:  =(64 j)
            wox
          =+  :*  l=(wac (sub j 15) wox)
                  m=(wac (sub j 2) wox)
                  n=(wac (sub j 16) wox)
                  o=(wac (sub j 7) wox)
              ==
          =+  x=:(mix (ror 0 7 l) (ror 0 18 l) (rsh 0 3 l))
          =+  y=:(mix (ror 0 17 m) (ror 0 19 m) (rsh 0 10 m))
          =+  z=:(sum n x o y)
          $(wox (con (lsh 5 j z) wox), j +(j))
      =+  j=0
      =+  :*  a=(wac 0 hax)
              b=(wac 1 hax)
              c=(wac 2 hax)
              d=(wac 3 hax)
              e=(wac 4 hax)
              f=(wac 5 hax)
              g=(wac 6 hax)
              h=(wac 7 hax)
          ==
      |-  ^-  @
      ?:  =(64 j)
        %=  ^$
          i  +(i)
          hax  %+  rep  5
               :~  (sum a (wac 0 hax))
                   (sum b (wac 1 hax))
                   (sum c (wac 2 hax))
                   (sum d (wac 3 hax))
                   (sum e (wac 4 hax))
                   (sum f (wac 5 hax))
                   (sum g (wac 6 hax))
                   (sum h (wac 7 hax))
               ==
        ==
      =+  l=:(mix (ror 0 2 a) (ror 0 13 a) (ror 0 22 a))    ::  s0
      =+  m=:(mix (dis a b) (dis a c) (dis b c))            ::  maj
      =+  n=(sum l m)                                       ::  t2
      =+  o=:(mix (ror 0 6 e) (ror 0 11 e) (ror 0 25 e))    ::  s1
      =+  p=(mix (dis e f) (dis (inv e) g))                 ::  ch
      =+  q=:(sum h o p (wac j kbx) (wac j wox))            ::  t1
      $(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)

Examples

    > (shay 1 'hello')
    \/16.144.219.278.061.159.438.339.586.294.967.166.038.336.988.797.862.808.055.174.98\/
    7.398.597.302.069.674
    \/

    > (shay 2 'hello')
    \/100.467.333.538.737.303.691.714.735.404.408.035.555.613.179.595.938.688.113.300.8\/
      01.974.878.934.544.183
    \/

Discussion

Because byte-strings can have leading zeros, but atoms cannot, we use len as a way of saying that the atom ruz is shorter than its representative byte-string.

*

++shaz

SHA-512

Produces an atom by hashing an atom ruz with SHA-512.

Accepts

ruz is an atom.

Produces

An atom.

Source

    ++  shaz
      |=  [email protected]  ^-  @
      (shal [(met 3 ruz) ruz])

Examples

    > (shaz 'hello')
    \/3.548.533.422.469.437.734.729.094.584.175.910.682.076.656.883.559.953.324.378.007\/
      .735.849.386.038.666.450.748.109.671.344.747.196.048.200.348.948.408.339.256.384.
      360.070.359.656.053.016.948.640.159.265.179
    \/

*

++og

Container arm for SHA-256-powered random-number generation. Its sample a is an atom that is used as a seed for the hash.

Accepts

a is an atom.

Produces

A core.

Source

    ++  og
      ~/  %og
      |_  [email protected]

Examples

    > ~(. og 919)
    <4.wmp {a/@ud <54.tyv 119.olq 31.ohr 1.jmk $143>}>

Discussion

Note that the product is deterministic; the seed will produce the same result every time it is run. Use eny, 256 bits of entropy, for a non-deterministic product.

*

++rad

Random in range

Produces a random number that is within the range of first b whole numbers, starting at 0.

Accepts

b is an atom.

Produces

An atom.

Source

      ++  rad
        |=  [email protected]  ^-  @
        =+  c=(raw (met 0 b))
        ?:((lth c b) c $(a +(a)))

Examples

    > (~(rad og 5) 11)
    4

    > (~(rad og 758.716.593) 11)
    2

    > (~(rad og 1) 100.000)
    71.499

    > (~(rad og eny) 11)                         ::  `eny` acts as a random sample
    7

*

++rads

Random continuation

Produces a cell. The head of the cell is a random number that is within the range of first b whole numbers, starting at 0. The tail is a new core produced from hashing the parent core with (rad b).

Accepts

b is an atom.

Produces

A cell.

Source

      ++  rads
        |=  [email protected]
        =+  r=(rad b)
        [r +>.$(a (shas %og-s (mix a r)))]

Examples

    > (~(rads og 4) 10)
    [2 <4.wmp {a/@ <54.tyv 119.olq 31.ohr 1.jmk $143>}>]

    > =/  rng  ~(. og 7)
        =^  a  rng  (rads:rng 10)
        =^  b  rng  (rads:rng 10)
        [a b]
    [2 8]

Discussion

Since everything in Hoon is a pure function, we need to use tricks like this to generate separate random values from the same seed. Notice how we jump from one rads function call to another in the above example.

*

++raw

Random bits

Produces an atom with a bitwidth b that is composed of random bits.

Accepts

b is an atom.

Produces

An atom.

Source

      ++ raw
        ~/  %raw
        |=  [email protected]  ^-  @
        %+  can
          0
        =+  c=(shas %og-a (mix b a))
        |-  ^-  (list [@ @])
        ?:  =(0 b)
          ~
        =+  d=(shas %og-b (mix b (mix a c)))
        ?:  (lth b 256)
          [[b (end 0 b d)] ~]
        [[256 d] $(c d, b (sub b 256))]

Examples

    > `@ud`(~(raw og 27) 4)
    0b1001

    > `@ub`(~(raw og 27) 3)
    0b0

    > `@ub`(~(raw og 11) 4)
    0b1111

    > `@ub`(~(raw og 11) 3)
    0b100

*

++raws

Random bits continuation

Produces a cell. The head of the cell is an atom with a bitwidth b that is composed of random bits. The tail is a new core produced from hashing the parent core with (raw b).

Source

      ++  raws
        |=  [email protected]
        =+  r=(raw b)
        [r +>.$(a (shas %og-s r))]
      --

Examples

    > `[@ub _og]`(~(raws og 7) 4)
    [0b1100 <4.wmp {a/@ <54.tyv 119.olq 31.ohr 1.jmk $143>}>]

    > =/  rng  ~(. og 7)
              =^  a  rng  (rads:rng 4)
              =^  b  rng  (rads:rng 4)
              [`@ub`a `@ub`b]
    [0b10 0b1]

Discussion

Since everything in Hoon is a pure function, we need to use tricks like this to generate separate random values from the same seed. Notice how we jump from one raws function call to another in the above example.

*