+++ title = "3f: Scrambling" weight = 26 template = "doc.html" +++ ## `++un` Reversible scrambling A core that contains arms that perform reversible scrambling operations. Used in the `@p` phonetic base. #### Source ```hoon ++ un |% ``` --- ### `++wren:un` Conceal structure Scrambles a byte-string `pyn` by adding the current position to each byte, looking it up in an s-box, and then performing the XOR operation on the result, pushing it forward. The inverse of `wred`. #### Accepts `pyn` is an atom. #### Produces An atom. #### Source ```hoon ++ wren |= pyn=@ ^- @ =+ len=(met 3 pyn) ?: =(0 len) 0 => .(len (dec len)) =+ mig=(zaft (xafo len (cut 3 [len 1] pyn))) %+ can 3 %- flop ^- (list [@ @]) :- [1 mig] |- ^- (list [@ @]) ?: =(0 len) ~ => .(len (dec len)) =+ mog=(zyft :(mix mig (end 3 len) (cut 3 [len 1] pyn))) [[1 mog] $(mig mog)] ``` #### Examples ``` > `@ux`(wren:un 'testing') 0x30.bf6a.b9fe.7d8f > `@ux`'testing' 0x67.6e69.7473.6574 > `@da`(wred:un (wren:un ~2001.2.5)) ~2001.2.5 ``` --- ### `++wred:un` Restore structure Unscrambles a byte-string `cry` by subtracting the current position from each byte, looking it up in an s-box, and performing the XOR operation on the result, pushing it forward. The inverse of `wren`. #### Accepts `cry` is an atom. #### Produces An atom. #### Source ```hoon ++ wred |= cry=@ ^- @ =+ len=(met 3 cry) ?: =(0 len) 0 => .(len (dec len)) =+ mig=(cut 3 [len 1] cry) %+ can 3 %- flop ^- (list [@ @]) :- [1 (xaro len (zart mig))] |- ^- (list [@ @]) ?: =(0 len) ~ => .(len (dec len)) =+ mog=(cut 3 [len 1] cry) [[1 :(mix mig (end 3 len) (zyrt mog))] $(mig mog)] ``` #### Examples ``` > (wred:un 0x30.bf6a.b9fe.7d8f) 29.113.321.805.538.676 > `@t`(wred:un 0x30.bf6a.b9fe.7d8f) 'testing' > (wred:un (wren:un 200.038.426)) 200.038.426 ``` --- ### `++xafo:un` Add modulo 255 Produces the sum of two atoms modulo 255, encoded as a nonzero byte. The inverse of `xaro`. #### Accepts `a` is an atom. `b` is an atom. #### Produces An atom. #### Source ```hoon ++ xafo |=([a=@ b=@] +((mod (add (dec b) a) 255))) ``` #### Examples ``` > (xafo:un 5 6) 11 > (xafo:un 256 20) 21 > (xafo:un 256 (xaro:un 256 20)) 20 ``` --- ### `++xaro:un` Subtract modulo 255 Produces the sum of two atoms modulo 255, encoded as a nonzero byte. The inverse of `xafo`. #### Accepts `a` is an atom. `b` is an atom. #### Produces An atom. #### Source ```hoon ++ xaro |=([a=@ b=@] +((mod (add (dec b) (sub 255 (mod a 255))) 255))) ``` #### Examples ``` > (xaro:un 17 57) 40 > (xaro:un 265 12) 2 > (xaro:un 256 (xafo:un 256 20)) 20 ``` --- ### `++zaft:un` Look up in 255 sub box Looks up a nonzero byte `a` in a substitution box with 255 values, producing a unique nonzero byte. The inverse of `zart`. #### Accepts `a` is an atom of one byte in length. #### Produces An atom. #### Source ```hoon ++ zaft |= a=@D =+ ^= b 0xcc.75bc.86c8.2fb1.9a42.f0b3.79a0.92ca.21f6.1e41.cde5.fcc0. 7e85.51ae.1005.c72d.1246.07e8.7c64.a914.8d69.d9f4.59c2.8038. 1f4a.dca2.6fdf.66f9.f561.a12e.5a16.f7b0.a39f.364e.cb70.7318. 1de1.ad31.63d1.abd4.db68.6a33.134d.a760.edee.5434.493a.e323. 930d.8f3d.3562.bb81.0b24.43cf.bea5.a6eb.52b4.0229.06b2.6704. 78c9.45ec.d75e.58af.c577.b7b9.c40e.017d.90c3.87f8.96fa.1153. 0372.7f30.1c32.ac83.ff17.c6e4.d36d.6b55.e2ce.8c71.8a5b.b6f3. 9d4b.eab5.8b3c.e7f2.a8fe.9574.5de0.bf20.3f15.9784.9939.5f9c. e609.564f.d8a4.b825.9819.94aa.2c08.8e4c.9b22.477a.2840.3ed6. 3750.6ef1.44dd.89ef.6576.d00a.fbda.9ed2.3b6c.7b0c.bde9.2ade. 5c88.c182.481a.1b0f.2bfd.d591.2726.57ba (cut 3 [(dec a) 1] b) ``` #### Examples ``` > (zaft:un 0x12) 42 > (zaft:un 0xff) 204 > `@ux`(zart:un 204) 0xff > (zaft:un 0x0) ! decrement-underflow ! exit ``` --- ### `++zart:un` Reverse look up in 255 sub box Looks up the index of a nonzero byte `a` in the substitution box with 255 values, producing a unique nonzero byte. The inverse of `zaft`. #### Accepts `a` is an atom of one byte in length. #### Produces An atom. #### Source ```hoon ++ zart |= a=@D =+ ^= b 0x68.4f07.ea1c.73c9.75c2.efc8.d559.5125.f621.a7a8.8591.5613. dd52.40eb.65a2.60b7.4bcb.1123.ceb0.1bd6.3c84.2906.b164.19b3. 1e95.5fec.ffbc.f187.fbe2.6680.7c77.d30e.e94a.9414.fd9a.017d. 3a7e.5a55.8ff5.8bf9.c181.e5b6.6ab2.35da.50aa.9293.3bc0.cdc6. f3bf.1a58.4130.f844.3846.744e.36a0.f205.789e.32d8.5e54.5c22. 0f76.fce7.4569.0d99.d26e.e879.dc16.2df4.887f.1ffe.4dba.6f5d. bbcc.2663.1762.aed7.af8a.ca20.dbb4.9bc7.a942.834c.105b.c4d4. 8202.3e61.a671.90e6.273d.bdab.3157.cfa4.0c2e.df86.2496.f7ed. 2b48.2a9d.5318.a343.d128.be9c.a5ad.6bb5.6dfa.c5e1.3408.128d. 2c04.0339.97a1.2ff0.49d0.eeb8.6c0a.0b37.b967.c347.d9ac.e072. e409.7b9f.1598.1d3f.33de.8ce3.8970.8e7a (cut 3 [(dec a) 1] b) ``` #### Examples ``` > `@ux`(zart:un 204) 0xff > `@ux`(zart:un 42) 0x12 > (zaft:un 0x12) 42 ``` --- ### `++zyft:un` Lookup byte in 256 sub box Looks up a byte `a` in a substitution box with 256 values, producing a byte. The inverse of `zyrt`. #### Accepts `a` is an atom of one byte in length. #### Produces An atom. #### Source ```hoon ++ zyft |= a=@D =+ ^= b 0xbb49.b71f.b881.b402.17e4.6b86.69b5.1647.115f.dddb.7ca5. 8371.4bd5.19a9.b092.605d.0d9b.e030.a0cc.78ba.5706.4d2d. 986a.768c.f8e8.c4c7.2f1c.effe.3cae.01c0.253e.65d3.3872. ce0e.7a74.8ac6.daac.7e5c.6479.44ec.4143.3d20.4af0.ee6c. c828.deca.0377.249f.ffcd.7b4f.eb7d.66f2.8951.042e.595a. 8e13.f9c3.a79a.f788.6199.9391.7fab.6200.4ce5.0758.e2f1. 7594.c945.d218.4248.afa1.e61a.54fb.1482.bea4.96a2.3473. 63c2.e7cb.155b.120a.4ed7.bfd8.b31b.4008.f329.fca3.5380. 9556.0cb2.8722.2bea.e96e.3ac5.d1bc.10e3.2c52.a62a.b1d6. 35aa.d05e.f6a8.0f3b.31ed.559d.09ad.f585.6d21.fd1d.8d67. 370b.26f4.70c1.b923.4684.6fbd.cf8b.5036.0539.9cdc.d93f. 9068.1edf.8f33.b632.d427.97fa.9ee1 (cut 3 [a 1] b) ``` #### Examples ``` > (zyft:un 0x12) 57 > (zyft:un 0x0) 225 > (zyft:un 0xff) 187 > `@ux`(zyrt:un 187) 0xff ``` --- ### `++zyrt:un` Reverse lookup byte in 256 sub box Looks up a byte `a` in a substitution box with 256 values, producing a byte. The inverse of `zyft`. #### Accepts `a` is an atom of one byte in length. #### Produces An atom. #### Source ```hoon ++ zyrt |= a=@D =+ ^= b 0x9fc8.2753.6e02.8fcf.8b35.2b20.5598.7caa.c9a9.30b0.9b48. 47ce.6371.80f6.407d.00dd.0aa5.ed10.ecb7.0f5a.5c3a.e605. c077.4337.17bd.9eda.62a4.79a7.ccb8.44cd.8e64.1ec4.5b6b. 1842.ffd8.1dfb.fd07.f2f9.594c.3be3.73c6.2cb6.8438.e434. 8d3d.ea6a.5268.72db.a001.2e11.de8c.88d3.0369.4f7a.87e2. 860d.0991.25d0.16b9.978a.4bf4.2a1a.e96c.fa50.85b5.9aeb. 9dbb.b2d9.a2d1.7bba.66be.e81f.1946.29a8.f5d2.f30c.2499. c1b3.6583.89e1.ee36.e0b4.6092.937e.d74e.2f6f.513e.9615. 9c5d.d581.e7ab.fe74.f01b.78b1.ae75.af57.0ec2.adc7.3245. 12bf.2314.3967.0806.31dc.cb94.d43f.493c.54a6.0421.c3a1. 1c4a.28ac.fc0b.26ca.5870.e576.f7f1.616d.905f.ef41.33bc. df4d.225e.2d56.7fd6.1395.a3f8.c582 (cut 3 [a 1] b) ``` #### Examples ``` > `@ux`(zyrt:un 57) 0x12 > `@ux`(zyrt:un 225) 0x0 > `@ux`(zyrt:un 187) 0xff > (zyft:un 0xff) 187 ``` --- ## `++ob` Reversible scrambling, v3 A core for performing reversible scrambling operations for the `@p` phonetic base. #### Source ```hoon ++ ob ~% %ob ..ob == %fein fein %fynd fynd == |% ``` --- ### `++fein:ob` conceal structure, v3 `+fein` conceals planet-sized atoms. The idea is that it should not be trivial to tell which planet a star has spawned under. Permutes atom `pyn` which fits into 17 to 32 bits, or if `pyn` fits into 33 to 64 bits, does the same permutation on the low 32 bits only. Otherwise, passes `pyn` through unchanged. #### Accepts `pyn` is an atom. #### Produces An atom. #### Source ```hoon ++ fein ~/ %fein |= pyn=@ ^- @ ?: &((gte pyn 0x1.0000) (lte pyn 0xffff.ffff)) (add 0x1.0000 (feis (sub pyn 0x1.0000))) ?: &((gte pyn 0x1.0000.0000) (lte pyn 0xffff.ffff.ffff.ffff)) =/ lo (dis pyn 0xffff.ffff) =/ hi (dis pyn 0xffff.ffff.0000.0000) %+ con hi $(pyn lo) pyn ``` #### Examples ``` > (fein:ob 111.103) 2.783.373.008 > (fynd:ob 2.783.373.008) 111.103 ``` --- ### `++fynd:ob` Restore structure, v3 Restores obfuscated values that have been enciphered with [+fein](feinob). Permutes atom `cry` that fits into 17 to 32 bits, or permutes the low 32 bits of `cry` if it fits into 33 to 64 bits. Otherwise, passes the atom through unchanged. The inverse of the one applied by [`+fein`](#feinob). #### Accepts `cry` is an atom. #### Produces An atom. #### Source ```hoon ++ fynd ~/ %fynd |= cry=@ ^- @ ?: &((gte cry 0x1.0000) (lte cry 0xffff.ffff)) (add 0x1.0000 (tail (sub cry 0x1.0000))) ?: &((gte cry 0x1.0000.0000) (lte cry 0xffff.ffff.ffff.ffff)) =/ lo (dis cry 0xffff.ffff) =/ hi (dis cry 0xffff.ffff.0000.0000) %+ con hi $(cry lo) cry ``` #### Examples ``` > (fein:ob 111.103) 2.783.373.008 > (fynd:ob 2.783.373.008) 111.103 ``` --- ### `++feis:ob` Four-round generalised Feistel cipher over the domain [0, 2^32 - 2^16 - 1] See: Black & Rogaway (2002), Ciphers for arbitrary finite domains. Inverse of [`+tail`](#tailob). #### Accepts `m` is an atom. #### Produces An atom. #### Source ```hoon ++ feis |= m=@ ^- @ (fee 4 0xffff 0x1.0000 (mul 0xffff 0x1.0000) eff m) ``` #### Examples ``` > (feis:ob 11) 776.343.932 > (tail:ob 776.343.932) 11 ``` --- ### `++tail:ob` Reverse [`+feis`](#feisob) Applies the reverse of the Feistel cipher applied by `+feis`. #### Accepts `m` is an atom. #### Produces An atom. #### Source ```hoon ++ tail |= m=@ ^- @ (feen 4 0xffff 0x1.0000 (mul 0xffff 0x1.0000) eff m) ``` #### Examples ``` > (feis:ob 11) 776.343.932 > (tail:ob 776.343.932) 11 ``` --- ### `++fee:ob` "Fe" in B&R (2002) A Feistel cipher given the following parameters: - `r`: Number of Feistel rounds. - `a`, `b`: Parameters such that `ab` >= `k`. - `k`: Value such that the domain of the cipher is [0, k - 1]. - `prf`: A gate denoting a family of pseudorandom functions indexed by its first argument and taking its second argument as input. - `m`: An input value in the domain [0, k - 1]. #### Accepts `r`, `a`, `b`, `k` are an atoms. `prft` is a gate: `$-([j=@ r=@] @)`. `m` is an atom. #### Produces An atom. #### Source ```hoon ++ fee |= [r=@ a=@ b=@ k=@ prf=$-([j=@ r=@] @) m=@] ^- @ =/ c (fe r a b prf m) ?: (lth c k) c (fe r a b prf c) ``` --- ### `++feen:ob` Reverse [`+fee`](#feeob) "Fe^-1" in B&R (2002). Reverses a Feistel cipher constructed with parameters as described in `+fee`. #### Accepts `r`, `a`, `b`, and `k` are atoms. `prf` is a gate: `$-([j=@ r=@] @)`. `m` is an atom. #### Produces An atom. #### Source ```hoon ++ feen |= [r=@ a=@ b=@ k=@ prf=$-([j=@ r=@] @) m=@] ^- @ =/ c (fen r a b prf m) ?: (lth c k) c (fen r a b prf c) ``` --- ### `+fe:ob` An internal function to [`+fee`](#feeob). Note that this implementation differs slightly from the reference paper to support some legacy behaviour. #### Accepts `r`, `a`, and `b` are atoms. `prf` is a gate: `$-([j=@ r=@] @)`. `m` is an atom. #### Produces An atom. #### Source ```hoon ++ fe |= [r=@ a=@ b=@ prf=$-([j=@ r=@] @) m=@] =/ j 1 =/ ell (mod m a) =/ arr (div m a) |- ^- @ :: ?: (gth j r) ?. =((mod r 2) 0) (add (mul arr a) ell) :: :: Note that +fe differs from B&R (2002)'s "fe" below, as a previous :: implementation of this cipher contained a bug such that certain inputs :: could encipher to the same output. :: :: To correct these problem cases while also preserving the cipher's :: legacy behaviour on most inputs, we check for a problem case (which :: occurs when 'arr' is equal to 'a') and, if detected, use an alternate :: permutation instead. :: ?: =(arr a) (add (mul arr a) ell) (add (mul ell a) arr) :: =/ f (prf (sub j 1) arr) :: =/ tmp ?. =((mod j 2) 0) (mod (add f ell) a) (mod (add f ell) b) :: $(j +(j), ell arr, arr tmp) ``` --- ### `++fen:ob` Reverse [`+fe`](#feob) This is an internal function to [`+feen`](#feenob) Note that this implementation differs slightly from the reference paper to support some legacy behaviour. #### Accepts `r`, `a` and `b` are atoms. `prf` is a gate: `$-([j=@ r=@] @)`. `m` is an atom. #### Produces An atom. #### Source ```hoon ++ fen |= [r=@ a=@ b=@ prf=$-([j=@ r=@] @) m=@] =/ j r :: =/ ahh ?. =((mod r 2) 0) (div m a) (mod m a) :: =/ ale ?. =((mod r 2) 0) (mod m a) (div m a) :: :: Similar to the comment in +fe, +fen differs from B&R (2002)'s "fe^-1" :: here in order to preserve the legacy cipher's behaviour on most inputs. :: :: Here problem cases can be identified by 'ahh' equating with 'a'; we :: correct those cases by swapping the values of 'ahh' and 'ale'. :: =/ ell ?: =(ale a) ahh ale :: =/ arr ?: =(ale a) ale ahh :: |- ^- @ ?: (lth j 1) (add (mul arr a) ell) =/ f (prf (sub j 1) ell) :: :: Note that there is a slight deviation here to avoid dealing with :: negative values. We add 'a' or 'b' to arr as appropriate and reduce :: 'f' modulo the same number before performing subtraction. :: =/ tmp ?. =((mod j 2) 0) (mod (sub (add arr a) (mod f a)) a) (mod (sub (add arr b) (mod f b)) b) :: $(j (sub j 1), ell tmp, arr ell) ``` --- ### `++eff:ob` murmur3-based pseudorandom function. 'F' in B&R (2002). - `j` is a number between 0 and 3, selecting the seed with that index in [+raku](#rakuob). - `r` is an atom with a maximum length of two bytes. This is an internal function of [`+feis`](#feisob) and [`+tail`](#tailob). #### Accepts `j` is an atom. `r` is an atom. #### Produces An atom. #### Source ```hoon ++ eff |= [j=@ r=@] ^- @ (muk (snag j raku) 2 r) ``` #### Example ``` > (eff:ob 0 'ab') 1.178.819.349 ``` --- ### `++raku:ob` Key list Produces a list of arbitrary hexademical keys for use with [`+eff`](#effob). #### Produces A list of atoms of aura `@ux` (hexadecimal). #### Source ```hoon ++ raku ^- (list @ux) :~ 0xb76d.5eed 0xee28.1300 0x85bc.ae01 0x4b38.7af7 == ``` #### Examples ``` > raku:ob ~[0xb76d.5eed 0xee28.1300 0x85bc.ae01 0x4b38.7af7] ``` ---