But, *concretely*, there is a symmetry between

- Stream cipher: map a fixed-length random input to a variable-length random output
- Hash function: map a variable-length random input to a fixed-length random output

```
def f(k):
n = 2 << k
q = 2
i = 1
while q != n:
i *= q
q <<= 1
return i
```

The Elixir translation is roughly the following:

```
def f(k) do
n = 2 <<< k # Remember to add "use Bitwise" at the top of the module
q = 2
i = 1
# (Storing the output into a tuple for reasons that will be explained later)
{i, _, _} = Stream.unfold({q, i}, fn # Initial values: current scope's q and i
{^n, _} -> nil # Loop halt condition: q == n (fixing the current scope's value of n)
{q, i} -> # Loop takes 2 arguments: q, i (inside a tuple)
i = i * q
{ # Return a 2-tuple to the `Stream.unfold` interface:
# 1st element gets yielded to the outer scope:
{i, :fyi, "You can return multiple values here if you want to"},
# 2nd element is fed back in as the argument to the next iteration of the loop:
{q <<< 1, i}
}
end)
|> Enum.take(-1) # Stream.unfold yields all values; only take the last
|> hd # Convert 1-element list into its component element
i
end
```

Generalizing further, we get:

```
hd(Enum.take(Stream.unfold({nil, VARS}, fn
{:halt, _} -> nil
{_, VARS} ->
WHILE_BODY(VARS) # _do_ modify VARS within this
{RETVAL(VARS), {if(EXIT_PREDICATE(VARS), do: :halt), VARS}}
end), -1))
```

(where `VARS`

may be either a bare variable or a tuple of them)

TODO: translate that last codeblock into `defmacro while…`

Of course, the above code is a **maximalist, generalizable example**—it is a **template** that you can take and fill with the most convoluted looped code you care to write (so long as you enumerate the variables that get changed each loop and shunt them away into the return value); in reality, computing the above function *per se* would be very simple since it's inherently a kind of accumulation; something like the following would do:

```
def f(k) do
q = 2
Enum.product(Stream.map(0..(k-1), fn k -> (q <<< k) end))
end
```

]]>- Take your (infinite) random bitstream as the binary digits ("fractional part") of random
**real**$r\in\left[0,1\right)$

Specifically: $r=\sum_{i=1}^{\infty}{\text{bit}_i 2^{-i}}$ - Read out
*only*as many digits of $r$ as are required to determine the value of $\left\lfloor rn\right\rfloor$ - You now (clearly) have fairly chosen $\leftarrow_{$}\left\{0,1,\cdots,n-1\right\}$
- For the next number, resume reading bits from the stream where this number left off

While it's easily-shown that no single-draw algorithm can be perfectly optimal, this algorithm *is* noticeably more efficient than rejection sampling in the single-draw case (and Lumbroso reminds us that this it is, obviously, also perfectly compatible with arithmetic-coded batching of the draws (left as an exercise for the reader)).

```
from fractions import Fraction
from random import getrandbits
def educational_randbelow(n):
# performs VERY poorly CPU-wise --
# for illustration only!
if n <= 1:
# A random integer "below" 1 must be 0
return 0
k = (n-1).bit_length()
if n == 2 ** k:
# Ironically, this interpretation
# of the algorithm
# doesn't handle the
# trivial case well...
# handle it specially:
return getrandbits(k)
# i represents the current level of "detail" we have on r,
# telling us how MANY bits of it we have uncovered so far:
i = 1
# next is the value r (from the equation):
# (it starts out VERY coarse, just i=1 bit of detail!)
# (*technically, it is a lower bound on r --
# it tells us AT LEAST how big r is known
# to be based on what we've seen of it.)
r = Fraction(getrandbits(1), 2**i)
# this next number is how big we KNOW
# that r can NEVER QUITE reach; if
# 100% of our "random" bits from here on out
# were high, it would APPROACH that value:
r_upperbound = r + Fraction(1, 2**i)
# if int(n * r) != int(n * r_upperbound)
# then that means that we don't yet have
# enough detail about our random number
# to see exactly what the true integer
# value of n*r should be
while int(n * r) != int(n * r_upperbound):
# Just keep resolving more
# bits of 0 <= r < 1
# until a number is
# homed-in-on unambiguously
i += 1
r += Fraction(getrandbits(1), 2**i)
r_upperbound = r + Fraction(1, 2**i)
# Once int(n * r) == int(n * r_upperbound),
# the while-loop will break, since resolving
# more bits of r would be pointless
# -- time to return the random number!
return int(n * r)
```

