on master help sign in
Merge pull request #304 from urbit/rmariani-patch-28
8c6d41aJoshua Reagan
docs/hoon/library/3d.md+504−85
@@ -2,107 +2,90 @@
2navhome: /docs/
2navhome: /docs/
3---
3---
4
4
5−
6# 3d: SHA hash family
5# 3d: SHA hash family
7
6
8−### `++og`
7+### `++shad`
9−
10− ++ og :: shax-powered rng
11− ~/ %og
12− |_ a/@
13−
14−XX document
15−
16−### `++rad`
17−
18− ++ rad :: random in range
19− |= b/@ ^- @
20− =+ c=(raw (met 0 b))
21− ?:((lth c b) c $(a +(a)))
22− ::
23−
24−XX document
25
8
26−### `++rads`
9+Double SHA-256
27
10
28− ++ rads :: random continuation
11+Produces an atom that is twice-hashed with `shax`, the SHA-256 cryptographic
29− |= b/@
12+hash algorithm.
30− =+ r=(rad b)
31− [r +>.$(a (shas %og-s r))]
32
13
33−XX document
14+#### Accepts
34
15
35−### `++raw`
16+`ruz` is an atom.
36
17
37− ++ raw :: random bits
18+#### Produces
38− ~/ %raw
39− |= b/@ ^- @
40− %+ can
41− 0
42− =+ c=(shas %og-a (mix b a))
43− |- ^- (list [@ @])
44− ?: =(0 b)
45− ~
46− =+ d=(shas %og-b (mix b (mix a c)))
47− ?: (lth b 256)
48− [[b (end 0 b d)] ~]
49− [[256 d] $(c d, b (sub b 256))]
50
19
51−XX document
20+An atom.
52
21
53−### `++raws`
22+#### Source
54
23
55− ++ raws :: random bits continuation
24+ ++ shad |=(ruz=@ (shax (shax ruz)))
56− |= b/@
57− =+ r=(raw b)
58− [r +>.$(a (shas %og-s r))]
59− --
60
25
26+#### Examples
61
27
28+ > (shad 11)
29+ \/20.519.637.820.582.103.109.435.907.615.585.653.479.776.629.591.855.451.248.\/
30+ 718.295.626.625.655.417.234
62
31
63***
32***
64−### `++shad`
33+### `++shaf`
65−
66− ++ shad |=(ruz/@ (shax (shax ruz))) :: double sha-256
67
34
35+Half SHA-256
68
36
69−XX document
37+Produces a 128-bit atom by performing the [bitwise XOR](2d/..) on the
38+first and last halves of the 256-bit salted hash `shas`.
70
39
40+#### Accepts
71
41
42+`sal` is an atom.
72
43
73−***
44+`ruz` is an atom.
74−### `++shaf`
75
45
46+#### Source
76 ++ shaf :: half sha-256
47 ++ shaf :: half sha-256
77− |= [sal/@ ruz/@]
48+ |= [sal=@ ruz=@]
78 =+ haz=(shas sal ruz)
49 =+ haz=(shas sal ruz)
79 (mix (end 7 1 haz) (rsh 7 1 haz))
50 (mix (end 7 1 haz) (rsh 7 1 haz))
80 ::
51 ::
81
52
82−XX document
53+#### Examples
54+
55+ > (shaf 17 8)
56+ 52.667.672.807.485.289.251.324.336.639.183.409.041
83
57
58+ > `@ub`(shaf 17 8)
59+ \/0b1011.1111.1101.0110.1110.1000.0100.1110.1100.1000.0010.0100.1111.0001.0010.0010\/
60+ .0100.1110.1110.0011.1100.1111.0001.1101.1101.1100.1110.1111.0100.0101.0001.0100
61+ \/
84
62
85
63
86***
64***
87−### `++shak`
65+### `++shal`
88
66
89− ++ shak :: XX shd be PBKDF
67+SHA-512 with length
90− |= [who/@p wud/@]
91− (shas (mix %shak who) wud)
92− ::
93
68
94−XX document
69+Produces an atom by hashing an atom `ruz` with SHA-512. Another atom, `len`, is
70+the byte-length of the theoretical buffer represented by the atom.
95
71
72+#### Accepts
96
73
74+`len` is an atom.
97
75
98−***
76+`ruz` is an atom.
99−### `++shal`
77+
78+#### Produces
79+
80+An atom.
100
81
101− ++ shal :: sha-512 with length
82+#### Source
83+
84+ ++ shal
102 ~/ %shal
85 ~/ %shal
103− |= {len/@ ruz/@} ^- @
86+ |= [len=@ ruz=@] ^- @
104 => .(ruz (cut 3 [0 len] ruz))
87 => .(ruz (cut 3 [0 len] ruz))
105− =+ [few==>(fe .(a 6)) wac=|=({a/@ b/@} (cut 6 [a 1] b))]
88+ =+ [few==>(fe .(a 6)) wac=|=([a=@ b/@] (cut 6 [a 1] b))]
106 =+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
89 =+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
107 =+ ral=(lsh 0 3 len)
90 =+ ral=(lsh 0 3 len)
108 =+ ^= ful
91 =+ ^= ful
@@ -211,30 +194,80 @@ XX document
211 $(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
194 $(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
212 ::
195 ::
213
196
214−XX document
197+#### Examples
198+
199+ > (shal 1 'hello')
200+ \/7.956.615.373.791.575.273.027.009.123.631.914.645.972.441.264.528.176.292.399.908\/
201+ .424.469.676.078.106.561.839.264.176.650.109.335.825.608.088.511.266.620.100.157.
202+ 847.055.280.028.606.252.747.432.021.213.474
203+ \/
215
204
205+ > (shal 1 'hello')
206+ \/7.956.615.373.791.575.273.027.009.123.631.914.645.972.441.264.528.176.292.399.908\/
207+ .424.469.676.078.106.561.839.264.176.650.109.335.825.608.088.511.266.620.100.157.
208+ 847.055.280.028.606.252.747.432.021.213.474
209+ \/
216
210
211+#### Discussion
212+
213+Because byte-strings can have leading zeros, but atoms cannot, we use `len`
214+as a way of saying that the atom `ruz` is shorter than its representative
215+byte-string.
217
216
218***
217***
219### `++sham`
218### `++sham`
220
219
220+128-bit noun hash
221+
222+Produces a 128-bit atom by hashing a noun `yux` with the `shah` function. If
223+that noun is a cell, then it is passed to the [`jam`](../2p) function to produce
224+an atom to be hashed.
225+
226+#### Accepts
227+
228+`yux` is a noun.
229+
230+#### Produces
231+
232+An atom.
233+
234+#### Source
235+
221− ++ sham :: noun hash
236+ ++ sham
222− |= yux/* ^- @uvH ^- @
237+ |= yux=* ^- @uvH ^- @
223 ?@ yux
238 ?@ yux
224 (shaf %mash yux)
239 (shaf %mash yux)
225 (shaf %sham (jam yux))
240 (shaf %sham (jam yux))
226 ::
241 ::
227
242
228−XX document
243+#### Examples
229
244
245+ > (sham [2 4])
246+ 0v3.71s52.4bqnp.ki2b8.9hhsp.2ufgg
230
247
248+ > (sham "hello")
249+ 0v1.hg8mv.t7s3f.u4f8a.q5noe.dvqvh
231
250
232***
251***
233### `++shan`
252### `++shan`
234
253
235− ++ shan :: sha-1 (deprecated)
254+SHA-1
255+
256+Produces an atom by hashing an atom `ruz` with SHA-1.
257+
258+#### Accepts
259+
260+`ruz` is an atom.
261+
262+#### Produces
263+
264+An atom.
265+
266+#### Source
267+
268+ ++ shan
236− |= ruz/@
269+ |= ruz=@
237− =+ [few==>(fe .(a 5)) wac=|=({a/@ b/@} (cut 5 [a 1] b))]
270+ =+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
238 =+ [sum=sum.few ror=ror.few rol=rol.few net=net.few inv=inv.few]
271 =+ [sum=sum.few ror=ror.few rol=rol.few net=net.few inv=inv.few]
239 =+ ral=(lsh 0 3 (met 3 ruz))
272 =+ ral=(lsh 0 3 (met 3 ruz))
240 =+ ^= ful
273 =+ ^= ful
@@ -299,52 +332,438 @@ XX document
299 $(j +(j), a tem, b a, c (rol 0 30 b), d c, e d)
332 $(j +(j), a tem, b a, c (rol 0 30 b), d c, e d)
300 ::
333 ::
301
334
302−XX document
303
335
336+#### Examples
337+
338+ > (shan 'hello')
339+ 975.987.071.262.755.080.377.722.350.727.279.193.143.145.743.181
340+
341+#### Discussion
304
342
343+SHA-1 is a deprecated function; it is not considered secure.
305
344
306***
345***
307### `++shas`
346### `++shas`
308
347
348+Salted hash
349+
350+Produces an atom by using SHA-256 plus a salt input. The [bitwise XOR](../2d)
351+is performed on `sal` and the product of `ruz` hashed with SHA-256. The product
352+of that logical operation is then itself hashed with SHA-256.
353+
354+#### Accepts
355+
356+`sal` is an atom.
357+
358+`ruz` is an atom.
359+
360+#### Source
361+
309− ++ shas :: salted hash
362+ ++ shas
310− |= [sal/@ ruz/@]
363+ |= [sal=@ ruz=@]
311 (shax (mix sal (shax ruz)))
364 (shax (mix sal (shax ruz)))
312 ::
365 ::
313
366
314−XX document
367+#### Examples
315
368
369+ > (shas 12.845 6)
370+ \/111.115.941.493.032.291.043.932.789.632.248.509.108.945.255.494.251.860.287\/
371+ .707.279.709.200.349.471.936
372+ \/
316
373
317
374
318***
375***
319### `++shaw`
376### `++shaw`
320
377
378+Hash to nbits
379+
380+Produces an atom of `len` random bits by hashing `ruz` with the salted
381+SHA-256 hash algorithm, where `sal` is the cryptographic salt.
382+
383+#### Accepts
384+
385+`sal` is an atom.
386+
387+`len` is an atom.
388+
389+`ruz` is an atom.
390+
391+#### Produces
392+
393+An atom.
394+
395+#### Source
396+
321− ++ shaw :: hash to nbits
397+ ++ shaw
322− |= [sal/@ len/@ ruz/@]
398+ |= [sal=@ len=@ ruz=@]
323 (~(raw og (shas sal (mix len ruz))) len)
399 (~(raw og (shas sal (mix len ruz))) len)
324 ::
400 ::
325
401
402+#### Examples
403+
404+ > `@ub`(shaw 3 6 98)
405+ 0b11.0111
326
406
407+ > `@ub`(shaw 2 6 98)
408+ 0b11
327
409
328***
410***
329### `++shax`
411### `++shax`
330
412
331−++ shax :: sha-256
413+SHA-256
332− ~/ %shax
333− |= ruz/@ ^- @
334− (shay [(met 3 ruz) ruz])
335−::
336
414
337−XX document
415+Produces an atom by hashing an atom `ruz` with SHA-256.
338
416
417+#### Sources
339
418
419+ ++ shax
420+ ~/ %shax
421+ |= ruz=@ ^- @
422+ (shay [(met 3 ruz) ruz])
423+ ::
424+
425+#### Examples
426+
427+ > (shax 'hello')
428+ \/16.552.786.619.039.860.277.601.417.878.457.384.195.409.020.923.835.016.617.984.82\/
429+ 0.774.431.701.725.740
430+ \/
431+
432+***
433+### `++shay`
434+
435+SHA-256 with length
436+
437+Produces an atom by hashing an atom `ruz` with SHA-512. Another atom, `len`, is
438+the byte-length of the theoretical buffer represented by the atom.
439+
440+#### Accepts
441+
442+`len` is an atom.
443+
444+`ruz` is an atom.
445+
446+#### Source
447+
448+ ++ shay
449+ ~/ %shay
450+ |= [len=@u ruz=@] ^- @
451+ => .(ruz (cut 3 [0 len] ruz))
452+ =+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
453+ =+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
454+ =+ ral=(lsh 0 3 len)
455+ =+ ^= ful
456+ %+ can 0
457+ :~ [ral ruz]
458+ [8 128]
459+ [(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
460+ [64 (~(net fe 6) ral)]
461+ ==
462+ =+ lex=(met 9 ful)
463+ =+ ^= kbx 0xc671.78f2.bef9.a3f7.a450.6ceb.90be.fffa.
464+ 8cc7.0208.84c8.7814.78a5.636f.748f.82ee.
465+ 682e.6ff3.5b9c.ca4f.4ed8.aa4a.391c.0cb3.
466+ 34b0.bcb5.2748.774c.1e37.6c08.19a4.c116.
467+ 106a.a070.f40e.3585.d699.0624.d192.e819.
468+ c76c.51a3.c24b.8b70.a81a.664b.a2bf.e8a1.
469+ 9272.2c85.81c2.c92e.766a.0abb.650a.7354.
470+ 5338.0d13.4d2c.6dfc.2e1b.2138.27b7.0a85.
471+ 1429.2967.06ca.6351.d5a7.9147.c6e0.0bf3.
472+ bf59.7fc7.b003.27c8.a831.c66d.983e.5152.
473+ 76f9.88da.5cb0.a9dc.4a74.84aa.2de9.2c6f.
474+ 240c.a1cc.0fc1.9dc6.efbe.4786.e49b.69c1.
475+ c19b.f174.9bdc.06a7.80de.b1fe.72be.5d74.
476+ 550c.7dc3.2431.85be.1283.5b01.d807.aa98.
477+ ab1c.5ed5.923f.82a4.59f1.11f1.3956.c25b.
478+ e9b5.dba5.b5c0.fbcf.7137.4491.428a.2f98
479+ =+ ^= hax 0x5be0.cd19.1f83.d9ab.9b05.688c.510e.527f.
480+ a54f.f53a.3c6e.f372.bb67.ae85.6a09.e667
481+ =+ i=0
482+ |- ^- @
483+ ?: =(i lex)
484+ (rep 5 (turn (rip 5 hax) net))
485+ =+ ^= wox
486+ =+ dux=(cut 9 [i 1] ful)
487+ =+ wox=(rep 5 (turn (rip 5 dux) net))
488+ =+ j=16
489+ |- ^- @
490+ ?: =(64 j)
491+ wox
492+ =+ :* l=(wac (sub j 15) wox)
493+ m=(wac (sub j 2) wox)
494+ n=(wac (sub j 16) wox)
495+ o=(wac (sub j 7) wox)
496+ ==
497+ =+ x=:(mix (ror 0 7 l) (ror 0 18 l) (rsh 0 3 l))
498+ =+ y=:(mix (ror 0 17 m) (ror 0 19 m) (rsh 0 10 m))
499+ =+ z=:(sum n x o y)
500+ $(wox (con (lsh 5 j z) wox), j +(j))
501+ =+ j=0
502+ =+ :* a=(wac 0 hax)
503+ b=(wac 1 hax)
504+ c=(wac 2 hax)
505+ d=(wac 3 hax)
506+ e=(wac 4 hax)
507+ f=(wac 5 hax)
508+ g=(wac 6 hax)
509+ h=(wac 7 hax)
510+ ==
511+ |- ^- @
512+ ?: =(64 j)
513+ %= ^$
514+ i +(i)
515+ hax %+ rep 5
516+ :~ (sum a (wac 0 hax))
517+ (sum b (wac 1 hax))
518+ (sum c (wac 2 hax))
519+ (sum d (wac 3 hax))
520+ (sum e (wac 4 hax))
521+ (sum f (wac 5 hax))
522+ (sum g (wac 6 hax))
523+ (sum h (wac 7 hax))
524+ ==
525+ ==
526+ =+ l=:(mix (ror 0 2 a) (ror 0 13 a) (ror 0 22 a)) :: s0
527+ =+ m=:(mix (dis a b) (dis a c) (dis b c)) :: maj
528+ =+ n=(sum l m) :: t2
529+ =+ o=:(mix (ror 0 6 e) (ror 0 11 e) (ror 0 25 e)) :: s1
530+ =+ p=(mix (dis e f) (dis (inv e) g)) :: ch
531+ =+ q=:(sum h o p (wac j kbx) (wac j wox)) :: t1
532+ $(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
533+
534+
535+#### Examples
536+
537+ > (shay 1 'hello')
538+ \/16.144.219.278.061.159.438.339.586.294.967.166.038.336.988.797.862.808.055.174.98\/
539+ 7.398.597.302.069.674
540+ \/
541+
542+ > (shay 2 'hello')
543+ \/100.467.333.538.737.303.691.714.735.404.408.035.555.613.179.595.938.688.113.300.8\/
544+ 01.974.878.934.544.183
545+ \/
546+
547+#### Discussion
548+
549+Because byte-strings can have leading zeros, but atoms cannot, we use `len`
550+as a way of saying that the atom `ruz` is shorter than its representative
551+byte-string.
340
552
341***
553***
342### `++shaz`
554### `++shaz`
343
555
556+SHA-512
557+
558+Produces an atom by hashing an atom `ruz` with SHA-512.
559+
560+#### Accepts
561+
562+`ruz` is an atom.
563+
564+#### Produces
565+
566+An atom.
567+
568+#### Source
569+
344− ++ shaz :: sha-512
570+ ++ shaz
345− |= ruz/@ ^- @
571+ |= ruz=@ ^- @
346 (shal [(met 3 ruz) ruz])
572 (shal [(met 3 ruz) ruz])
347
573
574+#### Examples
575+
576+ > (shaz 'hello')
577+ \/3.548.533.422.469.437.734.729.094.584.175.910.682.076.656.883.559.953.324.378.007\/
578+ .735.849.386.038.666.450.748.109.671.344.747.196.048.200.348.948.408.339.256.384.
579+ 360.070.359.656.053.016.948.640.159.265.179
580+ \/
581+
582+***
583+### `++og`
584+
585+Container arm for SHA-256-powered random-number generation. Its sample `a` is an
586+atom that is used as a seed for the hash.
587+
588+#### Accepts
589+
590+`a` is an atom.
591+
592+#### Produces
593+
594+A core.
595+
596+#### Source
597+ ++ og
598+ ~/ %og
599+ |_ a=@
600+
601+#### Examples
602+
603+ > ~(. og 919)
604+ <4.wmp {a/@ud <54.tyv 119.olq 31.ohr 1.jmk $143>}>
605+
606+#### Discussion
607+
608+Note that the product is deterministic; the seed will produce the same
609+result every time it is run. Use `eny`, 256 bits of entropy, for a
610+non-deterministic product.
611+
612+***
613+### `++rad`
614+
615+Random in range
616+
617+Produces a random number that is within the range of first `b` whole numbers,
618+starting at `0`.
619+
620+#### Accepts
621+
622+`b` is an atom.
623+
624+#### Produces
625+
626+An atom.
627+
628+#### Source
629+
630+ ++ rad
631+ |= b=@ ^- @
632+ =+ c=(raw (met 0 b))
633+ ?:((lth c b) c $(a +(a)))
634+
635+#### Examples
636+
637+ > (~(rad og 5) 11)
638+ 4
639+
640+ > (~(rad og 758.716.593) 11)
641+ 2
642+
643+ > (~(rad og 1) 100.000)
644+ 71.499
645+
646+ > (~(rad og eny) 11) :: `eny` acts as a random sample
647+ 7
648+
649+***
650+### `++rads`
651+
652+Random continuation
653+
654+Produces a cell. The head of the cell is a random number that is within the
655+range of first `b` whole numbers, starting at `0`. The tail is a new core
656+produced from hashing the parent core with `(rad b)`.
657+
658+#### Accepts
659+
660+`b` is an atom.
661+
662+#### Produces
663+
664+A cell.
665+
666+#### Source
667+
668+ ++ rads
669+ |= b=@
670+ =+ r=(rad b)
671+ [r +>.$(a (shas %og-s (mix a r)))]
672+
673+#### Examples
674+
675+ > (~(rads og 4) 10)
676+ [2 <4.wmp {a/@ <54.tyv 119.olq 31.ohr 1.jmk $143>}>]
677+
678+ > =/ rng ~(. og 7)
679+ =^ a rng (rads:rng 10)
680+ =^ b rng (rads:rng 10)
681+ [a b]
682+ [2 8]
683+
684+#### Discussion
685+
686+Since everything in Hoon is a pure function, we need to use tricks like this to
687+generate separate random values from the same seed. Notice how we jump from
688+one `rads` function call to another in the above example.
689+
690+***
691+### `++raw`
692+
693+Random bits
694+
695+Produces an atom with a bitwidth `b` that is composed of random bits.
696+
697+#### Accepts
698+
699+`b` is an atom.
700+
701+#### Produces
702+
703+An atom.
704+
705+#### Source
706+
707+ ++ raw
708+ ~/ %raw
709+ |= b=@ ^- @
710+ %+ can
711+ 0
712+ =+ c=(shas %og-a (mix b a))
713+ |- ^- (list [@ @])
714+ ?: =(0 b)
715+ ~
716+ =+ d=(shas %og-b (mix b (mix a c)))
717+ ?: (lth b 256)
718+ [[b (end 0 b d)] ~]
719+ [[256 d] $(c d, b (sub b 256))]
720+
721+#### Examples
722+
723+ > `@ud`(~(raw og 27) 4)
724+ 0b1001
725+
726+ > `@ub`(~(raw og 27) 3)
727+ 0b0
728+
729+ > `@ub`(~(raw og 11) 4)
730+ 0b1111
731+
732+ > `@ub`(~(raw og 11) 3)
733+ 0b100
734+
735+***
736+### `++raws`
737+
738+Random bits continuation
739+
740+Produces a cell. The head of the cell is an atom with a bitwidth `b` that is
741+composed of random bits. The tail is a new core produced from hashing the
742+parent core with `(raw b)`.
743+
744+#### Source
745+
746+ ++ raws
747+ |= b=@
748+ =+ r=(raw b)
749+ [r +>.$(a (shas %og-s r))]
750+ --
751+
752+#### Examples
753+
754+ > `[@ub _og]`(~(raws og 7) 4)
755+ [0b1100 <4.wmp {a/@ <54.tyv 119.olq 31.ohr 1.jmk $143>}>]
756+
757+ > =/ rng ~(. og 7)
758+ =^ a rng (rads:rng 4)
759+ =^ b rng (rads:rng 4)
760+ [`@ub`a `@ub`b]
761+ [0b10 0b1]
762+
763+#### Discussion
348
764
765+Since everything in Hoon is a pure function, we need to use tricks like this to
766+generate separate random values from the same seed. Notice how we jump from
767+one `raws` function call to another in the above example.
349
768
350***
769***