on 4fdc19d help sign in
868 lines 15 kB history raw
1+++
2title = "3f: Scrambling"
3weight = 26
4template = "doc.html"
5+++
7## `++un`
9Reversible scrambling
11A core that contains arms that perform reversible scrambling operations.
12Used in the `@p` phonetic base.
14#### Source
16```hoon
17++ un
18 |%
19```
21---
23### `++wren:un`
25Conceal structure
27Scrambles a byte-string `pyn` by adding the current position to each
28byte, looking it up in an s-box, and then performing the XOR operation
29on the result, pushing it forward. The inverse of `wred`.
31#### Accepts
33`pyn` is an atom.
35#### Produces
37An atom.
39#### Source
41```hoon
42++ wren
43 |= pyn=@ ^- @
44 =+ len=(met 3 pyn)
45 ?: =(0 len)
46 0
47 => .(len (dec len))
48 =+ mig=(zaft (xafo len (cut 3 [len 1] pyn)))
49 %+ can 3
50 %- flop ^- (list [@ @])
51 :- [1 mig]
52 |- ^- (list [@ @])
53 ?: =(0 len)
54 ~
55 => .(len (dec len))
56 =+ mog=(zyft :(mix mig (end 3 len) (cut 3 [len 1] pyn)))
57 [[1 mog] $(mig mog)]
58```
60#### Examples
62```
63> `@ux`(wren:un 'testing')
640x30.bf6a.b9fe.7d8f
66> `@ux`'testing'
670x67.6e69.7473.6574
69> `@da`(wred:un (wren:un ~2001.2.5))
70~2001.2.5
71```
73---
75### `++wred:un`
77Restore structure
79Unscrambles a byte-string `cry` by subtracting the current position from
80each byte, looking it up in an s-box, and performing the XOR operation
81on the result, pushing it forward. The inverse of `wren`.
83#### Accepts
85`cry` is an atom.
87#### Produces
89An atom.
91#### Source
93```hoon
94++ wred
95 |= cry=@ ^- @
96 =+ len=(met 3 cry)
97 ?: =(0 len)
98 0
99 => .(len (dec len))
100 =+ mig=(cut 3 [len 1] cry)
101 %+ can 3
102 %- flop ^- (list [@ @])
103 :- [1 (xaro len (zart mig))]
104 |- ^- (list [@ @])
105 ?: =(0 len)
106 ~
107 => .(len (dec len))
108 =+ mog=(cut 3 [len 1] cry)
109 [[1 :(mix mig (end 3 len) (zyrt mog))] $(mig mog)]
110```
112#### Examples
114```
115> (wred:un 0x30.bf6a.b9fe.7d8f)
11629.113.321.805.538.676
118> `@t`(wred:un 0x30.bf6a.b9fe.7d8f)
119'testing'
121> (wred:un (wren:un 200.038.426))
122200.038.426
123```
125---
127### `++xafo:un`
129Add modulo 255
131Produces the sum of two atoms modulo 255, encoded as a nonzero byte. The inverse
132of `xaro`.
134#### Accepts
136`a` is an atom.
138`b` is an atom.
140#### Produces
142An atom.
144#### Source
146```hoon
147++ xafo |=([a=@ b=@] +((mod (add (dec b) a) 255)))
148```
150#### Examples
152```
153> (xafo:un 5 6)
15411
156> (xafo:un 256 20)
15721
159> (xafo:un 256 (xaro:un 256 20))
16020
161```
163---
165### `++xaro:un`
167Subtract modulo 255
169Produces the sum of two atoms modulo 255, encoded as a nonzero byte. The inverse
170of `xafo`.
172#### Accepts
174`a` is an atom.
176`b` is an atom.
178#### Produces
180An atom.
182#### Source
184```hoon
185++ xaro |=([a=@ b=@] +((mod (add (dec b) (sub 255 (mod a 255))) 255)))
186```
188#### Examples
190```
191> (xaro:un 17 57)
19240
194> (xaro:un 265 12)
197> (xaro:un 256 (xafo:un 256 20))
19820
199```
201---
203### `++zaft:un`
205Look up in 255 sub box
207Looks up a nonzero byte `a` in a substitution box with 255 values, producing a
208unique nonzero byte. The inverse of `zart`.
210#### Accepts
212`a` is an atom of one byte in length.
214#### Produces
216An atom.
218#### Source
220```hoon
221++ zaft
222 |= a=@D
223 =+ ^= b
224 0xcc.75bc.86c8.2fb1.9a42.f0b3.79a0.92ca.21f6.1e41.cde5.fcc0.
225 7e85.51ae.1005.c72d.1246.07e8.7c64.a914.8d69.d9f4.59c2.8038.
226 1f4a.dca2.6fdf.66f9.f561.a12e.5a16.f7b0.a39f.364e.cb70.7318.
227 1de1.ad31.63d1.abd4.db68.6a33.134d.a760.edee.5434.493a.e323.
228 930d.8f3d.3562.bb81.0b24.43cf.bea5.a6eb.52b4.0229.06b2.6704.
229 78c9.45ec.d75e.58af.c577.b7b9.c40e.017d.90c3.87f8.96fa.1153.
230 0372.7f30.1c32.ac83.ff17.c6e4.d36d.6b55.e2ce.8c71.8a5b.b6f3.
231 9d4b.eab5.8b3c.e7f2.a8fe.9574.5de0.bf20.3f15.9784.9939.5f9c.
232 e609.564f.d8a4.b825.9819.94aa.2c08.8e4c.9b22.477a.2840.3ed6.
233 3750.6ef1.44dd.89ef.6576.d00a.fbda.9ed2.3b6c.7b0c.bde9.2ade.
234 5c88.c182.481a.1b0f.2bfd.d591.2726.57ba
235 (cut 3 [(dec a) 1] b)
236```
238#### Examples
240```
241> (zaft:un 0x12)
24242
244> (zaft:un 0xff)
245204
246> `@ux`(zart:un 204)
2470xff
249> (zaft:un 0x0)
250! decrement-underflow
251! exit
252```
254---
256### `++zart:un`
258Reverse look up in 255 sub box
260Looks up the index of a nonzero byte `a` in the substitution box with 255
261values, producing a unique nonzero byte. The inverse of `zaft`.
263#### Accepts
265`a` is an atom of one byte in length.
267#### Produces
269An atom.
271#### Source
273```hoon
274++ zart
275 |= a=@D
276 =+ ^= b
277 0x68.4f07.ea1c.73c9.75c2.efc8.d559.5125.f621.a7a8.8591.5613.
278 dd52.40eb.65a2.60b7.4bcb.1123.ceb0.1bd6.3c84.2906.b164.19b3.
279 1e95.5fec.ffbc.f187.fbe2.6680.7c77.d30e.e94a.9414.fd9a.017d.
280 3a7e.5a55.8ff5.8bf9.c181.e5b6.6ab2.35da.50aa.9293.3bc0.cdc6.
281 f3bf.1a58.4130.f844.3846.744e.36a0.f205.789e.32d8.5e54.5c22.
282 0f76.fce7.4569.0d99.d26e.e879.dc16.2df4.887f.1ffe.4dba.6f5d.
283 bbcc.2663.1762.aed7.af8a.ca20.dbb4.9bc7.a942.834c.105b.c4d4.
284 8202.3e61.a671.90e6.273d.bdab.3157.cfa4.0c2e.df86.2496.f7ed.
285 2b48.2a9d.5318.a343.d128.be9c.a5ad.6bb5.6dfa.c5e1.3408.128d.
286 2c04.0339.97a1.2ff0.49d0.eeb8.6c0a.0b37.b967.c347.d9ac.e072.
287 e409.7b9f.1598.1d3f.33de.8ce3.8970.8e7a
288 (cut 3 [(dec a) 1] b)
289```
291#### Examples
293```
294> `@ux`(zart:un 204)
2950xff
297> `@ux`(zart:un 42)
2980x12
300> (zaft:un 0x12)
30142
302```
304---
306### `++zyft:un`
308Lookup byte in 256 sub box
310Looks up a byte `a` in a substitution box with 256 values, producing a byte. The
311inverse of `zyrt`.
313#### Accepts
315`a` is an atom of one byte in length.
317#### Produces
319An atom.
321#### Source
323```hoon
324++ zyft
325 |= a=@D
326 =+ ^= b
327 0xbb49.b71f.b881.b402.17e4.6b86.69b5.1647.115f.dddb.7ca5.
328 8371.4bd5.19a9.b092.605d.0d9b.e030.a0cc.78ba.5706.4d2d.
329 986a.768c.f8e8.c4c7.2f1c.effe.3cae.01c0.253e.65d3.3872.
330 ce0e.7a74.8ac6.daac.7e5c.6479.44ec.4143.3d20.4af0.ee6c.
331 c828.deca.0377.249f.ffcd.7b4f.eb7d.66f2.8951.042e.595a.
332 8e13.f9c3.a79a.f788.6199.9391.7fab.6200.4ce5.0758.e2f1.
333 7594.c945.d218.4248.afa1.e61a.54fb.1482.bea4.96a2.3473.
334 63c2.e7cb.155b.120a.4ed7.bfd8.b31b.4008.f329.fca3.5380.
335 9556.0cb2.8722.2bea.e96e.3ac5.d1bc.10e3.2c52.a62a.b1d6.
336 35aa.d05e.f6a8.0f3b.31ed.559d.09ad.f585.6d21.fd1d.8d67.
337 370b.26f4.70c1.b923.4684.6fbd.cf8b.5036.0539.9cdc.d93f.
338 9068.1edf.8f33.b632.d427.97fa.9ee1
339 (cut 3 [a 1] b)
340```
342#### Examples
344```
345> (zyft:un 0x12)
34657
348> (zyft:un 0x0)
349225
351> (zyft:un 0xff)
352187
353> `@ux`(zyrt:un 187)
3540xff
355```
357---
359### `++zyrt:un`
361Reverse lookup byte in 256 sub box
363Looks up a byte `a` in a substitution box with 256 values, producing a byte.
364The inverse of `zyft`.
366#### Accepts
368`a` is an atom of one byte in length.
370#### Produces
372An atom.
374#### Source
376```hoon
377++ zyrt
378 |= a=@D
379 =+ ^= b
380 0x9fc8.2753.6e02.8fcf.8b35.2b20.5598.7caa.c9a9.30b0.9b48.
381 47ce.6371.80f6.407d.00dd.0aa5.ed10.ecb7.0f5a.5c3a.e605.
382 c077.4337.17bd.9eda.62a4.79a7.ccb8.44cd.8e64.1ec4.5b6b.
383 1842.ffd8.1dfb.fd07.f2f9.594c.3be3.73c6.2cb6.8438.e434.
384 8d3d.ea6a.5268.72db.a001.2e11.de8c.88d3.0369.4f7a.87e2.
385 860d.0991.25d0.16b9.978a.4bf4.2a1a.e96c.fa50.85b5.9aeb.
386 9dbb.b2d9.a2d1.7bba.66be.e81f.1946.29a8.f5d2.f30c.2499.
387 c1b3.6583.89e1.ee36.e0b4.6092.937e.d74e.2f6f.513e.9615.
388 9c5d.d581.e7ab.fe74.f01b.78b1.ae75.af57.0ec2.adc7.3245.
389 12bf.2314.3967.0806.31dc.cb94.d43f.493c.54a6.0421.c3a1.
390 1c4a.28ac.fc0b.26ca.5870.e576.f7f1.616d.905f.ef41.33bc.
391 df4d.225e.2d56.7fd6.1395.a3f8.c582
392 (cut 3 [a 1] b)
393```
395#### Examples
397```
398> `@ux`(zyrt:un 57)
3990x12
401> `@ux`(zyrt:un 225)
4020x0
404> `@ux`(zyrt:un 187)
4050xff
406> (zyft:un 0xff)
407187
408```
410---
412## `++ob`
414Reversible scrambling, v3
416A core for performing reversible scrambling operations for the `@p` phonetic
417base.
419#### Source
421```hoon
422++ ob
423 ~% %ob ..ob
424 ==
425 %fein fein
426 %fynd fynd
427 ==
428 |%
429```
431---
433### `++fein:ob`
435conceal structure, v3
437`+fein` conceals planet-sized atoms. The idea is that it should not be trivial
438to tell which planet a star has spawned under.
440Permutes atom `pyn` which fits into 17 to 32 bits, or if `pyn` fits
441into 33 to 64 bits, does the same permutation on the low 32 bits only.
442Otherwise, passes `pyn` through unchanged.
444#### Accepts
446`pyn` is an atom.
448#### Produces
450An atom.
452#### Source
454```hoon
455++ fein
456 ~/ %fein
457 |= pyn=@ ^- @
458 ?: &((gte pyn 0x1.0000) (lte pyn 0xffff.ffff))
459 (add 0x1.0000 (feis (sub pyn 0x1.0000)))
460 ?: &((gte pyn 0x1.0000.0000) (lte pyn 0xffff.ffff.ffff.ffff))
461 =/ lo (dis pyn 0xffff.ffff)
462 =/ hi (dis pyn 0xffff.ffff.0000.0000)
463 %+ con hi
464 $(pyn lo)
465 pyn
466```
468#### Examples
470```
471> (fein:ob 111.103)
4722.783.373.008
474> (fynd:ob 2.783.373.008)
475111.103
476```
478---
480### `++fynd:ob`
482Restore structure, v3
484Restores obfuscated values that have been enciphered with [+fein](feinob).
486Permutes atom `cry` that fits into 17 to 32 bits, or permutes the low 32 bits of
487`cry` if it fits into 33 to 64 bits. Otherwise, passes the atom through
488unchanged. The inverse of the one applied by [`+fein`](#feinob).
490#### Accepts
492`cry` is an atom.
494#### Produces
496An atom.
498#### Source
500```hoon
501++ fynd
502 ~/ %fynd
503 |= cry=@ ^- @
504 ?: &((gte cry 0x1.0000) (lte cry 0xffff.ffff))
505 (add 0x1.0000 (tail (sub cry 0x1.0000)))
506 ?: &((gte cry 0x1.0000.0000) (lte cry 0xffff.ffff.ffff.ffff))
507 =/ lo (dis cry 0xffff.ffff)
508 =/ hi (dis cry 0xffff.ffff.0000.0000)
509 %+ con hi
510 $(cry lo)
511 cry
512```
514#### Examples
516```
517> (fein:ob 111.103)
5182.783.373.008
520> (fynd:ob 2.783.373.008)
521111.103
522```
524---
526### `++feis:ob`
528Four-round generalised Feistel cipher over the domain [0, 2^32 - 2^16 - 1]
530See: Black & Rogaway (2002), Ciphers for arbitrary finite domains.
532Inverse of [`+tail`](#tailob).
534#### Accepts
536`m` is an atom.
538#### Produces
540An atom.
542#### Source
544```hoon
545++ feis
546 |= m=@
547 ^- @
548 (fee 4 0xffff 0x1.0000 (mul 0xffff 0x1.0000) eff m)
549```
551#### Examples
553```
554> (feis:ob 11)
555776.343.932
557> (tail:ob 776.343.932)
55811
559```
561---
563### `++tail:ob`
565Reverse [`+feis`](#feisob)
567Applies the reverse of the Feistel cipher applied by `+feis`.
569#### Accepts
571`m` is an atom.
573#### Produces
575An atom.
577#### Source
579```hoon
580++ tail
581 |= m=@
582 ^- @
583 (feen 4 0xffff 0x1.0000 (mul 0xffff 0x1.0000) eff m)
584```
586#### Examples
588```
589> (feis:ob 11)
590776.343.932
592> (tail:ob 776.343.932)
59311
594```
596---
598### `++fee:ob`
600"Fe" in B&R (2002)
602A Feistel cipher given the following parameters:
604- `r`: Number of Feistel rounds.
605- `a`, `b`: Parameters such that `ab` >= `k`.
606- `k`: Value such that the domain of the cipher is [0, k - 1].
607- `prf`: A gate denoting a family of pseudorandom functions indexed by its first argument and taking its second argument as input.
608- `m`: An input value in the domain [0, k - 1].
610#### Accepts
612`r`, `a`, `b`, `k` are an atoms.
614`prft` is a gate: `$-([j=@ r=@] @)`.
616`m` is an atom.
618#### Produces
620An atom.
622#### Source
624```hoon
625++ fee
626 |= [r=@ a=@ b=@ k=@ prf=$-([j=@ r=@] @) m=@]
627 ^- @
628 =/ c (fe r a b prf m)
629 ?: (lth c k)
630 c
631 (fe r a b prf c)
632```
634---
636### `++feen:ob`
638Reverse [`+fee`](#feeob)
640"Fe^-1" in B&R (2002). Reverses a Feistel cipher constructed with parameters as
641described in `+fee`.
643#### Accepts
645`r`, `a`, `b`, and `k` are atoms.
647`prf` is a gate: `$-([j=@ r=@] @)`.
649`m` is an atom.
651#### Produces
653An atom.
655#### Source
657```hoon
658++ feen
659 |= [r=@ a=@ b=@ k=@ prf=$-([j=@ r=@] @) m=@]
660 ^- @
661 =/ c (fen r a b prf m)
662 ?: (lth c k)
663 c
664 (fen r a b prf c)
665```
667---
669### `+fe:ob`
671An internal function to [`+fee`](#feeob).
673Note that this implementation differs slightly from the reference paper to
674support some legacy behaviour.
676#### Accepts
678`r`, `a`, and `b` are atoms.
680`prf` is a gate: `$-([j=@ r=@] @)`.
682`m` is an atom.
684#### Produces
686An atom.
688#### Source
690```hoon
691++ fe
692 |= [r=@ a=@ b=@ prf=$-([j=@ r=@] @) m=@]
693 =/ j 1
694 =/ ell (mod m a)
695 =/ arr (div m a)
696 |- ^- @
697 ::
698 ?: (gth j r)
699 ?. =((mod r 2) 0)
700 (add (mul arr a) ell)
701 ::
702 :: Note that +fe differs from B&R (2002)'s "fe" below, as a previous
703 :: implementation of this cipher contained a bug such that certain inputs
704 :: could encipher to the same output.
705 ::
706 :: To correct these problem cases while also preserving the cipher's
707 :: legacy behaviour on most inputs, we check for a problem case (which
708 :: occurs when 'arr' is equal to 'a') and, if detected, use an alternate
709 :: permutation instead.
710 ::
711 ?: =(arr a)
712 (add (mul arr a) ell)
713 (add (mul ell a) arr)
714 ::
715 =/ f (prf (sub j 1) arr)
716 ::
717 =/ tmp
718 ?. =((mod j 2) 0)
719 (mod (add f ell) a)
720 (mod (add f ell) b)
721 ::
722 $(j +(j), ell arr, arr tmp)
723```
725---
727### `++fen:ob`
729Reverse [`+fe`](#feob)
731This is an internal function to [`+feen`](#feenob)
733Note that this implementation differs slightly from the reference paper
734to support some legacy behaviour.
736#### Accepts
738`r`, `a` and `b` are atoms.
740`prf` is a gate: `$-([j=@ r=@] @)`.
742`m` is an atom.
744#### Produces
746An atom.
748#### Source
750```hoon
751++ fen
752 |= [r=@ a=@ b=@ prf=$-([j=@ r=@] @) m=@]
753 =/ j r
754 ::
755 =/ ahh
756 ?. =((mod r 2) 0)
757 (div m a)
758 (mod m a)
759 ::
760 =/ ale
761 ?. =((mod r 2) 0)
762 (mod m a)
763 (div m a)
764 ::
765 :: Similar to the comment in +fe, +fen differs from B&R (2002)'s "fe^-1"
766 :: here in order to preserve the legacy cipher's behaviour on most inputs.
767 ::
768 :: Here problem cases can be identified by 'ahh' equating with 'a'; we
769 :: correct those cases by swapping the values of 'ahh' and 'ale'.
770 ::
771 =/ ell
772 ?: =(ale a)
773 ahh
774 ale
775 ::
776 =/ arr
777 ?: =(ale a)
778 ale
779 ahh
780 ::
781 |- ^- @
782 ?: (lth j 1)
783 (add (mul arr a) ell)
784 =/ f (prf (sub j 1) ell)
785 ::
786 :: Note that there is a slight deviation here to avoid dealing with
787 :: negative values. We add 'a' or 'b' to arr as appropriate and reduce
788 :: 'f' modulo the same number before performing subtraction.
789 ::
790 =/ tmp
791 ?. =((mod j 2) 0)
792 (mod (sub (add arr a) (mod f a)) a)
793 (mod (sub (add arr b) (mod f b)) b)
794 ::
795 $(j (sub j 1), ell tmp, arr ell)
796```
798---
800### `++eff:ob`
802murmur3-based pseudorandom function.
804'F' in B&R (2002).
806- `j` is a number between 0 and 3, selecting the seed with that index in
807 [+raku](#rakuob).
808- `r` is an atom with a maximum length of two bytes. This is an internal
809 function of [`+feis`](#feisob) and [`+tail`](#tailob).
811#### Accepts
813`j` is an atom.
815`r` is an atom.
817#### Produces
819An atom.
821#### Source
823```hoon
824++ eff
825 |= [j=@ r=@]
826 ^- @
827 (muk (snag j raku) 2 r)
828```
830#### Example
832```
833> (eff:ob 0 'ab')
8341.178.819.349
835```
837---
839### `++raku:ob`
841Key list
843Produces a list of arbitrary hexademical keys for use with [`+eff`](#effob).
845#### Produces
847A list of atoms of aura `@ux` (hexadecimal).
849#### Source
851```hoon
852++ raku
853 ^- (list @ux)
854 :~ 0xb76d.5eed
855 0xee28.1300
856 0x85bc.ae01
857 0x4b38.7af7
858 ==
859```
861#### Examples
863```
864> raku:ob
865~[0xb76d.5eed 0xee28.1300 0x85bc.ae01 0x4b38.7af7]
866```
868---