# 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]
```

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.urbit.org/hoon/stdlib/3f.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