With one helping of mathematical intuition, two helpings of high-school algebra, and an invested afternoon, you can eliminate all the Fraction objects in the above example to MASSIVELY improve performance:

```
def randbelow(n):
if n <= 1:
return 0
k = (n - 1).bit_length()
a = getrandbits(k)
b = 2 ** k
if n == b:
return a
while (n * a // b) != (n * (a + 1) // b):
a = (a * 2) | getrandbits(1)
b = b * 2
return n * a // b
```

Below here is an adaptation **from the paper itself**; it runs far faster even than the above optimization (*and* has integrated handling of powers-of-2), but I couldn't possibly explain to you at this time just how or why *it is equivalent to* the above code. Perhaps I'll understand it after more pondering, someday:

Python

```
def randbelow(n):
"""Fast Dice Roller, Lumbroso, 2013"""
a = 0
b = 1
while True:
a = (a * 2) | getrandbits(1)
b = b * 2
if b >= n:
if a < n:
return a
a = a - n
b = b - n
```

C

```
uintmax_t randbelow(uintmax_t n, bool (*flip)())
// Fast Dice Roller
// Lumbroso, 2013
{
uintmax_t a = 0;
uintmax_t b = 1;
while (1) {
a = (a << 1) | flip();
b = b << 1;
if ( b >= n ) {
if ( a < n ) return a;
else
{
a = a - n;
b = b - n;
}
}
}
}
bool flip()
// example fair coin-flip function
{
return (rand() > RAND_MAX/2);
}
```

JS

```
function randbelow(n, getrandbit=()=>(Math.random() > 1/2)) {
// Fast Dice Roller
// Lumbroso, 2013
const _int = m => n.__proto__.constructor(m);
const [_0, _1] = [_int(0), _int(1)];
let a = _0;
let b = _1;
while( true ) {
a = (a << _1) + _int(getrandbit());
b = b << _1;
if ( b >= n ) {
if ( a < n ) return a;
else
{
a = a - n;
b = b - n;
}
}
}
}
```

]]>`sudo systemctl restart systemd-resolved`

]]>`127.0.0.53`

is returning painfully stale results, flush them with this command:
`sudo systemctl restart systemd-resolved`

]]>I have crafted thus far all characters in IBM 437, Windows-1252, and the Macintosh Cyrillic codepage.

(Original work; hereby published under a dual license CC0+WTFPL.)

Could be useful for very small LCD displays, or for fitting an entire movie script on your monitor at once.

It is not finished yet; my next goal is to figure out how to create one of these so I can actually *use* the thing… then I'll worry about adding more characters. (Fontforge is *waay* too sophisticated for this use-case, though, so it has ended up screwing up the font every time I tried to render an `.obt`

file: the letters all had "shaved tops", and the UI element to set their height manually was greyed-out. Hmm…)

