# 3f: Scrambling

## `+un` <a href="#un" id="un"></a>

Reversible scrambling.

A core that contains arms that perform reversible scrambling operations. Used in the `@p` phonetic base.

#### Source

```hoon
++  un
  |%
```

***

### `+wren:un` <a href="#wrenun" id="wrenun"></a>

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` <a href="#wredun" id="wredun"></a>

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` <a href="#xafoun" id="xafoun"></a>

Add modulo 255.

Produces the sum of two `$atom`s 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` <a href="#xaroun" id="xaroun"></a>

Subtract modulo 255.

Produces the sum of two `$atom`s 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` <a href="#zaftun" id="zaftun"></a>

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` <a href="#zartun" id="zartun"></a>

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` <a href="#zyftun" id="zyftun"></a>

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` <a href="#zyrtun" id="zyrtun"></a>

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` <a href="#ob" id="ob"></a>

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` <a href="#feinob" id="feinob"></a>

Conceal structure, v3.

`+fein` conceals planet-sized `$atom`s. 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` <a href="#fyndob" id="fyndob"></a>

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` <a href="#feisob" id="feisob"></a>

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` <a href="#tailob" id="tailob"></a>

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` <a href="#feeob" id="feeob"></a>

"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 `$atom`s.

`.prf` 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` <a href="#feenob" id="feenob"></a>

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 `$atom`s.

`.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` <a href="#feob" id="feob"></a>

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 `$atom`s.

`.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` <a href="#fenob" id="fenob"></a>

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 `$atom`s.

`.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` <a href="#effob" id="effob"></a>

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` <a href="#rakuob" id="rakuob"></a>

Key list.

Produces a list of arbitrary hexademical keys for use with [`+eff`](#effob).

#### Produces

A list of `$atom`s 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]
```

***