```
from PIL import Image
import struct, csv, gzip
# USAGE:
# python3 make_psf.py 6x7 cp437_tinyfont.gif unicode_cp437.tsv 437-Handmade5x6.psf2.gz && setfont -v 437-Handmade5x6.psf2.gz
# python3 make_psf.py 6x7 cp437_tinyfont.gif unicode_x1252.tsv x1252-Handmade5x6.psf2.gz && setfont -v x1252-Handmade5x6.psf2.gz
PSF2_MAGIC = b'\x72\xb5\x4a\x86'
PSF2_HAS_UNICODE_TABLE = 0b1
PSF2_MAXVERSION = 0
PSF2_SEPARATOR = b'\xFF'
PSF2_STARTSEQ = b'\xFE'
psf2_header = struct.Struct('<4sIiIII2I')
# PCF IS WIP NOT YET IMPLEMENTED #
# https://fontforge.org/docs/techref/pcf-format.html
PCF_MAGIC = b'\x01FCP'
PCF_PROPERTIES = 0b000000001
PCF_ACCELERATORS = 0b000000010
PCF_METRICS = 0b000000100
PCF_BITMAPS = 0b000001000
PCF_INK_METRICS = 0b000010000
PCF_BDF_ENCODINGS = 0b000100000
PCF_SWIDTHS = 0b001000000
PCF_GLYPH_NAMES = 0b010000000
PCF_BDF_ACCELERATORS = 0b100000000
PCF_DEFAULT_FORMAT = 0x000
PCF_INKBOUNDS = 0x200
PCF_ACCEL_W_INKBOUNDS = 0x100
PCF_COMPRESSED_METRICS = 0x100
PCF_GLYPH_PAD_MASK = 0b000011
PCF_BYTE_MASK = 0b000100
PCF_BIT_MASK = 0b001000
PCF_SCAN_UNIT_MANK = 0b110000
pcf_header_1 = struct.Struct('<4sI')
pcf_header_2 = struct.Struct('<IIII')
def im2glyphs(im, w, h):
for y in range(0, im.height, h):
for x in range(0, im.width, w):
yield im.crop((x, y, x+w, y+h))
def _makeheader(glyphs, *, ver=PSF2_MAXVERSION, flags=0):
n = len(glyphs)
assert len(set(glyph.size for glyph in glyphs)) == 1
w, h = glyphs[0].size
glyphsize = h * ((w + 7) // 8)
#glyphsize = -(w * h // -8)
return psf2_header.pack(PSF2_MAGIC, ver, psf2_header.size, flags, n, glyphsize, h, w)
def _makebody(glyphs):
assert len(set(glyph.size for glyph in glyphs)) == 1
for glyph in glyphs:
yield glyph.convert('1').tobytes()
def _makeuctable(unicodemap):
for position in unicodemap:
for sequence in position:
yield PSF2_STARTSEQ
yield sequence.encode("utf-8")
yield PSF2_SEPARATOR
def makepsf2(size, im, out, unicodemap=None):
global glyphs # for debugging, run python -i
glyphs = list(im2glyphs(im, *size))
flags = 0
if unicodemap is not None:
flags |= PSF2_HAS_UNICODE_TABLE
else:
assert len(glyphs) == 256
out.write(_makeheader(glyphs, flags=flags))
for chunk in _makebody(glyphs):
out.write(chunk)
if unicodemap is not None:
for chunk in _makeuctable(unicodemap):
out.write(chunk)
if __name__ == '__main__':
import sys
size = map(int, sys.argv[1].split('x'))
im = Image.open(sys.argv[2])
with open(sys.argv[3], 'r') as f:
r = csv.reader(f, delimiter='\t')
unicodemap = list(r)
if unicodemap[0][0] == '':
unicodemap[0][0] = '\u0000'
if unicodemap[255][0] == '\x20' and unicodemap[0x20][0] == '\x20':
unicodemap[255][0] = '\u00A0'
with gzip.open(sys.argv[4], 'wb') as f:
makepsf2(size, im, f, unicodemap)
```

"" ☺ ☻ ♥ ♦ ♣ ♠ • ◘ ○ ◙ ♂ ♀ ♪ 𝅘𝅥𝅮 ♫ ☼ ► ▶ ▸ ◄ ↕ ᛨ ‼ ¶ § ▬ ↨ ↑ ᛏ ↓ → ← ∟ ↔ ▲ ▼ " " ! ǃ ⵑ """" # $ % ٪ ⁒ & ' ʻ ʹ ˈ ʹ ᑊ ꞌ ( ❲ ) ❳ * ∗ 𐌟 + , ¸ ؍ ‚ ꓹ - ˗ ‐ ‑ . ܁ ܂ ․ ꓸ 𝅭 / ᜵ ∕ 〳 𝈺 0 1 2 3 З Ӡ 4 5 6 б 7 8 9 : ː ˸ ։ ׃ ܃ ܄ ः ઃ ᛬ ᠃ ᠉ ⁚ ∶ ꓽ ꞉ ︰ ： ; ; < ᐸ 𝈶 = > ᐳ 𖼿 𝈷 ? @ A Α А B Β В C Ϲ С D E Ε Е F G H Η Н I Ι І Ӏ J Ј K Κ К L M Μ М N Ν O Ο О P Ρ Р Q Ԛ R S Ѕ Ꚃ T Τ Т U V W Ԝ X Χ Х Y Υ Ү Z Ζ [ \ ] ^ ˄ ˆ _ ` a а b c с d e е f g h һ i і j ј k κ l m n o ο о p р q ԛ r s ѕ t u v w ԝ x х y γ у ү z { | ӏ } ~ ⌂ 🏠 Ç ü é â ä ӓ à å ç ς ҫ ê ë ё è ѐ ï ϊ ї î ì Ä Ӓ Å Å É æ ӕ Æ Ӕ ô ö ӧ ò û ù ÿ ӱ Ö Ӧ Ü ¢ £ ¥ ₧ ƒ á í ó ú ñ Ñ ª º ¿ ⌐ ¬ ½ ¼ ¡ « » ░ ▒ ▓ │ ┤ ╡ ╢ ╖ ╕ ╣ ║ ╗ ╝ ╜ ╛ ┐ └ ┴ ┬ ├ ─ ┼ ╞ ╟ ╚ ╔ ╩ ╦ ╠ ═ ╬ ╧ ╨ ╤ ╥ ╙ ╘ ╒ ╓ ╫ ╪ ┘ ┌ █ ▄ ▌ ▐ ▀ α ß β Γ Г Г π Σ σ µ μ τ ꚍ Φ Ф Θ Ѳ Ө Ω Ω δ ∞ ꚙ φ ε є ɛ ∩ ≡ Ξ ± ≥ ≤ ⌠ ⌡ ÷ ≈ ° ∙ · 𐩐 ٠ ۰ √ ⁿ ² ■ " "

○ ■ ↑ ᛏ ↓ → ← ║ ═ ╔ ╗ ╚ ╝ ░ ▒ ► ▶ ▸ ◄ │ ─ ┌ ┐ └ ┘ ├ ┤ ┴ ┬ ♦ ┼ █ ▄ ▀ ▬ " " ! ǃ ⵑ """" # $ % ٪ ⁒ & ' ʻ ʹ ˈ ʹ ᑊ ꞌ ( ❲ ) ❳ * ∗ 𐌟 + , ¸ ؍ ꓹ - ˗ ‐ ‑ . ܁ ܂ ․ ꓸ 𝅭 / ᜵ ∕ 〳 𝈺 0 1 2 3 З Ӡ 4 5 6 б 7 8 9 : ː ˸ ։ ׃ ܃ ܄ ः ઃ ᛬ ᠃ ᠉ ⁚ ∶ ꓽ ꞉ ︰ ： ; ; < ᐸ 𝈶 = > ᐳ 𖼿 𝈷 ? @ A Α А B Β В C Ϲ С D E Ε Е F G H Η Н I Ι І Ӏ J Ј K Κ К L M Μ М N Ν O Ο О P Ρ Р Q Ԛ R S Ѕ Ꚃ T Τ Т U V W Ԝ X Χ Х Y Υ Ү Z Ζ [ \ ] ^ _ ` a а b c с d e е f g h һ i і j ј k κ l m n o ο о p р q ԛ r s ѕ t u v w ԝ x х y γ у ү z { | ӏ } ~ € ‚ ƒ „ … † ‡ ˆ ˄ ‰ Š ‹ Œ Ž ‘ ’ “ ” • – — ˜ ™ š › œ ž Ÿ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ "" ® ¯ ° ± ² ³ ´ µ μ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Ӓ Å Å Æ Ӕ Ç È É Ê Ë Ì Í Î Ï Đ Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã å ä ӓ æ ӕ ç ς ҫ è ѐ é ê ë ì í î ï ð ∂ ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ]]>

`python3 -m pip install --user git+https://git.code.sf.net/p/mcomix/git`

(you're doing it as your own user because you don't want sweeping system changes for something like an unstable build of a comic book viewer)

but it won't compile due to weird and inscrutable errors

the Debian packages you *must* first install are: `libgirepository1.0-dev libcairo2-dev`

(yes, the development headers)

This section defines what is now known as the X25519 function.

Theorem 2.1: Let $p$ be a prime number with $p\geq 5$. Let $A$ be an integer such that $A^2 – 4$ is not a square modulo $p$. Define $E$ as the elliptic curve $y^2=x^3+Ax^2+x$ over the field $\mathbb{F}_p$. Define $X_0:E\left(\mathbb{F}_{p^2}\right)\to\mathbb{F}_{p^2}$ as follows: $X_0\left(\infty\right)=0;X_0\left(x,y\right)=x$. Let $n$ be an integer. Let $q$ be an element of $\mathbb{F}_p$. Then there exists a unique $s\in\mathbb{F}_p$ such that $X_0\left(nQ\right)=s$ for all $Q\in E\left(\mathbb{F}_{p^2}\right)$ such that $X_0\left(Q\right)=q$.In particular, define $p$ as the prime $2^{255}-19$. Define $\mathbb{F}_p$ as the prime field $\mathbb{Z}/p=\mathbb{Z}/{(2^{255}-19})$. Note that $2$ is not a square in $\mathbb{F}_p$; define $\mathbb{F}_{p^2}$ as the field $\left(\mathbb{Z}/{(2^{255}-19)}\right){[\sqrt{2}]}$. Define $A=486662$. Note that $486662^2-4$ is not a square in $\mathbb{F}_p$. Define $E$ as the elliptic curve $y^2=x^3+Ax^2+x$ over $\mathbb{F}_p$. Define a function $X_0: E\left(\mathbb{F}_{p^2}\right)\to\mathbb{F}_{p^2}$ as follows: $X_0\left(\infty\right)=0;X_0\left(x,y\right)=x$. Define $E$ as the elliptic curve $y^2=x^3+Ax^2+x$ over $\mathbb{F}_p$. Define a function $X: E\left(\mathbb{F}_{p^2}\right)\to\left\{\infty\right\}\cup\mathbb{F}_{p^2}$ as follows: $X\left(\infty\right)=\infty;X\left(x,y\right)=x$.

Given $n\in 2^{254}+8\left\{0,1,2,3,\ldots,2^{251}-1\right\}$ and $q\in\mathbb{F}_p$, the $\text{X25519}$ function produces $s$ in Theorem 2.1.

Now $\text{X25519}:\left\{\text{X25519 secret keys}\right\}\times\left\{\text{X25519 public keys}\right\}\to{\{0,1,\ldots 2^{8}-1\}}^{32}$ is defined as follows. Fix $q\in\left\{0,1,\ldots,2^{256}-1\right\}$ and $n\in 2^{254}+\left\{0,1,2,3,\ldots,2^{251}-1\right\}$. By Theorem 2.1, there is a unique integer $s\in\left\{0,1,2,\ldots,2^{255}-20\right\}$ with the following property: $s=X_0\left(nQ\right)$ for all $Q\in E\left(\mathbb{F}_{p^2}\right)$ such that $X_0\left(Q\right)=q\text{ mod }2^{255}-19$. Finally, $\text{X25519}{(\underline{n},\underline{q})}$ is defined as $\underline{s}$. Note that $\text{X25519}$ is not surjective: in particular, its final output bit is $0$ and need not be transmitted.

The author then proceeds to give some highly applied implementation details to do with bit twiddling algebraic polynomials, reductions around the CPU register size for constant-time arithmetic and whatnot… but, if my understanding is correct, the above quote contains the full specification of the **function itself**, if you have enough mathematical knowledge to wring it out of there (left, canonically, as an exercise for the reader; the paper excuses its terseness by recommending some math textbooks).

There have been some fantastic attempts [Martin Kleppman; Bill Buchanan] to bridge this gap and explain the *core function* at a humanly-comprehensible level, but they, like the original paper, all jump straight from the mathematically pure high-level descriptions of "point operations on generating curves" to the extremely technical low-level "scalar multiplications with montgomery ladders", without ever taking a segue through "just normal numbers". If I cannot find such an explanation myself, I may have to learn the relevant mathematics and *write* one.

Though, perhaps crafting such a document wouldn't be worth the investment: X25519 isn't quantum-safe, and what may be the best upcoming quantum-safe algorithm (produced by—among others—the very same gentleman that made X25519) has already got a fantastic explainer by Ashley Valentijn of Syracuse University, published as her honors capstone project. Better, perhaps, to study up about that, instead.

]]>`ssh -Y $someoneElse@localhost`

, you probably noticed that the program you're operating runs quite sluggishly (at least compared to how it's "asposta" run or does when run normally).
You may have independently discovered this "cheesy" workaround (just a cleaner alternative to copying `~/.Xauthority`

):

`ssh -t $someoneElse@localhost "xauth add $(xauth list); DISPLAY=$DISPLAY $0"`

But here's a *far* cleaner option:

```
xhost +si:localuser:$someoneElse
ssh -o SendEnv=DISPLAY $someoneElse@localhost
```

Note you *may* have to reconfigure your server to allow this:

```
grep '^AcceptEnv.*DISPLAY' /etc/sshd\
|| ( sudo sed -e 's/^\(AcceptEnv\) /\1 DISPLAY ' -i /etc/ssh/sshd_config\
&& sudo service sshd restart
```

While you're at it, here's how you allow those programs to play audio (if your system has a PulseAudio setup like most these days):

```
pax11publish -S /run/user/$UID/pulse/native -e
setfacl -m u:$someoneElse:x /run/user/$UID /run/user/$UID/pulse
setfacl -m u:$someoneElse:rw /run/user/$UID/pulse/native
setfacl -m m::rwx /run/user/$UID/pulse
```

]]>I've adapted the exact command to be more suitable for general use:

```
sudo chgrp -v "$(id -g)" /dev/sr0 # or whatever
tar c\
-ML716800\
--format=posix\
-f "${f=$(mktemp -t tar-XXXXXXX.iso)}"\
-F 'cdrecord -eject "$TAR_ARCHIVE" && read -p "Insert CD #${TAR_VOLUME}, CLOSE THE TRAY, then press Enter:"'\
$files
# Don't forget to run this afterwards
# to avoid leaving an 0.68G junk file laying around:
rm -v "$f" ; unset f
```

This will simply burn a tape-archive-formatted sequence of CD-Rs that can be extracted back onto most Unix systems with `tar x -Mf "/dev/sr0"`

. The files inside this archive may be a gigabyte or larger; it'll cause no problems. Tar will automatically prompt you to load the next "tape" when it reaches the end of a volume.

The flag `-L716800`

simply caps the archives at 716800KiB = 734003200 bytes = 700MiB (734MB)—the standard bare minimum that even the cheapest mass-market bulk vendor won't undershoot.

```
/* ~/.mozilla/firefox/…/chrome/userContent.css */
/* Remove advertisements for Mozilla VPN */
@-moz-document url(about:privatebrowsing) {
.promo {
display: none;
}
}
```

]]>(Easy access: go to

`chrome`

(all-lowercase)`userContent.css`

(uppercase (Windows users: don't forget to show file extensions!)

```
/* Remove advertisements for Mozilla VPN */
@-moz-document url(about:privatebrowsing) {
.promo {
display: none;
}
}
```

`toolkit.legacyUserProfileCustomizations.stylesheets`

to `true`