
About us
We are currently busy researching effective uses and extensions of the wonderful Glamorous Toolkit, particularly in the realm of synthetic finetuning and dataset discovery.
If you can't find us, we're off somewhere with a book, or maybe writing Rust, Elixir, Smalltalk, or Elm torwards some kind of disjointed and barely out of reach purpose.
This site is also available on ipfs. If you have a modern
browser, like Brave, you can access it at: ipns://awfulsec.com
.
Each page is also made available in multiple helpful formats so that you can do cool things like browse in your terminal and use gpg to check the authenticity of each file.
Nav
- PGP
- Contact
- Blog
PGP
You can use PGP to encrypt messages only I can read.
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZkAHyhYJKwYBBAHaRw8BAQdA4ugvt0YJnV3CweFUtBtKPMZ0zN+BsIuhtAjW
snR/ZaO0HFRob21hcyA8dGhvbWFzQGF3ZnVsc2VjLmNvbT6ImQQTFgoAQRYhBJ1c
xm+hZBBNTyrPOY7IGahNN2x6BQJmQAfKAhsDBQkB4TOABQsJCAcCAiICBhUKCQgL
AgQWAgMBAh4HAheAAAoJEI7IGahNN2x6DCYA/2Gmne4Q/p2JxxXdWMtRFwVjutXp
y5YpGXFCtk2CDDjMAQDbQR0yLa9KIyjHb/UbPUkOF9WHHCyzXg4Eh9UjlPqTB7g4
BGZAB8oSCisGAQQBl1UBBQEBB0DI371Bfej4AFEV2w+dGqTLCwDoaF07isrCAfIb
OAfmBQMBCAeIfgQYFgoAJhYhBJ1cxm+hZBBNTyrPOY7IGahNN2x6BQJmQAfKAhsM
BQkB4TOAAAoJEI7IGahNN2x6PIQBANXwX5u41D1oJ41lpzcM2k3x66Kd5YWiujXB
HdBv0WnBAP9cOaQdFGExj3iYQu6fYIbKySTxaPHRlDHz0qFq8A2YDw==
=8v93
-----END PGP PUBLIC KEY BLOCK-----
Contact
Please feel free to reach out for whatever reason. Methods of contact are listed in descending order of formality.
Thomas
- email:
thomas@awfulsec.com
- pgp: ./pgp.html
Blog
- Modeling the transmission of Covid-19 with Smalltalk
- Meditations
- Short Story
- Lyrea Stop Using My Fucking Phone Number
- Add a Custom Theme to mdBook
- Hallucinatory Sensory Remix
- Dinoxor
- Generative Testing Inline Assembly in Rust
- Philadelphia Urban Gardening
Modeling the Transmission Rate of COVID-19 with SIR in Smalltalk
Using Glamorous Toolkit, PolyMath, Roassal2 and Ordinary Differential Equations
From Wikipedia:
The SIR model is one of the simplest compartmental models, and many models are derivatives of this basic form. The model consists of three compartments: S for the number of susceptible, I for the number of infectious, and R for the number of recovered or deceased (or immune) individuals. This model is reasonably predictive[citation needed] for infectious diseases that are transmitted from human to human, and where recovery confers lasting resistance, such as measles, mumps and rubella.
These variables (S, I, and R) represent the number of people in each compartment at a particular time. To represent that the number of susceptible, infected and recovered individuals may vary over time (even if the total population size remains constant), we make the precise numbers a function of t (time): S(t), I(t) and R(t). For a specific disease in a specific population, these functions may be worked out in order to predict possible outbreaks and bring them under control.
Lucky for us the PolyMath library contains everything we need to start solving Ordinary Differential Equations and even includes a Tutorial on working with the SIR model.
From the wiki:
|solver state system dt beta gamma values stepper diag|
dt := 1.0.
beta := 0.01.
gamma := 0.1.
system := PMExplicitSystem block: [ :x :t| |c|
c := Array new: 3.
c at: 1 put: (beta negated) * (x at: 1) * (x at: 2).
c at: 2 put: (beta * (x at: 1) * (x at: 2)) - (gamma * (x at: 2)).
c at: 3 put: gamma * (x at: 2).
c
].
stepper := PMRungeKuttaStepper onSystem: system.
solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt.
state := #(99 1 0).
values := (0.0 to: 200.0 by: dt) collect: [ :t| state := stepper doStep: state
time: t stepSize: dt ].
In order to begin using this code to create our own model we must first understand the dt
, beta
and gamma
variables.
dt
is a measure of time and in our model we'll use1.0
so that each step represents1 day
.beta
is the transmission rate. We'll discuss this further in the following section.gamma
is the recovery rate. We'll discuss this further in the following section.
The SIR Model
I found the best explanations of the SIR model to be this Wikipedia entry and the documentation of the R library ShinySIR.
From ShinySIR
:
In the simple SIR model (without births or deaths), susceptible individuals (S) become infected and move into the infected class (I). After some period of time, infected individuals recover and move into the recovered (or immune) class (R). Once immune, they remain so for life (i.e. they do not leave the recovered class). The corresponding equations are given by:
- \( \frac{dS}{dt} = - \beta {S}{I} \)
- \( \frac{dI}{dt} = \beta {S}{I} - \gamma I \)
- \( \frac{dR}{dt} = \gamma I \)
where
S
,I
, andR
, are the numbers of susceptible, infected, and recovered individuals in the population. Suppose the unit of time we are considering is days, then
- β is the transmission rate and βSI represents the number of susceptible individuals that become infected per day;
- γ is the recovery rate and γI is the number of infected individuals that recover per day;
- 1/γ is the infectious period i.e. the average duration of time an individual remains infected.
An important quantity of any disease model is the the reproductive number, R0, which represents the average number of secondary infections generated from one infectious individual in a completely susceptible population. For the SIR model,
\( R_0 = \beta N / \gamma, \)
where \( N = S + I + R \) is the total (constant) population size. Since R0 and the infectious period are more intuitive parameters, we use these as inputs for the built-in SIR model. We can then calculate β as:
\( \beta = R_0 \gamma / N. \)
It's important to note that:
- \( \beta \) is the mathematical notation for
beta
. - \( \gamma \) is the mathematical notation for
gamma
.
In order to calculate the beta
parameter I source \( R_0 \) from Report 3: Transmissibility of 2019-nCoV as 2.6
. This means that on average each infected person will infect 2.6 others. According to CoronaTracker: World-wide COVID-19 Outbreak Data Analysis and Prediction the average duration of recovery is 7.5 days
.
Given the average duration of recovery it's trivial to calculate our gamma
value:
\( \gamma = \frac{1}{D} \)
where \( D \) is the average duration of recovery.
| durationOfRecovery gamma |
durationOfRecovery := 7.5.
gamma := 1 / durationOfRecovery
Given \( R_0 \), \( \gamma \) and \( N \) (the total population size) it's trivial to calculate our beta
value:
We'll start by setting N
to the total population size of Florida. According to Google the population of Florida is 21.48 million
.
| durationOfRecovery gamma populationSize r0 beta |
durationOfRecovery := 7.5.
gamma := 1 / durationOfRecovery.
populationSize := 21480000.
r0 := 2.6.
beta := r0 * gamma / populationSize
We now have enough information to start simulating COVID-19 transmission across a population using SIR.
Simulating COVID-19 transmission in Florida
Let's plug the information we have into the ODE tutorial from PolyMath.
| dt durationOfRecovery gamma populationSize r0 beta solver state system values stepper |
dt := 1.0.
durationOfRecovery := 7.5.
gamma := 1 / durationOfRecovery.
populationSize := 21480000.
r0 := 2.6.
beta := r0 * gamma / populationSize.
system := PMExplicitSystem block: [ :x :t| |c|
c := Array new: 3.
c at: 1 put: (beta negated) * (x at: 1) * (x at: 2).
c at: 2 put: (beta * (x at: 1) * (x at: 2)) - (gamma * (x at: 2)).
c at: 3 put: gamma * (x at: 2).
c
].
stepper := PMRungeKuttaStepper onSystem: system.
solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt.
state := #(21480000 1 0).
values := (0.0 to: 180.0 by: dt) collect: [ :t| state := stepper doStep: state
time: t stepSize: dt ].
This results in a multi-dimensional array indexed by days from the start of the spread to the 180th day (~6 months.) Each entry in the array is an array containing the Susceptible, Infected, and Recovered individuals. This information is much easier for humans to digest when visualized. For this we'll use the wonderful Roassal2.
Let's take the values from our... uhhhh... values array and build some Roassal Data Frames.
| dt durationOfRecovery gamma populationSize r0 beta solver state system values stepper susceptible infected recovered b ds1 ds2 ds3 |
dt := 1.0.
durationOfRecovery := 7.5.
gamma := 1 / durationOfRecovery.
populationSize := 21480000.
r0 := 2.6.
beta := r0 * gamma / populationSize.
system := PMExplicitSystem block: [ :x :t| |c|
c := Array new: 3.
c at: 1 put: (beta negated) * (x at: 1) * (x at: 2).
c at: 2 put: (beta * (x at: 1) * (x at: 2)) - (gamma * (x at: 2)).
c at: 3 put: gamma * (x at: 2).
c
].
stepper := PMRungeKuttaStepper onSystem: system.
solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt.
state := #(21480000 1 0).
values := (0.0 to: 180.0 by: dt) collect: [ :t| state := stepper doStep: state
time: t stepSize: dt ].
susceptible := values collectWithIndex: [ :each :idx | Point x: idx y: (each at: 1) ].
infected := values collectWithIndex: [ :each :idx | Point x: idx y: (each at: 2) ].
recovered := values collectWithIndex: [ :each :idx | Point x: idx y: (each at: 3) ].
b := RTGrapher new.
ds1 := RTData new.
ds1 label: 'Susceptible'.
ds1 noDot.
ds1 points: susceptible.
ds1 connectColor: Color blue.
ds1 y: [ :v | v y ].
ds1 x: [ :v | v x ].
ds1 interaction popup text: [ :v | ((v key y) asInteger) asString, ' susceptible on day ', (v key x asString)].
b add: ds1.
ds2 := RTData new.
ds2 label: 'Infected'.
ds2 noDot.
ds2 points: infected.
ds2 connectColor: Color red.
ds2 y: [ :v | v y ].
ds2 x: [ :v | v x ].
ds2 interaction popup text: [ :v | ((v key y) asInteger) asString, ' infected on day ', (v key x asString)].
b add: ds2.
ds3 := RTData new.
ds3 label: 'Recovered'.
ds3 noDot.
ds3 points: recovered.
ds3 connectColor: Color green.
ds3 y: [ :v | v y ].
ds3 x: [ :v | v x ].
ds3 interaction popup text: [ :v | ((v key y) asInteger) asString, ' recovered on day ', (v key x asString)].
b add: ds3.
b addDecorator: (RTCursorFollower new color: Color gray).
b axisX title: 'Days'; noDecimal.
b axisY title: 'Population'; noDecimal.
b legend right.
b build view canvas buildMorph extent: 1000@500; exportAsPNG.
As you can see, this lays out our data in an easily digestable fashion. It shows the peak of the infections happening on day 84 with 5,143,437 individuals infected.
Our model is in no way precise and leaves out many factors such as the effects of social distancing, state measures to slow the spread, population density, age, etc. Even so, the peak infected rate seems quite high at over 5 million individuals while at the time of writing (midnight April 24, 2020) there are only 30,839 confirmed infected individuals in Florida..
Let's do a little investigating to see what the problem may be. We'll first change the Y-axis to our actual calendar date. The CDC confirmed the first two COVID-19 cases in Florida on March 1, 2020 so we'll change our Y-axis to start on March 1. The linked article also announces 2 initial cases so we'll change our starting state so that it repressents 2 infected individuals.
state := #(21480000 2 0).
The graph interactions are, sadly, lost when I export the Roassal visualizations to an image or even the javascript representation but as you can see in the screenshot from my Pharo image the number of infected on today's date is 297,236 individuals. Why is it so high? It seems as though our model is off by about 267,000 people!
We need to talk about testing. To date, the state of Florida has only tested 333,099 of it's 21.48 million inhabitants which is only 1.5 percent of it's population and, terrifyingly, of the 333,099 persons tested just over 9 percent tested positive for COVID-19. If we were to extrapolate that out to the total population then 1,988,663 people would currently test postive for the Corona virus. Extrapolating the ratio of infected to tested to the total population isn't going to give us an accurate estimation for a multitude of reasons but most notably because the 9% testing positive were presumably showing symptoms of the virus or are health care workers recently exposed to it. Nine percent of a total population seems quite high but the CDC estimates that between 3-11% of the United States population are infected with the common flu each year and with the revalations that carriers of the virus may remain asymptomatic the 297,236 infected to date that our model shows might not be as far off as it seems.
Let's run our model on another population, one in which testing is more widely available and reporting presumably more accurate, New York City. First we do a little refactoring, DRYing up the code a bit by referencing the populationSize
variable from the state
array and changing the population size to match that of New York City according to Google. The first reported case of Corona virus in New York City was also March 1, 2020 so our X-axis remains unchanged.
| dt durationOfRecovery gamma populationSize r0 beta solver state system values stepper susceptible infected recovered b ds1 ds2 ds3 |
dt := 1.0.
durationOfRecovery := 7.5.
gamma := 1 / durationOfRecovery.
populationSize := 8399000.
r0 := 2.6.
beta := r0 * gamma / populationSize.
system := PMExplicitSystem block: [ :x :t| |c|
c := Array new: 3.
c at: 1 put: (beta negated) * (x at: 1) * (x at: 2).
c at: 2 put: (beta * (x at: 1) * (x at: 2)) - (gamma * (x at: 2)).
c at: 3 put: gamma * (x at: 2).
c
].
stepper := PMRungeKuttaStepper onSystem: system.
solver := (PMExplicitSolver new) stepper: stepper; system: system; dt: dt.
state := { populationSize . 1 . 0 }.
values := (0.0 to: 180.0 by: dt) collect: [ :t| state := stepper doStep: state
time: t stepSize: dt ].
susceptible := values collectWithIndex: [ :each :idx | Point x: idx y: (each at: 1) ].
infected := values collectWithIndex: [ :each :idx | Point x: idx y: (each at: 2) ].
recovered := values collectWithIndex: [ :each :idx | Point x: idx y: (each at: 3) ].
b := RTGrapher new.
ds1 := RTData new.
ds1 label: 'Susceptible'.
ds1 noDot.
ds1 points: susceptible.
ds1 connectColor: Color blue.
ds1 y: [ :v | v y ].
ds1 x: [ :v | v x ].
ds1 interaction toggleDataset.
ds1 interaction popup text: [ :v | ((v key y) asInteger) asString, ' susceptible on ', ('March 1, 2020' asDate + v key x day) asDate asString].
b add: ds1.
ds2 := RTData new.
ds2 label: 'Infected'.
ds2 noDot.
ds2 points: infected.
ds2 connectColor: Color red.
ds2 y: [ :v | v y ].
ds2 x: [ :v | v x ].
ds2 interaction toggleDataset.
ds2 interaction popup text: [ :v | ((v key y) asInteger) asString, ' infected on ', ('March 1, 2020' asDate + v key x day) asDate asString].
b add: ds2.
ds3 := RTData new.
ds3 label: 'Recovered'.
ds3 noDot.
ds3 points: recovered.
ds3 connectColor: Color green.
ds3 y: [ :v | v y ].
ds3 x: [ :v | v x ].
ds3 interaction toggleDataset.
ds3 interaction popup text: [ :v | ((v key y) asInteger) asString, ' recovered on ', ('March 1, 2020' asDate + v key x day) asDate asString].
b add: ds3.
b addDecorator: (RTCursorFollower new color: Color gray).
b axisX
title: '';
labelRotation: -30;
labelConversion: [ :v | ('March 1, 2020' asDate + v day) asDate ].
b axisY title: 'Population'; noDecimal.
b legend right.
b build view canvas buildMorph extent: 1000@500; exportAsPNG.
To review the accuracy of our NYC model we first reference the number of Corona virus cases in NYC as of April, 26, 2020 which is 153,204. When we remove the Suscepible and Recovered lines and check the Infected on April, 26 we see our NYC model is much closer to reality with 147,108 infected individuals.
Now seems like a good time to abstract our code into classes to make it easier for us to run models. A live screencast is a great way to show how we can and turn our scripts into a collection of objects working together to achieve our goals with the the added bonus of extending the package to fit more models. I'll consider recording a live screencast within the near future.
In the meantime you can find the library I've already abstracted on Github at: https://github.com/graves/2019-nCov
Meditations
In Marcus Aurelias's Meditations he states "Some things are hurrying to come into being, others are hurrying to be gone, and part of that which is being born is already extinguished. Flows and changes are constantly renewing the world, just as the ceaseless passage of time makes eternity ever young. In this river, then, where there can be no foothold, what should anyone prize of all that races past him? It is as if he were to begin to fancy one of the little sparrows that fly past - but already it is gone from his sight. Indeed this is the nature of our very lives - as transient as the exhalation of vapour from the blood or a breath drawn from the air. No different from a single breath taken in and returned to the air, something which we do every moment, no different is the giving back of your whole power of breathing - acquired at your birth just yesterday or thereabouts - to that world from which you first drew it."
I just pasted that quote in two roundtrips from my iPhone to my Macbook because the statement was spread across two pages of a tiny book.
Technology can be an incredible thing. My hand is a bit squished owing to the tension of the spine of a newly purchased book and my unwillingness to feed into vanity. The first highlighted part, "Some things are hurrying to come into being, others are hurrying to be gone, and part of that which is being born is already extinguished. Flows and changes are constantly renewing the world, just as the ceaseless passage of time makes eternity ever young." perfectly encapsulates how I feel about that rapid changes in software today and the company I work for's inability to adopt better tools. It is their inability to do this that has forced me to retire my position there.
Yet I am still stuck, laboring on this never ending task of proving it to them. While they languish, the tools are already here. They are safer (no memory corruption,) faster (native compilation,) better supported (not abandoned,) and easier to reason about (they were built on the most modern operating systems available, containing the necessary software to debug issues and trace the path of execution as far as those operating systems allow.) Somehow, mystically, magically, or fated through divine intervention (as i scratch my head like a tattooed deranged Albert Einstein) the software that allows these things has not progressed since the start of my career here, three years ago. I know that because I constantly revisit that software and the best is still the best, it's written in Rust, and the most important tools save for exa (which has been abandoned and whose mantel has been picked up by eza) are still the same and our teams ability to solve problems as a team consistently declines.
Not a single engineer, product liaison, quality assurance engineer, or engineering manager has turned on their camera since the first day I began this job. Members of other teams fly into our daily standup meetings, or weekly review meetings, or weekly planning meetings, camera on ready to work. Not a single member of our team does. When I offered to jump on cam to review our issues adopting technology Apeachalonius was coincidentally sick and no one on our team was ready to speak to the issues. The last time a manager forced the issue, made themselves visibly vulnerable to discuss anything was Admiral Hayden who has been promoted up the chain enough that he need not force the issue. Any time I attempted to set a trend by appearing on camera, whether it be during standups or manager lead 1 on 1 meetings I was met with swift resistance from the plethora of security settings, the rearranging of these settings due to operating system updates and the impedance caused by the settings of the software that run on those operating systems governing the same pathway from the camera to the operating system. Those issues have been resolved in my office, on my company provided laptop. Most of team members don't even use photographs for avatars.
Spread across the inside spine of the book is sprawled "No different from a single breath taken in and returned to the air, something which we do every moment, no different is the giving back of your whole power of breathing - acquired at your birth just yesterday or thereabouts - to that world from which you first drew it." This also took two roundtrips from my phone to this laptop, this technology is revolutionary. It's extremely simple to use, in this case for one who has at least one working optic nerve and a single digit capable of pressing the screen of the phone and the fine motor skills required to follow the path of the hilighted, or unhilighted text on the screen. Any text on the screen.
I can't help but laugh every time I read this passage. Marcus Aurelius necessarily easing his conscience about the slaughter he's witnessed and taken part in and me, an atom to Software Engineering imagining all of the open-source software rising up to dethrone the best, blinking out existence with each breath. Cameras on tomorrow fellas, unless of course you have a legitimate reason not to.
Short Story
The world is collapsing. Collapsing in on itself I can never be certain but collapsing from great heights it has not. I blankly stare into the mirror, blink twice and am greeted by a pair of sunken in doe shaped eyes. Set wider across a slightly pointed once beautiful face. The bathroom is a pallid yellow color. Not the pale yellow of the sun as it sets just before autumn, nor the sickly color one might imagine pissing out after drinking raw milk but the uninspired default wall coloring of lower income housing that may be confused for public housing by any passer-by. I'm 40 years old and stand 5'10. Extremely attractive for my age is what I've been told but for every tabloid detailing my husband's torrid inclination of body, a Wall Street Journal article is born exposing my incompetence. To escape the monotony of decision making I escape by way of US 95 North to our sister state, Canada.
The psychiatrist's waiting room is bright. A kind older woman, with a pleasant English accent graces my ears from behind a tapped bell. Allowing me to summon her like dog or a child for dinner from wherever she could be hiding. Where could she be hiding? There is a plain white wooden door to my left, indistinguishable from any other wooden door bearing assenting panels, engraved to slope in four obtuse directions from the point at which they enter my vision. I don't stop to remember that shouting for help in a psychiatrist's office may not only disturb the assistant in the restroom, barely out of site to the right of the small counter but my induce a sort of catastrophe that would cause the most beautiful schizophrenic I know to bound out the window, wrists covered in gashes and leap out into the street like the Dachshund in that Todd Solondz movie about the increasingly depressing lives of the privileged. I see her burst through her glass cage, happy as can be. Wild and free from a large chunk of disgusting fibrous mass that I am compelled to help Mr. Psychiatrist wipe up by some force beyond reason.
That soothing feminine, faintly English voice assures me I can excuse myself outside for a smoke while she handles the mess. The cold winter enters through my nose and mouth at the same time the moment the window paned door shuts behind me. There's enough chill to the air that I can see my breath and a basketball sits dimpled in the shade of the surrounding trees. The psychiatrist's office is on the ground floor of a residential home like so many of their offices. They can't possibly live in these houses, so I imagine the tenants who live above. Husband, stethoscope to floor whispering fragments of diagnoses intertwined with the most mundane trivialities of life.
"Honey, the common schizophrenic of the DMT-5 variety builds battle figurines out of animals!" shouts the husband.
She dutifully jots "The animals, C, The DMT, Something about a Schizophrenic Bee."
"I've never even tried 2cb." she thinks.
She remembers an Erowid experiences article about the powerful hallucinogenic that is promised to increase the sex drive of any marriage so broken and begins writhing around on the floor in tears.
Mr. Sweet-pea hops to attention to ask her what he could have possibly done to provoke such a reaction and trips over Johnny's electronic phantasm they purchased just this week. He's bleeding from just above his eye, gouged deep into his eyebrow is a single metal resistor. The blood pools under his left eye running like garden hose of tears to his upturned nose and Mrs. Holland is crawling towards him like a hysterical Lisa Left-eye Lopez singing.
It's about this point I set one well pedicured foot down on each side of the ball. In one sweeping motion I caress the tense orange mass up the bridge of my tanned heal, I carry its inflated weight up the curvature of my slender calf muscle like the dip of a metallic Jersey shore roller coaster. I leap with my stationary foot and allow the branded mass to roll back down to my heal at the perfect moment in which my growth plate knocks into a rainbow motion appearing two feet above my flowing pitch black, shoulder-blade length mane. The regulation NBA sports ball claps my soft right palm. I clutch it and draw it back to me the way a server presents a tray of caviar. My slender left arm bends to perfect 45 degrees and I leap ever so slightly from my right sneaker, emblazoned with a secretive number of stripes and swish, nothing but net. I glance around furtively looking for a witness, someone to share the moment with but there's nobody. Mrs. Holland is engaged in the most passionate sex of her life after simply reading her husband the article. I briefly fumble around with my phone wondering who would even believe such an effortless accomplishment and how to explain how effortless it truly was without offending my tender sensibilities.
Mr. Psychiatrist's office is sterile in a sort of Buddhist kind of way. His diploma sits framed decoratively in the center of a white wall separating the two of us surrounded, on all sides by nothing but legal documents and regulations. The small postcard sized frame in which his family photo hides slides so gently into my brain as I recall he has one beautiful wife. She's holding their infant on a trip to the coast, his son stands proudly next to him. They're all beaming, radiating love in the perfect Hawaii morning sun. It never gets too hot in Hawaii. Before one can even taste the thick air in their lungs or feel a burdened movement the sky violently expels raindrops the size of tiny fists. Doctor Beamingson can barely look at me. He had rushed me into his office and scrolls intently up and down what limited information my experiences have so gracefully afforded us. I cordially ask about his education, and he declines to elaborate, I take a great interest in his grasp of medicine. My attention spotlights the room and travels from his attractive middle-aged visage to a tiny Zen fountain. A store-bought recreation of a practice that to be correctly initialized, that is; brought into this world, requires the observer to choose each individual marble stone and allow themselves to fall into the rhythm of grace. He combatively resists the uncomplicated decision I have already made and provides me a modest concession.
A frostbitten chill slams into my face like a train as I navigate an icy sidewalk holding me upright against my despair. The temperature is well below freezing and the powdered snow has been turned to glaciers by the rain who joins intermittently to mock this drab affair. Even the Douglas squirrels hide from the pitiful conditions of cars blazing by on their perilous escape from the ravaging cold. They sit atop the backs of Golden Retrievers marching defiantly around the garages in which our noble citizens should have stayed. There's not a Husky or Alaskan Malamute in sight. My tightly wound black yoga pants split directly up the curve of my thigh revealing what some may consider insincere intentions. A car horn joins the ocean's whisper through a clogged gutter to sing to me as a Mocking Bird, a Blue Jay guiding me to some other state. I drift silently along sidewalks of black ice, imitating the most graceful of figure skaters and try to remember if Tanya Harding was the hero or if she just ruined the Olympics and the last time I had the opportunity to ice skate, backwards.
I met a man in Florida who in a post-drug induced delirium had some creative solutions to everlasting life. Among other observations about the advancement of technology and troubles getting from one place to another. He rode a bike from his $100 a week recovery house to his part-time minimum wage job at Dollartree. He could not afford a bike lock because he could not even afford to eat and his bike was subsequently stolen from behind the Dollartree. He was, before his most recent troubles a Software Engineer. This part of Florida, just southeast of Naples is hot, humid, and disadvantaged. Its population is made up primarily of Hispanic residents with English speaking blacks and whites followed by French and Creole speaking Haitians. The Hispanic population had mostly immigrated from Cuba. A fact which he always researches online when going anywhere and had verified by speaking with the customers of the most pathetic Dollartree you could imagine. On a nowhere day, with nothing to do and his bunk mate freshly moved out he lay on freshly sheeted mattress atop a broken box spring in an empty hardwood room. Nothing but a single designer backpack containing a cheap Lenovo computer sit dormant by the bedside. He keeps fragmented notes of his thoughts in his phone.
They all look like this:
"On August 31, 2024, I learned how to represent bit nibbles with my fingers. My left fist plays the part of a hexadecimal registers. It allows me to count in hexadecimal while visualizing physical switches. I'm still working on doing this in three languages but I'm sure as hell closer than ever."
0x0
0x9
0xA
0xF
0x10
00000000
0000 1001
0000 1010
0000 1011
0000 1111
0001 0000
0xF - 0xA = 1001
0x11
0001 0010
0xFF
0011 0000
0xFF01
0011 0001
0xFF09
0011 1001
0xFF10
0011 1010
"Explain to me the canyon that separates motivation from intention. It seems to me that there is a factor involved in initiative."
"Structure society in such a way that removes rational motive from any crime thus any person committing a crime needs medical treatment or education."
"a spy for human suffering"
actionable intelligence gathered from
in-person community forums
geolocated grant money in/resources out
federal / state / local government led initiatives
medical data (anonymized statistics)
emergency medicine specific data
policing data
census data (economic, demographic)
voluntarily submitted data for religious organizations (The Church)
quantifiable results through short/medium/long term studies
smart humanist dAtA sCiEnTisT to make sense of the data, raw data-> actionable information
main view displayed intuitively on a Google Earth style map
community "needs" emanating from the verified geographic source
"needs" are weighted time series data
"you will have to deal with The Trolley Problem in all of its variations and do so with authority"
"Facebook style 'social' view for the olds. Intelligently restrictive to maintain intention (collaboratively lessen human suffering?)"
Rather than spend money he did not have or waste more of his life writing computer programs that no one but he uses, I'm fairly certain he just likes the look of them, he was thinking back on his near-death experience. Mining the depths of his darkest experience for inspiration he could somehow turn into a computer program. It doesn't take him long to know the path he is on is not one that can be serialized into bits and bytes. It's an uncomplicated theory with great implications. It goes like this, time can be divided infinitesimally. We, as conscious humans can only experience time as measured. Our experiences diverge in the ways in which we are capable of experiencing the most minute of measured time. These are our capabilities, and a ledger of these capabilities exists in a realm outside of measured time. What he had yet to discover is that this ledger is also balanced outside of measured time. The way he figures it, is that on our deathbeds we start to experience time in slower manner as all our bodily processes slow, most especially our neurological processes. Voices slow, your vision fades and the room seems to swirl around us uncomprehendingly. The slowing of the perception of time can be perfectly tuned to the slowing of our neurological processing abilities. The measurement of our senses is taken by how well our cells integrate information and distribute that information through our bodies and back to the observer. It's common knowledge that body releases DMT just before the moment of death. He whole-heartedly believes that two consenting parties are able to rebuild our realities before this dreaded moment of anticipation. It's paradoxical yet somehow logical to me. Why would our consciousness not instinctively resist death the way our bodies do? I leave Florida well before the next triplet of devastating hurricanes.
The hospital is a futuristic sterile kind of place. The automatic sliding doors framed in silver steel reflect a sharp beam of light into my eye as I hazard my approach. The security cameras hung from the rafters burn the screens of greyscale nondescript display panels. An L shaped reception desk, a taped off rectangular waiting area, a square holding pen and the ever-ominous egg shaped waiting chair stands apart from light blue plastic chairs that seem to wave of one material. When this wasteland’s sole inhabitant, an overly polite seamstress moonlighting as a nurse asks me what I'm in for, I pause. She races through her schedule as I race through experience blogs frantically piecing together some semblance of procedure.
She smiles.
I gasp.
"You can sit wherever you'd like" and she motions towards the stable.
I briefly make a show of surfing the wave chairs. I position one directly in front of the styrofoam colored egg chair. I place one stiletto heal on curvature that frames where the ideal ass must go and the other hooks the back of the chair. I can’t quite fit the chasm between the heel and the steep slippered portion of my ruby red attire around the impossible upper lip and tumble over the back of the chair and into my pod. One vegan leather fashion accessory left dangling on the chair. I glance over at the receptionist in sheer terror and find that her back is turned. I start desperately trying to uncork my heel from this godawful monstrous contraption before she can turn around and catch me in the act. I'm wrenching it by the straps and twisting it in a futile attempt to apply the correct amount of pressure at an angle just subtle enough to match curvature when the receptionist turns. Not all the way around, just enough to make noise but seems to be staring off into the back, towards hallways containing only alphanumeric symbols. I'm not wearing my glasses because they hurt my eyes and I'm content with dull blurring effect this creates on the world around me. There was probably a reason Phil Mickelson was pissed off all the time. It hurts, like physically hurts, often. I get back to work on this fucking object of unearned affection. By this point I'm sweating, glistening like a pig, my mascara is running and notice a tear in my stockings where a stylish run once may have made me smile. A Giant supermarket branded robot with two googly eyes rounds the corner blotting out intense symbolism of 2C and we begin our solitudinal death march to the pod.
The pod is an oblong, black and white sphere like the kind you'd find at a mall were you browsing for something that looks expensive and could match any room. And there are no robots, a team of medical professionals lead by Dr. Carter guide me around the corner. I look like I stumbled out of a dorm room and for a brief moment I prayed that they would gang bang me in this fucking thing. My hair perfectly tousled, one still pristine heel on, makeup like I had gagged the cock of the seamstress who so graciously permitted me entry. The only thing missing was a fucking cigarette. The medical procession must have attuned the same because not a single one of these cowboys seemed hot to trot and as a matter of medical necessity, I seemed inhuman to them. Dr. Carter asked the attending neurologist about his crystal wine glasses and he assured him that it was a chalice. I swear I saw an aluminum tumbleweed roll down the hall the moment they started blabbering about protein synthesis. One asks the other about their experience with whole wheat tortillas and another expounds their triumphs over the virtue of whole grains. Whole entire fucking grains, God please tell me you laced these with seeds about the crust. Let me wear them like rhinestone embroidery while I puke my fucking guts out cutting them off for the children. We navigate the hospital like an M.C. Escher sketch, you know the one? The fucked up impossible paradoxical staircases ascending and descending depending on how hard you squint your eyes. They've another where bats form a sort of positive and negative image, transforming the space where there was once yin and yang. By the time I was deluded enough to not ignore the conversation at hand we had made our way to my room. In it sat a single saltwater isolation tank with a television stapled to the wall. No other furniture, no waiting area, no family fair-thee-wells. The Doctor presses a button on his phone and the pod door slides open like the butterfly doors of Lamborghini. He motions towards the salty black abyss and I'm not sure whether to back myself in or dive in headfirst. I decide I'm going to risk it for the biscuit and back my ass up the stairs making that beep noise you hear when a giant slow moving construction vehicle crawls in reverse, that droning BEEP, BEEP, BEEP, BEEP and immediately regret it as this is the moment my ass has never looked so good. I look up for sign of tacit or even loving approval on the faces to those I must remain something of an object and haphazardly slip on porcelain structure of this death contraption.
I fall straight backwards, performing a sort of inverted belly flop and half-expect to be greeted by a lung full of Atlantic salt water. Instead, my skull hits the surface of the Dead fucking Sea. How much salt did they put in this fucking thing? They must have shot it in rocks out of the 12-gauge shotgun designed to keep Stranger Things monsters from finding their way back in. The collision creates the kind of mist you only find outside of the crowded shopping center of a Steven King novel. I think I must have blacked out when I hit my head because the smell is fucking awful and I have filled this body temperature-controlled pit of hell with the worst stench known to man, unattributed diarrhea leaking from an unknowable orifice. The pod ceiling slides open like the window-to-window sunroofs you can find in today’s fully electric vehicles. Vehicles capable of regenerative breaking, which is a creative method of harnessing all a vehicle’s capabilities to avert the worst effects of our impending climate catastrophe. Not only harnessing the carbon emission byproduct free, limitless power of the sun’s ultraviolet rays but mechanically distributing the energy created by the friction of a large mass slowing down back to the battery from whence it came. Six little heads come popping through the ceiling and I can no longer place their accents, they look so far away through the tint.
I'm gasping "I CAN'T BREATHE, I CAN'T BREATHE, I'M GONNA FUCKING PUKE" and one of these shiny head little fuckers cracks an air vent and says, "Hold on, I got you."
They tap the side of the pod, and a cool breeze appears from seemingly nowhere. I hear my last name for the first time and can't tell if he's said Mrs. or Ms.
They take my temperature.
"What brought you in here today?"
"Well Doctor, it would probably take longer than both our lifetimes combined to explain it to you."
Like explaining to the customs official in an airport tunnel the purpose of every assorted item in your bag. "What are you going to do pull me off the plane? If you were going to you already would have and all my shampoo is hotel variety sized."
An even smaller head in a misplaced Irish accent retorts "Have you seen what those Aveda girls can do? The colorists among them."
A larger purple head responds "Oh I modeled for them once."
And I'm like "Oh my god, a fucking human mannequin is giving me pointers about my hair, how did you even get here?!"
To that, which he definitely heard, he replied "8 years of college and a supportive girlfriend. How about yourself?"
And I'm like "8 years of hell after the purgatory my pervert husband drug me through."
Mr. Carter's voice booms through the pod like a hurricane thunderclap.
He asks, "Would you like to tell us about your husband or about the hell?" and I'd rather choke on my own shit than justify this man’s actions one more time.
I shout "You would be far more intrigued by my lovers!" and I think I hear him retch.
I must have because his stupid little head disappeared from my tinted pod roof and another slower voice yells "Sweetie, we've got a live wire." and winks.
As their voices slow the sound is akin to practicing an accent while conveying an emotion you don't or can't entirely feel, because you are reciting the emotions of a fictional character for public consumption, and then immediately switching gears by blasting music in your native tongue. An experience that can be had by all who don't keep their phones entirely on silent and dare to recite an audiobook in an accent only somewhat familiar to them. I'm told you can hear Nicole Kidman's accent if you really try hard enough.
I hear someone say "Aw, she thinks she's in Dogville."
I shout back "The set pieces look like your fucking hospital!"
There's only the low hum of the air conditioner, the swishing sound of a gentle underwater rip current, and the smell of rotting carcasses. Out of sheer boredom I try to recall their outfits. The letters staining the No Parking, Prince Symbol, parking lanes were a sort of deep aubergine color. Was the doctor even wearing a tie? Doctors don't wear ties. It must have been his stethoscope, navy blue and someone's eyes must have been green. I've always wanted to tear off a piece of my catholic skirt and choke a man to climax with it. Is that where Ralph Lauren got the idea for his Christmas themed patterns. Deep blue, hunter green flannel with ripped tassels ornamenting artificially worn ties. Hours start to slow into minutes. I make my 55th call for a donation to my husband's campaign. The incredulous woman on the phone shouts my name to man in the distance. I assume they're a woman because her eggshell tipped French manicure taps pastel pink floral Android case.
"Donations again?!" He shouts. "What have they done this time?"
My husband laughs and I drill him for the number of calories of each container of store-bought sauce in the house.
"The peanut flavored Tahini Paste is 70 calories per tablespoon" he proudly proclaims.
I intimate from his keen observation of physical health that he must be worth another phone call. My heartbeat slowing as a speckled golden mustard starts to surround the bathtub. I hear a vague Polish accent as a man no more than 25 years of age rips by in his Forever 21 adornment. The fading pink of a thrice donated and pitch-black cuff accented getup that matches his fake Givenchy sweat shorts. His long gallops give resonance to the fact that the leg holes have been cut too wide and the perfectly embroidered logo untangles itself into a hypnotized cobra hissing with a soft lisp.
"Reddit slash r slash fashionreps."
A place where perfectly reasonable Chinese citizens provide us with lesser standard of living, we so desperately deserve. They certainly win out over the bondage strapped, pervert pants and Peter Pan slippers with my feet placed curtly, toes pointing at each other. Minutes turn to seconds. A blue and white tie-dyed Bin Laden smiles peacefully over the garbage filled streets as I wind between the parked cars of the willing and the bodies of the required. Seconds to milliseconds and there is a Palestinian Keffiyeh draped around my neck. It took months of research just to figure out how to drape it around my neck in way that would not cause offense the affirmation comes as a Palestinian cab driver is nearly brought to tears by the fact he feels unsafe in his own city to make such a statement. A student had recently been shot in a fit of derangement under the sheltered burden of genocide, a fear that they had become everything that had been done to previous generations of relatives most had never met. An unresolved jealousy in the fact that they could not acknowledge the necessity of their desire to change. An assimilation already gone through by the majority of the living planet. Those of us who understand the scale of the numbers, can imagine unimaginable horrors, and were born with an intuitive sense of power dynamics already have a plan. A plan that would change humanity for the history of forever. Seconds turn to milliseconds. Goddamn, it's boring in this fucking hell hole. I pancake the shit that I'm standing into Naan, feel the warmth squish between my toes and realize I'm standing. How did I get here I mutely ponder and hear what I imagine a mostly deaf individual hears when the bass is maxed out in Dodge Neon with rattling windows. A limousine full of them comes tossing by.
They shout "CVL† SH‡† - ßƟD¥ ßΔGƵ, XXYYXX, GVCCI HVCCI, WHITE ROSE, SALEM, BLVCK CEILING - SHE IS NOT IN HEAVEN." Periodt.
Sophie dips her hand into the pond from her rooftop hideaway singing "Lemonade, le le Lemonade."
She's labored for years to get the pitches and tones to be perfectly original and they are. The planet has never heard anything like it. Charlie XCX or Hannah Diamond accompanies her like diamond enchanted faeries trailing every color of the rainbow. When the entire spectrum of ultraviolet light is combined the name of the color on which we've seemed to confer is white, but this color could be called anything we desire as a common description is unknown to man. Blank, rouge, noir, azur, grigio, call it 666 for all I fucking care but can we somehow leave it out of flowery exposition?
I'm suddenly getting my toad sucked off, knob slobbed before an intimate act of sex having. Excuse me bbgurl "Love in the making." It's the album where a beautifully pockmarked Asian woman sings a beautiful melody of her love being spurned by a boy whose mother would not approve. He doesn't notice her and I'm working out whether or not this woman can climax from vaginal penetration as I've never experienced one in the flesh. She definitely doesn't but at least she has the nerve not to fake it. We lay bask in the afterglow examining each other's bodies. Both giggling as we examine the symmetry. Our bed is in the room which would become the children's room, the children at their father's sleeping peacefully. We're swallowed by Bob's Discount Furniture's bunkbed Charlie's Angel carries me to the storage unit of a food pantry whose main attraction seems to be the most awful fruit gummy chips one without teeth could ever imagine. How long do they expect me to suck on this shit to attain the necessary number of calories to sustain human life. It works as a snack or as a subtle distraction from the death-defying misery that sits just 2 miles north. An easily walkable distance for a gracious privileged bipedal mammal that had once operated the other direction in search of a singular Hawaiian pizza. I remember his notes:
"How do I even explain that I may have saved a man from being executed by the police, a woman from being assaulted by that man, and walked away from an opportunity to use drugs all because I wanted to walk downtown to buy a bacon/pineapple pizza?"
Was that a suggestion, command, or a lesson? A drunken, extremely menacing black man was aggrieved over a slight that I had just missed. A terrified, young blonde Domino's pizza artisan bearing the brunt of his avarice. He was screaming for a free pizza. He had drunkenly wandered into this Domino's pizza on the busiest street of this city at midnight and demanded to know if they could even speak Arabic. Whether or not they knew the traditions in Turkey and had they no soul! No ability to grant a screaming, drunken underprivileged man a free pizza. The kitchen full of male employees sat stunned. They had no idea what to do as the man screamed and bashed the polyurethane separating divider that shields them from life or death. The door sits cracked open and I worry that he is going to crash through at any moment while I stand directly behind him, noticed by every person but him. The girl pleads to me with her eyes to do something, anything to diffuse this situation as no one has a phone in hand or seems keen to make a sudden movement towards anything, really. I announce my presence to this man by slightly ascenting to his assertion that no person in the richest country in the world should ever sleep hungry. I'm acutely aware that it's possible as I have done so many times, with and without the poverty or interdiction of illicit substances. I assure him that I am buying a pizza and that I will share it with him. I'm fucking starving and Domino's Hawaiian Pizza is my favorite cuisine on this Godforsaken planet, and I know that it's something I must soon give up. His violent mannerisms fade as he boisterously condescends that they do not even know the Arabic prayers. "They," I think and want to hug him and say my Lord and Savior please teach me in your infinite wisdom every prayer you know, "Sing them to me in Arabic, my liege."
But the man is piss drunk and can barely remember his own name. We walk back to his house, ignoring the motorcycles outside the bodega in which I greet the young man out front with a parting "Gracias," and the neon glow of the passing crowds while I look for a place to divvy up the slices. All I really want to do is go back home and eat but I'm sure this man must be some kind a Maliki. God's messenger from a cat I had once promised a new home free from neglect. He offers me shorts on his black and mild which I would have fucking loved but he was too busy knocking on car windows and shouting about cocaine to be bothered. By the time I asked the tobacco party was over, I take the plastic filter, strip it of its charred sickly-sweet contents that at one time I would have packed into a pipe and desperately search for a trash bin. There is never a conveniently placed trash bin when I need one. His drunken slurring and aggressive nature tell me it's time to get out of the street before this man gets severely injured. It could come from an aggrieved member of the public, or God-forbid the police but this man is a menace in his current state of intoxication. He believes me to be the white boy from the bar he had most recently attended. I concede that this is surely not the case as he begs me for whiteboy swag.
We have a pleasant walk past the park, just a few blocks to his house. He loses his balance a couple times, and I keep him conscious as our footprints form a trail of figure 8s in our wake. I'm nervous, fucking scared that this man is not going to be able to find his own house and I want to go fucking home but I refuse to leave him there in the street to die, or worse.
He's pawing around a flimsy metal screen door for a key, and it strikes me that someone else might be home that we don't want to wake up, his kids? His Mother? His equally terrifying roommates?
I don't have a fucking clue and I'm thinking that if we could have just sat down and ate some fucking pizza all of this could have been settled out in the open. You tell me the last time you had Hawaiian Pizza while I bite my tongue about being of Hawaii. We don't burn the roof of our mouths on the pizza because you recite your favorite prologue dinner prayer and translate the words into English at which point I try it, catholic cross myself, left side first (a habit I learned from stage direction) and we dig into the pizza. This game sucks I proclaim an he crawls across the stiff grey and blue speckled carpet floor on which he will sleep, to put on music. He fumbles around his 2008 style Toshiba laptop. He puts on hip-hop with lyrics from an artist whose name escapes me, and I ask him if I can show him a remix, that dope whiteboy swag he so desperately craved not even an hour ago. We had each housed one slice of what had once been a miracle substance that allowed me to swallow even under the influence of methamphetamine. A stimulant drug renown for its ability to suppress hunger in every person who used it. The same concept, using stimulant medications to suppress hunger has been mostly popularized by the bored housewives choosing furniture from the Sears catalogues that at one point sold actual heroin.
I wasn't around for all of this, but I can imagine the tinctures sold in the sort of antique bottles you find washed ashore with a note in it that reads: "You are not Haram." I return from the broken-down bathroom, pulling the chain of the tank that sits behind to no avail, I wash my hands, leave my piss in the toilet and return to the couch for another slice of Americanized Italian cuisine. I'm unable to convince the man to navigate to Soundcloud as he starts fading into the ground like those letters from antiquity. I rush through my second slice of pizza looking to get home as soon as humanly possible because in this man's realization that his buzz is wearing off, he pleads for cash for cocaine. I had offered him cash for food to get my foot in the door and because I am compassionate and had just enough to spare but what I did not have was actual cold hard cash. My money could only be transferred through the complex web of money transfer applications to which he could not access. We both walk out the front door and wait for an Uber.
This man is on the front porch begging me to walk to an ATM, but I am not going, the mood sours but somehow, I keep it playful, assuring him I would see him again. I did wholly intend on following through on that assurance but the number of times he called and texted lead me to believe that I would have to spend the rest of my life putting up with this behavior in lieu of actually feeding myself. To the neglect of my work and all of my aspirations. This I deem intolerable. Had this man left my presence, our presence (my extremely tolerant, if not bemused Uber driver) with any semblance of future pleasantries, I would have moved heaven and earth to learn Arabic with him, play something more interesting than chess and woo him away from his darkened path with stories of my yet undiscovered travailles.
I'm in the basement of a recently discovered church, Presbyterian. Presbyterianism follows the reformed tradition that splintered from Catholicism the day John Calvin stamped his grievances on the front door of an English church proclaiming that "we shall not buy our way into heaven!" An ideology that I certainly adhere to though I no longer attribute that malice to the Catholics. The services when observed by sound through giant red doors out front sound Catholic to me but their priest dresses like a Mormon. That halfway point between a non-denominationalist pastor in jeans and a polo and the sullen robed figure you find at the beautiful Jesuit mass. In the air is a sense of nervousness though it is probably just wafting off me since I can't remember anyone but the Pastor's name and the kindly, older black gentleman who delegates responsibilities to all of us volunteers. Not a soul seems nervous around me, mainly just uninterested and quiet. There's not much in the way of conversation.
I'm given my directions. They are to build a nuclear power plant to bridge the gap between faith and malice. The exact purification of mutually assured destruction. A symbiotic relationship containing mutually assured disaster where a more powerful force is subservient to their own growing ambition. A man with a more brutish energy clears the corner in which there stands 3 bins. I am to empty the twice bagged articles of these canvas objects to bag them thrice and replace them in any way I see fit. I'm assured they will be sifted through later at the destination at which they find their homes. As I listen to the way of the Tao, pronounced Dao, or Dow like frontal lobe of Dowery I pray that the speed of my movement is not disturbing anyone. We are volunteers and there is an infinite amount of work to do. Many of us retire here for a brief respite from our busy lives, there are no deadlines, but I would like to complete the task.
Churches are an extremely funny place when you're working in one. The mere mention of a sign from God calls whatever the next statement is into question. The pastor or priest or whatever, John ascends the ramp to the basement displaying the same effeminate qualities I have when I feel truly comfortable with myself. I'm not gay or bisexual, I would probably makeout with a dude to shock you and have had a number of MMF threesomes. These were of the ball slapping fun quality had between three consenting adults and to imagine me and John in that position would make me cry tears of laughter and halt all forward progress, so I refrain. He remarks that that the items donated earlier in the year were of perfect fit for the moment and it might even be a sign from God. Nobody says a word and in the brief time it takes for a star to sparkle I decide that it's my time to shine. I ask him how the summer went. It takes an inordinately long time to muster that it's been great. You see he knows me and everyone else just recognizes me. When I mention the splinter cell that formed in this same basement and that I had spent most of my summer there we move our arms in tandem and cock our hips. As he runs out of interest of who I am as a person and expresses that fact by not shifting his conversation to any outside ambition I hold I slink back to the corner. Not exactly defeated by curious as to the reason why nobody here discusses their lives on the outside, perhaps they have run out of things to say.
A giant young black woman with braided hair is the center piece of an archway between two towering pillars that stretch for miles. A young black with a clean-cut fade, and muscular biceps stands propped up by an angelic creature in a plague mask. His simple blue jeans stretch down to the awaiting crowd below. Above them, where the cherubs fly, four dancing figures sit perched, each standing on one leg, the other knee bent. Their arms frame each other and the figure in the ball gown on the end frames our queen. Her left hand caresses her braids as her right hand keeps her insides obscured. You are able to make out both the shapes of her internal organs but also imagine a child being cradled. Down the face of the pillars run the opposite of salt as both humans and statuesque monuments of the renaissance run down to the dark ages. A young girl of a darker complexion than I support a ballet dancer’s back. It's the exact spot on her back where my dimples reside, the spot at which you can find a tramp stamp or an inordinately stretched whale tale. She's taking lessons from a corseted woman with eyes drawn tight. Squinting either in concentration or lack of, perhaps not squinting at all. Rising to these dancers hips we find ghastly figures. A feminine figure set in stone for that task she is to perform. A parliamentarian wigged congress critter emerges from the vaginal entryway of what appears to be the statue of a servant boy. She's aware of the task that she must perform and the symbols on the scroll. In the locket stands another toned black man in humble modern attire locking hands with a somewhat stockier white man. They are mere boys, but their responsibility frames them as men. They are beset by two women with washboards and soap laden pails. A heavyset black woman that I would gas up as thicc frames the white revolutionary war coded white boy with afro-like curly hair. A gaunt white woman sports a dirty white robe, its plainness offset by a checkered lapel that spans the length of her torso and covers what hair she may have hidden. Wafting behind them a sickly green glow of what was once an enchanted forest as they all stand on pedestals. Climbing up the copper pendant from the empty sidewalk below are copper leaves, splintering the bends like olive branches and turning to grain or twisting in on themselves, compressing to form the curves of a golden tusk.
I'm optimistic about school. At least the Arabic classes are going well. This is mostly due to the fact that the professor is able to deftly navigate the capabilities of his pupils to find a common middle ground that works for us, him included. I knew a woman who preached psychology who could do the same. To be able to understand the multiple meanings a single sentence can have before it is said, and then almost instantly ascertain its reception across a room full of bodies is probably the greatest gift known to man. This gift allows for the education of every person in the presence of which it shines while not entirely making itself known. It was the recognition of this gift that alighted my love of education and it was the misplaced faith in my ability to light my own path that led me astray. I remember when this all started, and I could not wait to get out of this fucking office. An office I have refashioned as a study but not in name only. I had realized the necessity of moving the litter box outside of my bedroom. A robotic contraption that spins along its axis like the earth. The Bluetooth entirely unable to first synchronize in a city dense with radio signals crowding the same frequency. One of these signals is the moan of the Isis, the Egyptian fertility goddess. Her siren wails yet to beckon out her last surviving under the guise of shelter and her curious daughter wishing to rejoin her graveyard of tears. No one can sleep under such conditions so they must be separated. We have tried placing them together in every configuration possible. Outside reaps death and inside they will not eat. If they are not bound together and stay together the length of their entire lives they will not survive. The litterbox bounces off of the study floor and shatters into a million little pieces and I press the globe into its shallow basin, plug the awkwardly built machinery into the wall and take a breath full of candlelight aroma and with a hint of cat shit. The online classes are fulfilling enough but I wish to employ my faculties, full-time on education. My 401k sits at the ready for such a plunge, but I desperately wish to draw on it to purchase a house, my first purchase of such magnitude. The idea haunts me, but it sits so far outside of the life I have built that I'm afraid it would collapse, it seems irrational. It's the accelerated winter semester so a full-time schedule is not on the menu. Coffee is however but it's a soupy black thick substance just barely sweetened enough by Splenda, my sugar substitute of choice. Budgeting, ever a necessity is made easier by adding the almond or oat milk always so plentiful in my refrigerator to the pale green, clay rimmed coffee mug. I take a swig and pray the community college doesn't need me to rewrite this in a fashion that's easier to comprehend. I love nicotine so I take a blast from a bodega shopped electronic vape, but I despise the way my heart races when I inhale to much of the vapor or hold the hit too long. A far too focused attention against all vices I've formed from Alcoholics Anonymous, Narcotics Anonymous, and the self-examination of my own wasteful tendencies held up to the charitable actions of the fruits sprouted from community organizing. I seek to no longer understand this as a student but participate in the life I would have had, had I taken another path.
You round the corner in your business apparel. A blue cotton jacket and navy-blue trousers, a bit too tight for my tastes but you wear yourself better than I ever could. We used to share the clothes that more closely resembled our lives. Loud obnoxious, and carefree as our insides frayed. As the twine that bound us rolled down each street like a ball of yarn it marked a map across which we have finally rejoined. At least that's how I like to think of it. You're a little more nonchalant than me. We embrace, as always. It's a pleasantly warm spring morning and the air smells of sugar plum pastries. With the sun on my face and cool breeze in my nostrils I desperately hope that the cafe has some kind of apricot filling for both of us to enjoy. A vision of this contained in a dream nearly brought me to my knees in tears.
"Is that Tom Ford?" I chide.
You laugh as we break away.
"Who's that? It's Gucci." you reply shyly.
We enter the cafe in the midst of a newly formed peace. Smiling and jovial families wait pleasantly as we joke about the menu. The entire time I'm trying to figure out which warm caffeinated beverage may be the specialty of this particular cafe. The French do not fuck with oat milk, nor do they fuck with almond milk. A slightly bemused barista greets us.
I stumble out "Have you got any pistachio flavored syrups?"
They amble to the back and I stammer "Wait, is it sugarfree?"
You roll your eyes at the waiter. I can hear them move in your skull.
You reply, "He's new here, obviously."
We split off to admire the decorations on the walls and the passerby’s on the street. Me, ever on the lookout for your new boyfriend and you ever wondering where my girlfriend hasn't joined us yet. I hold the door for you and in enters a mother and her small child and you laugh as they squeeze between us. We round the short corner to an awaiting table. We effortlessly glide into our seats and for the first time in our entire lives the legs lay level on the concrete sidewalk and the table does not budge. I ask about Ava, and you tell me she's the same as she ever was but with more space to roam and noticeably more content without the anxiety of sudden separation.
"You look fucking great, how is this new job going?" I ask.
"You would not believe this place," he tilts his head to the side, looks me directly in the eyes and smiles.
I laugh and turn my head to the right slightly, looking down.
I respond "Wait, what exactly do you do again?"
"Accounting and bookkeeping for Denomination Hotels." he proclaims.
"I really am proud of you. I would have never believed we escaped that miserable fucking church," I meant existence, "and actually got our lives together." I meant going to court for our warrants.
His, a felony fraud charge dealing with stolen credit and mine a misdemeanor drug charge. I had finished my probation a year earlier which was made easier to the fact that I was no longer on methadone and could piss freely. Opiates make it hard to piss. As mentioned, they slow down every bodily process. His charges were downgraded to a misdemeanor owing to his ever-present luck and his sincere belief that the worst of us is over.
He tucks his chin and smiles bashfully.
"Stop," he giggles, "you're going to make me cry."
I take a bite of the flaky golden-brown crust towards the middle of the custard filled pastry. A ball of dough tucked in the lower left quadrant of my mouth.
I start with "I'm serious though."
He pulls the plastic lidded nectar from his lips and sets the container on the table.
"They've got me overseeing the redesign of a chain they're developing!"
"Oh, a subsidiary, now that's fucking dope."
He asks me what I'm doing next, now that I've finally got my associates degree.
"Going to Temple." I assure him.
I'm scared because philosophy seems to be the common enemy of mathematics and thief of time. The biggest misconception I have ever had is that the end result of philosophy is mathematics, math being a truly universal language and that this language could ever be expressed in the writings of a single philosopher.
"I'm majoring in English literature with a minor of Arabic studies,"
I pause.
"If not to atone for the sins of our forefathers, then to express a commonality among modernity."
He winces because we had once plans of being employed together.
"Do you still code?" he asks.
"No, not at all actually. It feels fucking great. I'm free from that constant weight around my neck while everything of any value I had written waits to be completed by anyone who dares pick up the mantel."
Everything I have ever written fits the dual purpose of education or exploitation. That's the way computer programs are.
"How's Huma?" he asks.
"She's great!" I blurt out.
"No longer bounding around the house like a maniac or wailing to go outside. I think I've finally found a schedule that works to benefit our ages."
If no one understands what that means I find it confounding. I have an age, a beginning and a present. She has an age. Her mother has an age and our behaviors are centered around the consideration of these ages and actions displayed by them. When a child is prevented from eating by her own nature, her reticence to join her mother to feed, to detriment of her own health, the two must be separated. When two cats cannot share the same space no matter what configuration the food bowls, water bowls, water fountains, and litterbox they cannot share the same space. When the mother moans at the door only to draw out the child, no matter her woes she will only be fed. As the child bounds for escape she will be lovingly tossed into another room and sealed in until the mother is safe and fed while her fatter compatriots are held at bay. The cats in back yard which once ran me rampant are no longer a problem. Nobody wanted to adopt them and the kittens that were to be adopted have all died. Some of life's more delicate balancing acts are resolved by universality of death.
"When do you think, modernity is going to change?" he ventures.
"I'd wager about another 20 years before we notice a perceptible change."
We both scan the areas behind and next to the other nostalgically. We finish our brunch speaking of old friends and bringing to light new, our current associations and families. Our parting gift another hug and a few pats on the back, me choking back the tears of both pride and regret as we walk away.
The cabin is in the mountains, it's isolated and awake in a darkly lit log encumbered structure to a flickering glow of a lantern. I had once dreamed of studying computer science here. I had planned on bringing a laptop whose source code could be read from bootloader to userland. These delineations now change so rapidly that one would have to become a monk devoted to a single layer to understand the intricacies. It was not fear of my own incompetency or lack of faith in burgeoning abilities that drew me away from computer science. It was my disinterest in the subject when I experienced the way these subjects are treated in practice. The way we collaborate in a critical industry makes me sick to my stomach and I've fasted in sacrifice. Finally, I have a quiet place to discover my new self, free from the bondage of which I had constrained my future paths. Free to act as goofy as I'd like, attempt jerking myself to completion with my left hand, mock God in almost every way with utmost respect. The tips of our dicks touching somewhere in the atmosphere as she scolds "Yeah, that's not where that goes."
The bookshelf laden room is filled with classics of the authors I've read and who's novels I have yet to complete. Also spread out across the floor, in no particular order, are authors I've never dreamed of being attracted to. Intellectually attracted and perhaps sexually as I imagine myself as their protagonist, antagonist or whoever it is they are secretly fucking. Around the bookshelves I see W.E.B Du Bois, a personal mentor of mine, John Steinbeck, Octavia Butler, Sylvia Plath, Salmon Rushdie, C.S. Lewis, Edgar Allen Poe, Tom Robbins, Henry David Thoreau, Thomas Hardy, Friedrich Nietzsche, Amber A'Lee Frost, Arthur Conan Doyle, Irvine Welsh, and Oscar Wilde. I don't know who left the room in such a mess but imagine it was their characters engaged in a passionate act of love making. Mr. Du Bois pulls Esther from the precipice just as Sylvia pulls a fresh apple pie out of the oven. I join Mr. Poe's sweet Annabelle Lee to the chagrin of the seraphs up in heaven as they cast a net into the sea for any demons birthed by a misinterpretation of Mr. Nietzsche's attempts to create a more equitable, educated human race. Switters bubbles to surface dragging behind him stylistically pleasing run-on sentences and disgusting fancies long since abated. John stands East of Eden and Octavia to the west summoning Amber to rain the right to women's bodily autonomy across the world as Dessie emerges from a sea of free contraception cradling Mr. Wilde like a purple egg. Salmon Rushdie is begging Mr. Lewis to give due consideration to the prophet Moses as the Christian philosopher takes note on whimsical imagery. I crack the egg on the cast iron skillet resting on the fireplace grate and find 3 more in my pocket. The rage I felt upon finding misplaced cigarettes around my apartment in a fit of mania is now replaced with the sibilancy. The subtle repressed excitement imposed by trying not to scare a kitten by bounding around the corner to find my phone when inspiration strikes or my new favorite toy I've enhanced for her incomprehensible.
The debt I owe to Mr. Wilde is both immeasurable and utterly incomprehensible. His bravery in a time most unlike ours, and his adeptness in both mockery and skill inform my gender expression. It somehow strengthens my resolve in my sexual preferences in the way it was forecasted to detract. These mannerisms which I have only ever attributed to being the son of a single mother have refracted through sky as a prism and may offer peace to us all. A clean energy power plant in the West Bank being cooperatively maintained it is not, but we all may pray that one day our energy will be directed there. And there, you will find me, shovel in one hand, broken teeth wrapped around a hospital blue glove being torn at the wrist internally screaming "SOMEONE FUCKING HELP ME!"
Lyrea Stop Using My Fucking Phone Number
Lyra, Hercules, Virgo, Pegasus
A dingy green sectional sofa sits against a sealed off staircase two paces away from the northern facing window.. I open my eyes to the taste of the curled nails of a 3 year old Boxer of the canine variety. His explosion off of the three hundred year old brick wall created a trail of dust in my spit that leads to the big screen LCD television. Liquid crystal display soon to be replaced with OLED, organic electroluminescent diode. We love organic and we love bioluminescence so I assume by now we all love organic light-emitting diodes. The only downside of using less energy is that no one can agree on what motion smoothing actually does and when to turn it off. I leave it off, it's more authentic that way. Swerve the Boxer takes a leap off of a coffee table in the style of a pirate humping his crate and barrel doubloons over the Indian Ocean. He crouches ready to pounce, shoulders bent, ass in the air, no tail to wiggle. Above him, parallel to our bodies but perpendicular to my vision is the television. On the television young german babushkas parade around the screen. A man sits on a park bench and spots appear on the screen around him. These spots first appear as sun spots and then fade to red and green as they distort. Zavijeh sits at where her chin is formed at the bottom of what would be heart shaped face were her hair not parted to be wrapped around her body. Zaniah sits just below her shoulders. Her rounded biceps, not muscular, are too big to slide through my cupped hand even when my thumb is extended to the furthest part of my hand. Whichever finger creates the largest diameter. Her right elbow pressed against her torso sits barely below her nipple, Porrima. Her forearm extends from there and stretches longer than her upper arm and as it does it stretches past the spot where her hips turn into her waist, Auva. Viandematrix is placed just above her slender wrist. If you trace her thigh back up where her flowing hair covers her ass, back up to Auva and trace her pelvic muscle across her body to the dimple of the entrance her thigh creates we find Heze. The shortest path to Spica would be to slice off her left arm. She delicately pinches Syrma between her thumb and pointer finger and out shoots a beam of light straight to Rijl Al Awwa.
Tinky-Winky and the gang. A feminine voice fades in and out.
"I love you, I love you" she beeps out in a robotic trance.
You could tune a watch to it. Always in pairs, occasionally bleating out "I love you" in their singular tone.
I can't remember how long I've been subjected to this kind of extreme loving exposure therapy. It must have been at least a year. It takes one month to go from the examination of the public release of Air Force video footage of unexplained aerial phenomenon to studying War Game Development with Maurice Grela. The footage is real and the pilot's excited reactions of joy genuine. War Game Development is also real. A more algorithmic version of the movie War Game starring Mathew Broderick. Their brightly patterned screens can't look much more impressive than a 3 dimensionally rendered globe beset by television screens full of data. Bespeckled nerds jerking off into their corner trashcan while The Generals carve out the world's resources. It's the same amount of time it takes to locate a charitable organization feeding the unhoused and hungry. Where you can meet a sarcastic nun with a limp who will point you to a table to serve. You've already humped your chili to the kitchen. You carried it in a canvas tote bag you borrowed from your roommate, bread freshly purchased from Reading Terminal Market. Enough time to be pointed the way to an anarchist bookstore. You've been told you're in need in constant adoration but you're afraid you're unable to express your values in a way that's comprehendible to the people you love most. You know the words you use to describe them stem from leftist politics and you feel guilty about your corporate job. You walk through the narrow entrance way and nervously glance to the left hoping to find something you recognize, a novel or author prolific enough to grab your attention. The attractive woman behind the counter sits nervously behind the counter and casts a furtive glance. The titles of the novels seem to obviously express an opinion about any identitarian coping strategy you may need, while none of them seem keen on addressing climate change or the roots of the ethnostate currently committing a genocide. This forces my eyes up and directly forward where slightly to the right there is a desk full of children's books and toys. This makes me want to scream as the last time I was in this store I was planning on raising 3 children with the woman I love and we didn't discuss a single item on the table. We pointed at the books and nodded in tacit agreement as she wandered off. The woman behind the counter catches my solemn sigh and I hear an interested "Hmm?" She's about 10 years older than I. She's wearing dark blue floral dress tied at the waist with an equally blue belt. Her posture composed and her torso thin, her pose creates enough space for the silky dress to ruffle between. Her calf rests on her knee through the slip in her dress revealing a tattoo of ivy up her thigh. I approach the counter loosely gripping a novel between my torso and bicep. I let the novel slip into the palm of my hand and place it on the counter without making a sound. "Olive Juice?" she inquires. I can't quite determine the meaning of the utterance "Juice." The fact that behind sits rows of unopened novels I consider that she may be asking me if chose something read by those in the know. I hold up my second choice reading material, a history of conflict in Syria. She scans the item for a second, briefly examining it for anarchist tendencies, and confused, places it back on the counter.
I walk to the closest bar, the book taking up concerningly too little space in my giant canvas bag. The bottom scrapes the sidewalk any time my posture slouches in the least. Here we meet Veronica. We're in an Irish bar with a live band playing. The notes of trumpets and bagpipes selectively choose the words of the crowd. It's our bi-yearly date. A mistake I always make due to the way we track pay periods. Fate brings us together every 2 years. She's cut her hair shoulder length and dyed it red. It doesn't look great.
"You look great!" explodes out of me in-between the obnoxious blows of the brass instruments.
She frames her straight locks with the backsides of her hands and turns her head.
"Did you see my hair?"
Oh I saw it but I know from experience the mood swings produced from luscious locks trimmed too tightly and ever cautious not to bruise a fragile ego I tell her I love it. I imagine her boyfriend. A gentle creature helping her to navigate her new adoption. She had just been given the opportunity to foster her brother's children. We catch up on her adventure south of Prague through the anarchistic community in northern Spain. We reminisced on our favorite novel where two lovers synchronize the princesses's menstruation to the moon. I review the things I've learned from my Arabic friends in Damascus. Tahini is made from shockingly few ingredients. Sesame seeds and olive oil, toasted in a pan, crushed and combined. I find that adding lemon creates a mixture adds acid, the only missing element recommended by chefs. The taste and texture is how universally despised Australian specialty Vegemite has been described to me. Salty and overpowering, it's pungent aroma may remain in your suppressed belches for days on end. The upside of this mixture besides the price of the ingredients is that the smallest amount will bring to life the blandest of flavors. For the weeks that you don't have ghee because it has been replaced with soy butter it can add a much appreciated flavor to your mundane daily meals. The same meals you make over and over because you don't dare step outside the box and try something new. You don't care to research the effects of commercial factory farming. You don't care to research the largest contributing factors to climate change and understand that it's deeply intertwined to our treatment of animals. You don't care to know that Halal in reference to our food refers to the treatment of such animals. You don't bother to cut back on your consumption habits, food and otherwise. She does however. She whispers in our last embrace that my adventuring is leading to something akin to an "Olive Truce."
"There's truth in the olives!" I shout walking away, swinging around to flash her a peace sign. She tearfully giggles as she gets into her car.
The trudge to the most non-judgmental gym on earth is treacherous. You really are in the most enticing exurb of the city of neighborhoods for a drug addict intent on a life of misery. The walk to the gym is over a mile in each direction and the streets are paved in gold and blast warnings from brightly lit curbs. Cobblestone graves pave the cross street where a robotic voice screeches through the night about the home security system installed on the house. This completely ruins any opportunity for peaceful conversation on the adjoining porches or in front of the house. To ruin the peace in your own home in such a matter can only drive your family to paranoia and to steal from your neighbors the chance of true connection is even worse. You would love to "get into jogging" because "it's so good for you" and it really is but your muscle mass is low enough that it no longer shines through the decade of fat that sits atop. You meet your personal trainer at the gym. She teaches you an improved version of the modified Bulgarian Split Squat. Her body commendable she grips her ankle with her right hand, she pulls her ankle to her ass as she stretches her Rectus femoris and Vastus lateralis tight. She stands directly upright and slowly raises her left hand straight, pointing her longest finger past the wall in front of her. She simultaneously extends her gripped ankle backwards while leaning forward just until she begins to feel a stretch in her Plantaris. She keeps her weight bearing down towards her heel and works her Vastus lateralis to lower her planked body as far as her muscles will allow her. To balance her when she begins to stumble she bends her outstretched arm to a perfect 90 degree angle. Straightening it again to perform the squat. The only trick to it is looking past whatever you see. She extends a branch to my nose as I stare through the soles of her feet.
She whispers "Olive truce."
I find myself musing over what to wear to the local post-hardcore concert. I require the proper amount of flexibility to use these newly sharpened calf muscles. There are no concert clothes weather appropriate for a concert when there is nowhere to put your coat. A black t-shirt and black skinny jeans with a black pullover hoodie seem appropriate for the occasion. At least then I can give away the hoodie at the door should any of our brothers and sisters require one. I do so at the door as I enter the mouth of The Pegasus. The lights are up and the opening band has already started, Dread. The Dread heads clumped around the front of stage occasionally shouting the lines they remember. They amble off stage to rapturous applause. Recon takes the stage next, playing a tight 15 minute set, their music instrumental as guerrillas meander around the crowd searching for feds. Headlining is:
Direct your Tor Browser to https://daunt.link
Skip the first six dreadful unknowns or proceed with parental supervision. Click on Dark Matter.
There may be alternating members of the band, the URLs displayed after TOR. Their last names, their TLDs are all .onion. Here we only see 3 such band members. Click the text next to the uppermost gray TOR box.
The respectful staff at the door wearing blindfolds stand gallantly awaiting your arrival. Their wands only meant to detect your humanity as the problem of automated chat bots stem from the plague of spam. Not the delicious Hawaiian processed meat, cheap, nutritious, especially inviting when fried with pineapple.
The gate swings open.
You approach a strapping young lad before the palatial entryway. His broad shoulders brimming over his flat stomach give his legs the appearance of toothpicks. Under his chainmail fishnets he appears to be completely hairless. His name tag reads Hercules. The precious woman next to him effortlessly wands the approaching hoard with one hand while directing her previous victim with the other. Hercules, despite his Brazilian waxed physique meant for propelling Olympic swimmers up mountains like trout, seems to have his directing hand down the back of his fishnets, unable to reach an itch that must be scratched. You wipe the lenses of your glasses as you approach unsure how soon to twirl. You turn left expecting the wand to come from his left hand when you notice his previously occupied fingertips tugging the front of his uniform as he uses his palm for a broader brush stroke of his chest. He looks at you with grave concern and instructs you to face him directly and casts a desperate glance to that graceful woman next to him. You can't help but notice her beauty when she reveals a menacing smile. You glance down at her name tag, Deainira. A hidden contemplative smile crosses your face as you consider what you're signing up for.
You need to provide only 4 anonymized pieces of information that only you can remember. It's more than likely that only 1 of these pieces of information remain shrouded in secrecy, the password, so the other three should be as distant as possible from your own personal records.
You communicate the required information through a series of finger taps, mirroring the man in front of you and you wonder if you were sitting down could you use your feet as well?
Your fingers are pressed together and as you pull one back his follows so you can't tell whether it was initially a pressure exerted by him so as you push back your ring finger instinctively retracts but this time his does as well. With one hand frozen your free to tap out the beat with your left.
You close your eyes and practice intentional breathing. Not the maternal kind but the kind that allows you to slow and speed time with the rate of your heart, otherwise known as deep meditation. The kind of spiritual experience that allows Mr. Aurelias's better angels to shine through in his meditations on the act. For further confirmation, see Meditations.
Mr Asimov produces two baldheaded lil Octavia Butlers separated in age by two years, the older the braver of the two but enraptured in childlike wonder at the texture of your hair. You wonder if the shivers sent directly down the back of your neck are equally compelled to climb up through her fingertips and you twitch at the thought of where they may stop.
It's raining out so lets call her polishedraindrop42. Polished, due to her finely manicured nails. A style of her own design and not her equally adorable hair style. A style she can hopefully find pride in. 42 as she's the forty-second Raindrop her family has produced.
She must know for what reason you've arrived and it better fucking make her laugh. You have a shame ridden history of such requests which have been transformed through the aid of recovery. It keeps your prying mind from wandering. She is the best in the world at keeping secrets and your request need not be made out loud. Your request works and access has been granted as she points you further down the way.
You stumble through the door ofMr. Penumbra's 24-Hour Bookstore. Clay disaffectedly mentions Ajax is lost in the tunnels somewhere near the upper west-side tunnels under New York City, hunting for PGP private keys. Kat Potente, looking somber perks up at the mention of PGP.
"Omg, Pretty Good Privacy, GNU..."
Clay suddenly remembers and giggles out, "GNU is NOT Unix."
After a sigh of the longing variety, her face takes the shape of relief and comfort, nostalgia. She used to code, time series data visualizations, d3 charts in Javascript with a Hadoop backend much to the chagrin of José Valim and Chris Phoenix. Had she not been promoted to a slightly less dignified position she may have held out long enough to experience the joy in coding these wonderful creations.
A pained expression retakes her face's momentary solace when she remembers her brief stint as a Product Manager and returns to a cute sort of resolve when she sees you, dutifully presented to her for assistance.
"I was instructed to ask you for numbers." you say.
"Numbers?" she asks inquisitively.
"King James?" spouts Clay.
She laughs.
"Wait, like the dude that compiled The Bible?" you reply.
"No, I'm in need of something entirely more, uhhh.." you trail off.
She rolls her eyes, "Eccentric?"
"Eclectic." corrects Clay.
"Transformative, actually." I say with a slight grin.
I've long been interested in all sorts of mystic religions and had recently been acquainted with a Jewish Kabbalist who was a little too selfish for my liking thus causing our falling out.
"Let's start here," Kat begins.
She spins through her Dewey Decimal rolodex, producing a notecard entitled "Apocrypha, pseudepigrapha, intertestamental works"
"I'm thinking of a number between 0 and 999." I proclaim.
"I think he's asking you to play." says Clay.
"Easy, 222?" she asks assuredly.
"Nope." I lie.
"305??" she leads.
"229.305203" Clay adds. "I don't think he's there yet."
Exasperated, she writes "229" on a slip of paper and slides it my way.
"A Pharisee I know?" I ask and the library dissolves away before I can even
Astrea emerges in a silver haze grasping a fistful of golden wheat. We're somewhere in the heavens, a place that becomes our sky. Her hair messy in a way that implies she just rolled out of bed or has sat at her desk for days doing research. With dark bags under her eyes, they lower to my chest.
She asks, "What's the pocket for?"
"Excuse me?" I ask.
"The material and cut of your shirt imply that it's cost you considerably more than most shirts I've ever seen. I see no emblazoned logo stressing vanity. Do you care for or about each piece of material that rests upon your body?"
"Yes?" I halfheartedly stammer becoming a little frightened honestly.
"For or about?" she asks sternly.
"What happens if I refuse to answer?" I offer.
Astrea considers this for several moments. I push my mind closer to the answer, pressure in my face grows and as soon as I snap to the other consideration a lightening bolt flashes. This soundless surge of light stretches far below the bronze age mishaps below us.
Dionysus whispers in my ear, "Hades got your back. Ask her what pomegranate tastes like."
"When was the last time you had pomegranate? I imagine dividing all that wheat must be strenuous and mentally exhausting." I posit.
"Fuck dude, that's not what I said." Dionysus admonishes.
"I don't HAVE anything." she rebukes, her voice raising in intensity.
"I spend all of my time dealing with the fuckups who mostly appear to me exactly like you. Distributing a basic necessity of life to those who don't offer a modicum of appreciation. Occasionally I spend an eternity without a single hint of recognition." she blurts out in a perfectly aggrieved tambour.
Dionysus chuckles in a way that shows he actually cares deeply about her while separated by worlds. He loves her, she hates him and likely believes she hates everything he stands for.
"What does pomegranate taste like?" I ask.
Her left eye begins to twitch. As it does so, it appears as though the crease of her mouth follows, both pulling to the same direction.
She starts sputtering, "Kind of, kind, kind of. NO! Lie of, lie of, lie of spruce." "JUICE, oh GOD, juice. It's sickly sweet spirits..."
And just like that, before she can finish her body explodes into a nebula around us as her face rearranges like a fucked up, beautiful Mr Potato Head puzzle.
The illuminated nebula surrounds her constellation obscured by 5 objects once belonging to her face. Her eyes, nose, and lips form the ancient greek column in the upper left quadrant. Her right ear is torn off by the blast and Vincent Van Gogh loving carries it across the space which was once the center of her face. With her left ear, a nagging problem of hers in the way, he lifts it up and places in the exact row her nose now sits in the adjacent quadrant. Her right ear, now in Van Gogh's adept fingers is placed at the direct center of the constellation.
As Vincent begrudgingly makes his retreat I inform him that The Art Institute of Chicago has arranged his art beautifully and perhaps, if it would not be too much trouble to visit the windy city to inspire someone lost. No more trains need be painted by suicide nor ears chopped off in frustration. He promises to make an appearance. He mentions a woman who appeared to him, crawling onto the banks of the Sienne. An actual goddess, another goddess, goddamn. She was raptured from the arms of another man with her disappointed mother standing above. Her mother had warned her of sucking on seeds, for in their world fruit was plentiful. The phrase Demeter had come up with for her daughter's disobedient insolence was "Odo Conniculus." Latin for "tunnel ear" or the feeling one experiences upon a rapid change of pressure when ascending or descending the earth's atmosphere in the cabin of an airplane.
I gently whisper, "Odo Conniculus" and the scene explodes.
smtp gateways open up allowing every student to attend a community college free of cost
floral arrangements are built from single donated plastic flower from a stranger
scene kids of all stripes mosh to industrial trap under a bridge
leon the professional frees cracka
disco inferno activates john travolta's better angel
explorer is finally retired as an internet browser and remains the most accessible way to access files
milfs of all shapes, denominations, and sexual preference rain consent from the heavens
fourth base is defined and we create a new kind of sex
homepage exists on ipfs and no longer requires DNS for anybody to deem it worth reading
omissions of truth are never again questioned as lies and faith is taken at face value
rally cars are made of plywood and donated roller skate wheels
fountain is again a place to cast your youthful dreams and not a place to maintain youth
Add A Custom Theme to mdBook
What is mdBook?
mdBook is the open-source project that this website was built with. It's hosted on Github and it's project maintainers are the maintainers of Rust, my favorite programming language when I'm forced to write code. The project compiles to a single binary that one can use to compile markdown files and related assets to html. The location of the files is specified by convention and the project supports plugins that can modify the output using preprocessing. This website makes use of a few of these preprocessing tools at the moment. They are also compiled to a single binary, all of their filenames must start with the prefix mdbook-
. mdBook is made aware of your intention to use these preprocessors by a simple specification in your website's book.toml
. This website is currently using the following preprocessors:
This website also uses the following external tools. These are binaries that you will need to run in addition to the mdbook build
command:
Why do you need a custom theme?
I need a custom theme because I don't particularly enjoy writing code. I enjoy writing stories and I'd like these stories to not hurt your or my eyes when reading them. I noticed that the built in theme's colors strained my eyes and made words blur together even though I'm wearing glasses. Books, for the most part, don't affect me like this unless the light is too low in my extremely dark apartment. It took a little bit of experimenting and a helpful blog post on non-violent fonts to find something that works for me. I have an elementary undersatnding of French so when I read that serif means "declorative flourish" I was astonished that I've gone all these years ignoring "without decorative flourish" while continuing to build apps and websites. I landed on Garamond which actually has a cool backstory, I had no idea fonts could be hundreds of years old. It's available for free at freefonts.com. As per mdBook convention the font will need to be converted to woff2
because the only available file type I could find was ttf
. There are libraries available to do this on Github but because I am me, I would have ended up reading their source code, along with the source code of any important dependencies, so I just used this free online tool which works swimingly. Alternatively, if you like the font on this website you can just download it.
Here are the other fonts that came in the package that I have already converted from ttf
to woff2
. I can't answer with any specificity what they are to be used for but I didn't specify their use anywhere, so I'm assuming they're not being used anywhere. Browsers are massive projects so I could be wrong, but I'm definitely not looking it up tonight.
If you try my custom theme to read the stories contained in this website, and find that it strains your eyes, please send me an email! I want you to read these and I do not want you to hurt yourself doing so!! Check out my contact page for ways to contact me.
I've also found a dearth, neigh, a void, of theme options that don't involve replacing the built in themes, or that seem to only replace the code block themes. The two I played with were:
- Catpuccin's repo - Really pretty themes for many different applications, but requires replacing the built in themes.
- mdbook-theme - Actually seems really cool and gives you all of themes from ace editor, but involves a more intensive setup, only allows "theming" by modifying the css variables in a preprocessor which affects all themes, and only supplies all the really flowery theming to the live Rust code editor built into mdBook.
Is it hard to do?
Not really. A general overview is that you need recursively copy the fonts
directory from your compiled book
directory into your src
directory and then add your font the newly copied directoy (src/fonts
). You then recursively copy the book/theme
directory to your src
directory. Following that, you modify a couple of the .css
files. Finally you add the menu option of your new theme to src/theme/index.hbs
.
For convenience, here are the unix commands to initially build the required files and copy them to the correct locations.
mdbook build
cp -r book/fonts src
cp -r book/theme src
You can see the additions I made by diffing the commit that made the changes to the previous commit on my Github. Just scroll down to the files in question.
Will you explain the changes?
Sure, the src/theme/css/variables.css
file contains variables that get imported into the other css files. They are defined as so:
.theme-name-css-class-selector {
--variable-name: "value"
}
They are then used in the files they are imported into as so:
.css-class-selector {
style-property: var(--variable-name)
}
This way, the values of those style properties dynamically change when a theme is selected from your website's theme menu options.
The src/theme/css/general.css
file contains the base styles for the major div
elements you see when you look at your website. For instance the html
, body
, code
, and content
tags. The content
tags contain essentially everything that isn't navigation or interactivity. So basically, the pages in your book. We modify this file to use the variables we defined in src/theme/css/variables.css
.
The src/theme/css/chrome.css
contains extra styles of unspecified purpose, they are styles that the maintainers did not deem worthy of the "Base Style" mantle.
Using this knowledge we need only make a few changes to get the desired effect, a skinable custom theme that doesn't require replacing any of the existing themes.
First we add the font-family
property to src/theme/css/chrome.css
, giving it the value "Open Sans", sans-serif;
, which is the default font used by the themes. This prevents us from interfering with the other themes' font, and has the positive side effect of allowing us to only use our pretty Serif font on the pages of the book. This means that the sidebar navigation will retain its "Open Sans" or fallback sans-serif font. I did this so that the website bits look like a website and the book bits look like a page in a book.
To do this, locate the .sidebar
css class selector and add the property definition font-family: "Open Sans", sans-serif;
, so that the final property definition looks like this:
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--sidebar-width);
font-size: 0.875em;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
background-color: var(--sidebar-bg);
color: var(--sidebar-fg);
font-family: "Open Sans", sans-serif;
}
Next, in src/theme/css/general.css
, we add add a css class selector definition with the title of our custom theme, and fill it with the values of any of the other themes definined in the file. I just copied the values contained in the .rust
definition because it contained the closest color scheme to what I desired. You then, modify the values of each property to match what you're looking for. I found it's some guess and check work but mdbook serve
recompiles your site every time you save a change, and VScode or other editor plugins make it easier by adding in-line color pickers and such. You then, add a variable named --font
to the existing css class selector definitions of each theme, .ayu
,.coal
,.light
,.navy
, and .rust
, and set its value to "Open Sans". Make sure to also include a --font
variable in your custom theme. As mentioned before, I went with "Garamond Regular".
For brevity, we will only look at an example of a single modified theme located above our new custom theme definition in src/theme/css/general.css
. Also, I found that the Garamond font I downloaded appeared much smaller than the "Open Sans" font, so to remedy this I defined another variable, --content-font-size
and set it to 1.5em
.
.rust {
--bg: hsl(60, 9%, 87%);
--fg: #262625;
--sidebar-bg: #3b2e2a;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505254;
--sidebar-active: #e69f67;
--sidebar-spacer: #45373a;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #262625;
--links: #2b79a2;
--inline-code-color: #6e6b5e;
--theme-popup-bg: #e1e1db;
--theme-popup-border: #b38f6b;
--theme-hover: #99908a;
--quote-bg: hsl(60, 5%, 75%);
--quote-border: hsl(60, 5%, 70%);
--table-border-color: hsl(60, 9%, 82%);
--table-header-bg: #b3a497;
--table-alternate-bg: hsl(60, 9%, 84%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #dec2a2;
--search-mark-bg: #e69f67;
--font: "Open Sans"
}
.papier {
--bg: hsl(45, 46%, 85%);
--fg: #262625;
--sidebar-bg: #3b2e2a;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505254;
--sidebar-active: #e69f67;
--sidebar-spacer: #45373a;
--scrollbar: var(--sidebar-fg);
--icons: #737480;
--icons-hover: #262625;
--links: #434341;
--inline-code-color: #6e6b5e;
--theme-popup-bg: #e1e1db;
--theme-popup-border: #b38f6b;
--theme-hover: #99908a;
--quote-bg: hsl(60, 5%, 75%);
--quote-border: hsl(60, 5%, 70%);
--table-border-color: hsl(60, 9%, 82%);
--table-header-bg: #b3a497;
--table-alternate-bg: hsl(60, 9%, 84%);
--searchbar-border-color: #aaa;
--searchbar-bg: #fafafa;
--searchbar-fg: #000;
--searchbar-shadow-color: #aaa;
--searchresults-header-fg: #666;
--searchresults-border-color: #888;
--searchresults-li-bg: #dec2a2;
--search-mark-bg: #e69f67;
--font: "Garamond Regular";
--content-font-size: 1.5em
}
We then modify the font-family
property in src/theme/css/general.css
under the html
element selector to use our --font
variable we created previously in src/theme/css/variables.css
. We also modify the value of the property font-family
contained in the .body
class selector definition.
To do this locate the html
element selector and modify the font-family
value so that final definition looks as follows:
html {
font-family: var(--font), sans-serif;
color: var(--fg);
background-color: var(--bg);
text-size-adjust: none;
}
Then locate the body
element selector and add a font-family
definition that uses the --font
variable we defined previously:
body {
margin: 0;
font-size: 1.6rem;
font-family: var(--font);
overflow-x: hidden;
}
Finally, locate the .content
class selector and modify the font-size
value so that the final definition uses the --content-font-size
variable we defined previously:
.content {
overflow-y: auto;
padding: 0 15px;
padding-bottom: 50px;
font-size: var(--content-font-size);
}
The last file you will need to modify is src/theme/index.hbs
. Add a list item for your custom theme to the unordered list that defines the theme menu items.
To do this locate the ul
element with the id
"theme-list" and add an li
element containing a button with a handlebars definition that passes off the hard work to mdbook
. The new menu definition should look like this:
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">{{ theme_option "Light" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">{{ theme_option "Rust" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">{{ theme_option "Coal" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">{{ theme_option "Navy" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">{{ theme_option "Ayu" }}</button></li>
<li role="none"><button role="menuitem" class="theme" id="papier">{{ theme_option "Papier" }}</button></li>
</ul>
Above, you can see the line I added for my custom theme, "Papier". The two parts that need to change if you just copy one of the lines of html for another theme are the button
id
and the variable passed to theme_option
.
Here are all of the completed changes, sans font file, if you would like to just copy my files and make your adjustments after:
Hallucinatory Sensory Remix
Sometimes I feel dysphoria. Not in my gender, gender expression, sex, or sexuality but in the way my preferred atmosphere conflicts with the realities of daily life. It's not a huge deal, I'm not a "noise is violence" type snowflake but I've recently had a few pretty terrible episodes of it that induce panic attacks. Mr brain moves very fast sometimes and it feels like my body can't keep up with it, this can be especially noticable if a person is speaking to me about something I don't care about or especially when they speak slow. This worst of this anxiety producing dysphoria was brought on while trying to learn another language, realizing I wanted to learn a different language and saw that it would be nearly impossible to do so without interacting with a person or persons for that specific purpose. I am a software engineer. I don't enjoy software engineering, I enjoy philosophy. At this point droning on about this further just feels like complaining to me so lets get to the thing I made.
I often heard a myth growing up, that if one was to somehow synchronize Pink Floyd's The Dark Side of the Moon to Victor Fleming's film The Wizard of Oz, they achieve some kind of transformative high through their synchronicity. Not being a fan of Pink Floyd nor The Wizard of OZ, I never thought it worth the effort to embark on such a meaningless journey. You can read about the opportunity if you are so inclined, the experience has been dubbed The Dark Side of The Rainbow.
I do however like vampires. The metaphors infinite since they had been immortalized by Bram Stoker's Dracula. I find a vampire with suicidal ideations especially compelling, though my favorite depiction is John Ajvide Lindqvist's Let the Right One In. I waver on whether the Swedish film or American film is better, but I usually land in Sweden.
I had put together a playlist on Spotify, not exactly vampire themed but gets me in a vampiric mood. I had been experimenting with syncing audio that I enjoy with different media, on different mediums. In a moment of boredom and frustration, I decided to just let the playlist run while watching Only Lover's Left Alive. For fun, not for money. The outcome is actually thoroughly enjoyable.
It was just an experiment, so the audio quality isn't quite what I'd like. While the initial experience was exhilarating, upon review, it kind of requires the original audio for the desired effect. I plan on ripping the playlist and re-dubbing the video. I'd also like to add the option to include the lyrics to the songs and a way to navigate the video by song.
I had initially posted this to Youtube but it was DMCA'd into oblivion so I put here. My website's prettier than Youtube anyway and there are no ads. I hope you enjoy!
Inspiration for Sensory Re-imagining
Being bored and alone, as I so often find myself despite my actual best efforts, I decided to try something that I learned from the trans community. I left for the theater, alone, in the back of an Uber listening to a Witchouse playlist I found by searching an old T.a.t.u pop song, All The Things She Said prepended to the genre as the artists' intentionally obscure their names to prevent them from gaining noteriety. Art for arts sake and it's fucking beautiful.
The group of young black adults sitting in an empty chair to the left of me seemed nice enough. They had fun, laughed, and joked. I would have loved to laugh along with them and participate in their conversations had I actually known them. This is of course, an impossibility and having already watched this movie before it came out, at home on my couch, on my television, sat directly on the hardwood floor, I thought it a perfect opportunity to try something new.
While it's not quite reading emotions, it's more like rewriting intentions. There are times where the film perfectly synchronizes with the music, where emotions play off of each other as more of a dance. It adds intensity to the movie without withdrawing any of it's B movie slasher humor, which personally, I find grotesque and uninteresting. The first time I arose to use the lavatory, I did so keeping the noise-cancelation technology provided by my Airpods switched on because I am perfectly capable of using my eyes to navigate a half-filled AMC theater on Broad Street in North Philadelphia, without the aid of the sounds we all make at such an event.
The synthetic leather, couch-like seats, recline giving us the option of enjoying from multiple angles; or sleeping if need be. I could see a pair of legs jutting out of the flashing tunnel, guiding my way and at least two recliners open. Brushing past this, without interupting anyones movie viewing experience, for too long, usually comes quite naturally to me. Thus I did so effortlessly. Taking my airpods out when at the bottom of the steps, I realized I was making a transition not only into light, but around a corner.
Airpods in the theater might appear somewhat strange, and I loathe to be gawked at when I'm unable to explain the purpose of what I'm doing. Explaining the purpose of what I'm doing ruins the experience altogether.
I maintained my balance. I walked an empty hallway, dimly lit but not so dim as the theater during the previews, and not as bright as a halogen lit megastore. A young theater employee was speaking to his friend. Needing to pass between them, and due to their proximity, to remain natural, I needed to at least acknowledge them. Swivel-head-double-nod, was out of the question. I chose the one on my left, the theater employee of about my approximate height. I spat out the worst "sup" I have ever heard, followed by a mistimed head nod and kept it moving.
I should have left the airpods in. The bathroom was empty. I wanted an actual photo representation of myself to display for the world to see, yes the world. I thought of how depressing it is to take a selfie in the restroom of a theater alone again, and how there's not a single person in NA who wants do anything but hang out with their families, fuck, or go to NA related events, and how the person I had made plans with refused to provide an alternative to my current situation.
One single fucking suggestion of what this person wants to do with their time other than get high and my plans become unimportant to me, as they were to begin with. If you want to sit down on a fucking street corner and talk then let's do that. If you want to eat in a fancy restaurant, let's do that. If you want to eat at the worst restaraunt this city has to offer, then point it out and let's do that. If you want to make music, guess what, I can do that too, let's talk about it. What are you running from, my door is open, my phone answered, my text messages responded to. You do not even need to tell me where you spend your time; fucking lie to me, do something other than whatever the fuck this is.
The second time I needed to use the restroom, the path was exactly the same, with in my estimation, the same pair of legs jutting out. I again attempted to weave between the legs on the recliner, and the Schrodinger's box of refreshments littering the ground, where the cat's life is whether or not you are enjoying them enough to consume them or share them with the person next to you. I guess the first time, I sort of just hopped over these obstacles. On this attempt however, after hitting their shoes with my shin, I loudly and forcefully ejaculated "SORRY" and while I have a practiced control of my voice, I could not recite with any authority how loud I was and how startled they truly were.
It was an embarassing situation for me but not once did I feel anger, just a mild annoyance. I stumbled my way back down the steps and regained my composure. The empty hallway felt different as I questioned how much of a disturbance I had actually made during a movie where a dead women sexually gratifies herself while a mime brutally murders every person he comes into contact with. At one point, during just the second or so pause, before the song unseemlessly transitions, I heard the guy next to me say "I hope they get married." and I really do too, soulmates in that regard.
The hallway was empty this time and quiet, sadder only owing to my misjudged leap and the walk to the restroom slower. I should have kept the music on. Bathroom selfies are a delicate thing to manage in the men's restroom. You rarely, if ever catch one in progress. The process is such. You briefly scan the restroom for signs of life, glancing down the line of urinals. A single person restroom makes this infinitely easier but not always. If there is no one there, you listen for signs of a person shitting, grunting, coughing, writhing in agony, whatever. You guage how close they are to completion by listening for toilet paper rustling, then try to measure if you can make it to the sink by the time they finish.
If you've made it to the sink before they open the door, you've basically won. First you wash your hands, because if you don't, you will not want to be caught dead taking a selfie in the same bathroom. If your phone is already out of your pocket by the time he crests your peripheral vision just go for it, smile with your fucked up hair and try to keep your mind off of perfection until you examine the damage digitally. Smile, look down, and shake your head knowlingly and return to your seat.
Had you not heard paper rustling, or had you been spiritually molested by a movie-goer similarly eager to return to his viewing pleasure, then you have the chance to actually look at yourself. You can brush the popcorn kernels off of your Peace Valley Recovery hoodie, appreciate your Haculla gemstone embroided fang skinny pants, and brush away any dermititis that may have littered your beard. You can neatly tuck your hair you haven't cut in 4 years behind both ears, the left more tightly than right and work on your stance.
In doing this, you'll find it quite difficult to keep the phone out of your face if you are of a certain proportion. Any extension of the arm too far creates not only a boxy appearance but puffs the chest out too far to seem disaffected. Glancing back and forth between the screen and the mirror a few times you may become disinterested in the prospect of your photograph being taken altogether, but that's when you know you'll get a good one. Just cock your hip to the side a bit, look up, and smile. Unfortunately, I was accosted by a kindly, quiet, older gentleman who took up the sink beside me at exactly the same time and while I could have taken an unusually long time to wash my hands, muttering about covid, or the quality of the liquid butter substance which now, in some measure, graces the shaft of my dick. This display may have only bought me another three seconds before my window of opportunity comes crashing down. Twice that, should he run out to warn the next onlooker that I'm having issues.
I make the walk back to my seat to the turned backs of two usher hallway guards, thrilled about their Saturday night too, I'm sure. On the undistracted walk up the stairs I prepared myself to face the consequences of tripping over an unknown foot, hovering over an unknown pile of food by attempting to take lighter steps up the incline and scanning each faceless row until I could see the top. I round the corner half-expecting to see the recliners lowered but there were no feet this time.
I'm glad I kept the music off. I crept by what I now know to be the parents, of a scared little girl, who pleaded "sorry" in a way that only parents can make a child plea. A little scared of what my reaction would be but mostly embarassed. I was emabrassed for her, but mostly shocked as I was expecting anger or ridicule, and I wish I could have sat down and met the parents who brought their 6 year old daughter to watch Terrifier 2 in a whole ass movie theater on Christmas break.
Dinoxor
Re-implementing bitwise operations as abstractions in aarch64 neon registers.
_._
_/:|:
/||||||.
||||||||.
/|||||||||:
/|||||||||||
.|||||||||||||
| ||||||||||||:
_/| |||||||||||||:_=---.._
| | |||||:'''':|| '~-._ '-.
_/| | ||' '-._ _: ;
| | | ' '~~ _;
| ' _.=._ _-~
_.~ { '-_'
_.--=.-~ _.._ {_ }
_.-~ @-, { '-._ _. '~==+ |
(' } \_ \_.=~ | |
`=======' /_ ~-_ ) <_oo_>
`-----~~/ /'===...===' + /
<_oo_> / //
/ //
<_oo_>
I was bored an missing my favorite bipolar bear because she was being deported :( Fuck you Microsoft. I wanted to teach low-level Rust while I was learning arm64 ASM. I bought the book. This was before I had a manic episode and swore off any more computer knowledge. This post is going to be me, reading myself my own code to figure out what it does. I love obfuscation and bit twiddling because I can visualize the registers and perform a certain amount of operations in my head before I get frustrated and need to be on the computer again.
What I do remember about writing it, is that I wanted to make software slightly harder to reverse engineer by replacing the simple xor
instruction with a set of instructions that has the same effect. I wanted to this by utilizing the 128-bit Neon registers on my AArch64 processor.
All the (heavily commented) code is available on my Github, if you'd like to pull it and follow along.
Exclusive Or Truth Table
I did some research to figure out what the xor
logic does and whether there were alternative ways to do the same thing. I had some fruitful discussions with a few LLMs and perused the web. "With two inputs, XOR is true if and only if the inputs differ (one is true, one is false)." Sometimes bitwise operations are easier to visualize when I look at a truth table. There's a nice colored version on the wikipedia page but the one below will suffice.
A | B | A⊕B |
---|---|---|
F | F | F |
F | T | T |
T | F | T |
T | T | F |
Or goal is to XOR one byte with another byte. So that when we XOR 0b01010101
by 0b10101010
we expect the result to be 0b11111111
.
Let's take a look at the entrypoint to our assembly procedure.
_dinoxor
_dinoxor:
stp x29, x30, [sp, #-16]!
mov x29, sp
mov x2, #0
eor v0.16b, v0.16b, v0.16b
bl spread_bits_to_bytes
mov x0, x1
bl spread_bits_to_bytes
bl prepare_xor_truth_table
bl prepare_multiplication_table
bl calculate_xor_result
ldp x29, x30, [sp], #16
ret
The first operation transfers the link register (frame pointer) which resides in x29
and the stack address which lives in x30
to the address calculated when you subtract 16 bytes from the stack pointer.
[sp, #-16]
This part means "subtract 16 bytes from the stack pointer register and calculate the address in the register. The !
(exclamation point) at the end, mutates the stack pointer to contain the value you get when you subtract 16 from the stack pointer." The stack is where you store data for your procedure, it grows down, meaning that as you add things to it you subtract from the address that points to it's start.
Before advancing to the next instruction we can use lldb to subtract 16 from the stack pointer and check that our instruction behaves as we expect.
(lldbinit) p/x $sp
(unsigned long) 0x000000016fdfb5a0
(lldbinit) p/x $sp - 16
(unsigned long) 0x000000016fdfb590
We can then print the two 64bit values following the address that the stack pointer points to.
(lldbinit) mem read --format x --size 8 --count 2 '$sp - 16'
0x16fdfb590: 0x000000016fdfb64b 0x000000016fdfb619
Now let's advance to the next instruction.
The above image shows that the stack pointer (SP
) has been modified to contain the value that we expected (0x000000016fdfb590
). Now let's verify the 64 bits it points to contain the values in x29
and x30
.
(lldbinit) mem read --format x --size 8 --count 2 $sp
0x16fdfb590: 0x000000016fdfb5e0 0x0000000100000750
Great, we can now see that
0x16fdfb590: 0x000000016fdfb64b 0x000000016fdfb619
has become
0x16fdfb590: 0x000000016fdfb5e0 0x0000000100000750
Then we move the stack pointer to the link register. The value 0x000000016FDFB590
in SP
should replace the value 0x000000016FDFB5E0
in x29
.
Basically what we're doing, is stashing the stack pointer and link register so that when we are ready to return from our procedure, we can restore the stack pointer and link register to their inital state. This way, the process that called our procedure can continue its execution. There are official docs on the calling convention available from ARM but the best explanation I found was the accepted answer from this StackOverflow question:
A callee-save register must be saved by the callee (in opposition to a caller-save register, where the caller saves the register); so, if this is the ABI you are using, you do not have to save r10 before calling another function (the other function is responsible for saving it).
You can just substitute x
for r
. The x
denotes a 64bit register while r
generally denotes a 32bit register but can also be used to refer to 64bit registers.
The following 2 instructions are relatively simple.
mov x2, #0
eor v0.16b, v0.16b, v0.16b
The first moves the immediate value 0
into the x2
register. The next XORs, or in ARM parlance eor
's (exclusive OR's), the v0
register which is the first of the general purpose NEON registers. I think of v0-v31
exactly like x0-x27
except the v
registers can hold 128 bits that can be accessed and manipulated in what are called lanes. ARM has great reference documentation on NEON programming. When you eor
an operand against itself and store the result in itself, this has the effect of "zeroing out the register." In summation, we expect both x2
and v0
to contain the value 0
after these two instructions are run.
Let's step through these two instuctions and check.
(lldbinit) reg read $x2
x2 = 0x0000000000000000
(lldbinit) reg read $v0
v0 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}
This shows both that the registers contain 0
, and also that lldb prints the general purpose x
registers as a 64bit hex value and the NEON v
registers as 16 8bit hex values. Each of these values in v0
is called an 8bit lane.
When a procedure is called in aarch64, the AAPCS64 (AArch64 Procedure Call Standard) specifies that the x0 - x7
registers will contain the paramaters passed to the procedure. Our dinoxor
procedure expects 2 parameters to be passed, each a 1 byte operand value that should be eor
'd. This parameters will be in x0
and x1
.
Let's take a look at a C program that will run our assembly procedure.
#include <stdio.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
extern uint8_t dinoxor(uint8_t x0, uint8_t x1);
void printBits(unsigned int num)
{
printf("0b");
for(int bit=0;bit<(sizeof(uint8_t) * 8); bit++)
{
printf("%i", num & 0x01);
num = num >> 1;
}
printf("\n");
}
int main() {
uint8_t a = 0b01010101;
uint8_t b = 0b10101010;
uint8_t ret = dinoxor(a, b);
printBits(ret);
return 0;
}
When debugging this program, we expect x0
to contain 0b01010101
and x1
to contain 0b10101010
before we branch to the spread_bits_to_bytes
procedure.
(lldbinit) bits $x0
0b01010101
(lldbinit) bits $x1
0b10101010
Now that we can see our expectation has been validated, I need to point out that bits
is not a built-in lldb command. Is is a command script loaded by way of ~./lldbinit.py
. Here is the script:
import lldb
def bits(debugger, command, result, internal_dict):
frame = debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
expr = command.strip()
value = frame.EvaluateExpression(expr)
if value.IsValid():
num = value.GetValueAsUnsigned()
print(f"0b{num:08b}")
else:
print("Invalid expression")
The next instruction, bl spread_bits_to_bytes
will branch execution to the address of the procedure spread_bits_to_bytes
. bl
stands for Branch with Link which takes the address of the next instruction, in our case the address containing mov x0, x1
, and stores it in LR
so that when we return from spread_bits_to_bytes
the program will branch to the address that it is to resume execution from.
spread_bits_to_bytes
and spread_bit_loop
Let's take a look at the procedure we just branched to and the procedure that follows. Notice that spread_bits_to_bytes
does not end with a ret
. That means, that the program will continue execution straight into the procedure defined under it, because each instruction defined in an assembly file is executed procedurally, or in order, one line at a time.
spread_bits_to_bytes:
eor v1.16b, v1.16b, v1.16b
eor v2.16b, v2.16b, v2.16b
mov w2, #0
spread_bit_loop:
lsr w3, w0, w2
and w3, w3, #0x01
mov w4, w3
ext v2.16b, v0.16b, v0.16b, #1
ins v2.b[0], w4
mov v0.16b, v2.16b
add w2, w2, #1
cmp w2, #8
b.lt spread_bit_loop
ext v2.16b, v0.16b, v0.16b, #1
ret
spread_bits_to_bytes
only prepares the destination registers we will be working with. It zeroes out the NEON registers v1
and v2
and sets w2
to 0
. w2
is just way to address only the least significant bit, or LSB of x2
. w2
is set to 0
so it will act as a counter in the loop that follows in spread_bit_loop
. We want the procedure to run once for each bit in w0
, so we need it to run 8
times.
eor v1.16b, v1.16b, v1.16b
eor v2.16b, v2.16b, v2.16b
mov w2, #0
Execution then advances to the next instuction, defined in spread_bit_loop
, where the actual logic is done.
lsr w3, w0, w2
and w3, w3, #0x01
mov w4, w3
ext v2.16b, v0.16b, v0.16b, #1
ins v2.b[0], w4
mov v0.16b, v2.16b
add w2, w2, #1
cmp w2, #8
b.lt spread_bit_loop
ext v2.16b, v0.16b, v0.16b, #1
In the first interation of the loop w2
will contain 0
. So the first instruction, lsr w3, w0, w2
will not have any effect. LSR
stands for logical shift right. In this case it will shift the bits in w0
by the value stored in w2
and the bit that falls off the end will get stored in w3
. Let's look at some psuedocode.
# lsr w3, w0, w2
lsr w3, 0b01010101, 1
# Move each bit one position to the right and place a 0 in the, now empty, most significant bit's (MSB) place.
# First shift the LSB to the right, it falls off our value
0b01010101 -> 0b0101010_ 1
# Shift each bit that follows
0b01010101 -> 0b_0101010
# Place a 0 in the MSB
0b_0101010 -> 0b00101010
# Result
# w0 = 0b01010101
# w2 = 1
# w3 = 0b00101010
Now that we have that explanation out of the way, let's step through the first iteration. Our counter in w2
begins at 0
, so the first lsr
instruction won't have any effect. We step through it to the next instruction.
and w3, w3, #0x01
This instruction performs a Logical AND of the byte in w3
and 1
. and
will compare each bit in two operands and return a 1
in each bit place where the values are both 1. Let's look at another truth table.
A | B | A∧B |
---|---|---|
F | F | F |
F | T | F |
T | F | F |
T | T | T |
Now some psuedocode.
0b01010101 # w3
0b00000001 # 1
----------
0b00000001 # Result, the only bit place that contains 1 in both bytes is the least significant bit.
We step throught the instruction and see that w3
now contains 1
. This has the effect of isolating each bit of our input so that we can move them, one-by-one into their own byte lane in a NEON register.
(lldbinit) bits $w3
0b00000001
The next instruction moves the value we just stored in w3
to w4
so that when we work with this bit we don't mutate the value in w3
.
mov w4, w3
Now we see our first NEON specific instruction.
ext v2.16b, v0.16b, v0.16b, #1
ext
is the, somewhat complicated, Extract vector from pair of vectors instruction. In our case it has the effect of shifting the v0
register by one byte and storing the result in v2
. This is because we are extracting bytes from 2 vectors but starting from the least significant byte so that by the time the first vector is extracted, there is no more room left in the destination register. This first iteration has no effect, because v0
is still 0
so v2
will also contain 0
.
ins v2.b[0], w4
This next instruction inserts the byte in w4
into the first lane of v1
. Remember that we previously moved the bit from the and
operation into w4
, so now we are at the instruction where we are actually moving the least significant bit of our original input to a NEON register and interpreting it as a whole ass byte. Here is the result.
(lldbinit) p $v2
(unsigned char __attribute__((ext_vector_type(16)))) (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
ARM's documentation states that the purpose of the INS instruction is to insert vector element from another vector element, but apparently it works for inserting from a regular non-NEON register into a vector element because the compiler changes the instruction to mov.b v2[0], w4
, which moves the byte into the first ane of v2
.
Let's move on to the next two instructions.
mov v0.16b, v2.16b
add w2, w2, #1
The first instruction moves all lanes of v2
into v0
. The second increments our counter in w2
by 1
.
Next up.
cmp w2, #8
b.lt spread_bit_loop
We compare the value in w2
to 8
, and if the value is less than 8
we branch to the beginning of the spread_bit_loop
procedure. The value of w2
is 0
so we branch.
Now that we know the instructions, let's step through them all and inspect the important values after each instruction.
---
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
v2 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
w0 = 0b01010101
w2 = 0b00000001
w3 = 0b00000001
w4 = 0b00000001
---
lsr w3, w0, w2 // Shift the input byte right by the current bit position to bring the target bit to the LSB
---
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
v2 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
w0 = 0b01010101
w2 = 0b00000001
w3 = 0b00101010
w4 = 0b00000001
---
and w3, w3, #0x01 // Isolate the LSB (which is now the target bit)
---
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
v2 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
w0 = 0b01010101
w2 = 0b00000001
w3 = 0b00000000
w4 = 0b00000001
---
mov w4, w3 // Move the processed bit to w4 (to ensure w4 is correctly updated before duplication)
---
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
v2 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
w0 = 0b01010101
w2 = 0b00000001
w3 = 0b00000000
w4 = 0b00000000
---
ext v2.16b, v0.16b, v0.16b, #1 // Shift v0 left by one byte to make space for the new byte
---
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
v2 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
w0 = 0b01010101
w2 = 0b00000001
w3 = 0b00000000
w4 = 0b00000000
---
ins v2.b[0], w4 // Insert the new byte at position 0 of v2
---
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
v2 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
w0 = 0b01010101
w2 = 0b00000001
w3 = 0b00000000
w4 = 0b00000000
---
mov v0.16b, v2.16b // Move the temporary result back to v0
---
v0 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
v2 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
w0 = 0b01010101
w2 = 0b00000001
w3 = 0b00000000
w4 = 0b00000000
---
add w2, w2, #1 // Increment the bit position counter
---
v0 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
v2 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
w0 = 0b01010101
w2 = 0b00000010
w3 = 0b00000000
w4 = 0b00000000
---
cmp w2, #8 // Compare the counter with 8 (number of bits in a byte)
---
v0 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
v2 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
w0 = 0b01010101
w2 = 0b00000010
w3 = 0b00000000
w4 = 0b00000000
---
b.lt spread_bit_loop // If the counter is less than 8, continue the loop
You can see above that the byte in the least significant lane of v0
wrapped around to the most significant lane when the vector was shifted left. Let's now look at w0
, and list v0
printed at the end of every iteration.
On ARM NEON lanes' order of significance:
This confused me at first and will probably throw me off later so I'll take the time to note it. When LLDB prints NEON register values, it does so by listing the lanes from least significant to most significant UNLIKE printing bits, where the least significant bit is the value all the way to the right, at the end of the bit string.
w0 = 0b01010101
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
v0 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00)
v0 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01)
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00)
v0 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01)
v0 = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00)
v0 = (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01)
As you can see above, the bit pattern from w0
has been reproduced as a byte pattern in the upper half of v0
.
0b01010101
0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01
After this ret
is executed, we return to the frame that called spread_bits_to_bytes
, to the address of the instruction after the call. Let's go back and look at the _dinoxor
procedure where we land.
bl spread_bits_to_bytes
mov x0, x1 // <-- We land here.
bl spread_bits_to_bytes
We move the second operand to _dinoxor
, which is the second parameter, or byte that we are xor'ing against into x0
, and we again branch to spread_bits_to_bytes
. Now we repeat the same logic with a different input. Let's analyze our operand in register x0
.
(lldbinit) bits $x0
0b10101010
Now let's let the loop iterate 8 times and check the value of the v2
NEON register before we return.
(lldbinit) p $v2
(unsigned char __attribute__((ext_vector_type(16)))) (0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01)
Here we can see that v2
wasn't overwritten! It was modified and the logic holds, so that the most significant 8 lanes contain the first operand, each bit inflated into a byte and placed in a lane matching it's bit location in a byte, and the second operand is found in the least significant 8 lanes with the same properties.
Let's split up the value in v2
and compare each half to their corresponding operand to help see the pattern visually.
[ 0b10101010 , 0b01010101 ]
[ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ]
[ 1 0 1 0 1 0 1 0 ] [ 0 1 0 1 0 1 0 1 ]
[ 0x01 0x00 0x01 0x00, 0x01 0x00 0x01 0x00 ] [ 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ]
Now we're ready to look at the next procedure.
prepare_xor_truth_table
We can think of an Exclusive Or Truth table as a two-dimensional matrix in one dimension. Refer the truth table in the beginning of this post. We can unfold the table into one dimension like so:
A | B | A⊕B |
---|---|---|
F | F | F |
F | T | T |
T | F | T |
T | T | F |
Remove the operand columns.
A⊕B |
---|
F |
T |
T |
F |
Now, interperate the answer column on only an x-axis.
F | T | T | F |
---|
We need this pattern to work with 128bit NEON registers, so we need to repeat this pattern as bytes across 4 lanes. The resulting neon register should be as follows:
v0 = [ 0x00 0x01 0x01 0x00 0x00 0x01 0x01 0x00 0x00 0x01 0x01 0x00 0x00 0x01 0x01 0x00 ]
The code to do this is quite simple.
prepare_xor_truth_table:
movz w8, #0x0001, lsl #16
movk w8, #0x0100
dup v0.4s, w8
ret
When we branch to this procedure $w8
is 0
.
(lldbinit) bits $w8
0b00000000
The first instruction, movz
shifts a 32bit immediate value, in this case #0x0001
which is equal to the decimal value 1
or the bit value 0b00000001
, left by 16 places, leaving us with the value 0b10000000000000000
. In practice, the compiler optimizes this instruction to mov w8, #0x10000
, as the bit value of #0x10000
is 0b10000000000000000
.
The next instruction movk
or Move wide with keep moves an, optionally shifted, 32bit value into a destination register without altering the previous data in the register. Moving the value 0x100
, or 0b100000000
in bits, to w8
gives us the result 0b10000000100000000
.
Now we need to somehow turn this value into 4 individual bytes and duplicate that pattern 4 times to fill up a NEON register with the correct pattern. Lucky for us the dup
instruction lets us duplicate the general purpose register w8
into a neon register while specifying the arrangement of the bytes when they are duplicated. The .4s
in v0.4s
means interperate the v0
register as 4 seperate 32bit scalar values and duplicate w8
into them.
The pattern is made clearer when we include leading 0
's when inspecting w8
, to display all 32bits.
w8 = 0b10000000100000000
w8 = 0b00000000000000010000000100000000
w8 = 0b00000000_00000001_00000001_00000000
w8 = 0x 00 01 01 00
Now lets imagine v0
as four 32bit scalar values.
v0 = [ 0x00000000 0x00000000 0x00000000 0x00000000 ]
Now duplicating them in this fashion gives us the xor truth table that we need.
(lldbinit) p $v0
(unsigned char __attribute__((ext_vector_type(16)))) (0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00
We then return execution the next instruction in our main dinoxor
procedure, and we approach another unconditional branch.
bl prepare_multiplication_table
prepare_multiplication_table
The idea that allows us to XOR two binary values by using multiplication is quite simple, even if the rest of this post does not make it appear as such.
The algorithm to XOR x
and y
by using a lookup table, when both x
and y
are a binary value, or in the set {0, 1}, is truth_table[index]
where index = 2x+y
.
Let's try it, looking at the 1 dimensional truth table we built earlier.
0 | 1 | 1 | 0 |
---|
Now let's build a table of indexes into this array.
x | y | 2x+1 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 2 |
0 | 1 | 1 |
1 | 1 | 3 |
Now if we use the last column as an index to our truth table we get:
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
The algorithm works!
The procedure to build this one dimensional lookup table in a NEON register is quite simple.
prepare_multiplication_table:
movi v1.8b, #0x02
movi v8.8b, #0x01
mov v1.d[1], v8.d[0]
ret
The first instruction moves the immediate value 2
into the lower half of v
. The notation v1.8b
means interperate v1
as 8
byte size lanes, only giving us access to the least significant 64bits and copying the value 2
to each lane.
(lldbinit) p $v1
(unsigned char __attribute__((ext_vector_type(16)))) (0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
The next instruction moves the immediate value 1
into the lower half of v8
the same exact way. The reason we move 1
into each of the lower lanes is that we end up multiplying this entire register against a register that contains our first parameter in the lower lanes of a register and the second parameter in the upper lanes of the parameter.
(lldbinit) p $v8
(unsigned char __attribute__((ext_vector_type(16)))) (0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
Then we just move the lower half of v8
into the empty, upper half of v1
with the mov v1.d[1], v8.d[0]
instruction. This completes our multiplication table waiting patiently in v1
.
(lldbinit) p $v1
(unsigned char __attribute__((ext_vector_type(16)))) (0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
Finally, we return back to our main dinoxor
procedure. Where we find that our next instruction is out last non-conditional branch.
bl calculate_xor_result
calculate_xor_result
Let's pause for a moment and examine our register state heading into this procedure.
v0 = [ 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00 ]
v1 = [ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 ]
v2 = [ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ]
v3 = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
v0
: contains our truth table.v1
: contains our multiplication table.v2
: contains our two intial parameters, the first in the lower 8 lanes, the second in the higher 8 lanes.v3
: contains 0.
Now let's look at the procedure as a whole.
calculate_xor_result:
mul v3.16b, v2.16b, v1.16b
mov v3.d[1], v2.d[1]
ext.16b v1, v3, v3, #8
add.16b v1, v3, v1
mov.d v1[1], xzr
tbl.8b v1, {v0}, v1
movz x1, #0x0201, lsl #0
movk x1, #0x0804, lsl #16
movk x1, #0x2010, lsl #32
movk x1, #0x8040, lsl #48
mov v0.d[0], x1
mul v1.16b, v1.16b, v0.16b
addv b0, v1.8b
umov w0, v0.b[0]
ret
First we multiply each value in our multiplication table by each value in our NEON register that contains our 2 parameters we would like to XOR and store the result in v3
.
v3 = [ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ]
Then with mov v3.d[1], v2.d[1]
, we move the second parameter that was passed to dinoxor
that is now spread across the most significant 8 lanes of v2
to the most significant 8 lanes of the register v3
, replacing the bytes already there. Here is the result.
v3 = [ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ]
// To reiterate what we just explained.
|- Bottom half of (mult table x first param) ----|- Second parameter to dinoxor ------------------|
v3 = [ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00 | 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ]
The next instruction ext.16b v1, v3, v3, #8
, has the effect of moving the Second parameter to dinoxor) into the bottom half of v1
, overwriting half of our original multiplication table because we are finished with it, and we would like to reuse the register.
|- Second parameter to dinoxor -----------------|- Multiplication table x First param -----------|
v1 = [ 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 | 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00 ]
Then the instruction add.16b v1, v3, v1
adds each lane in v1
to its corresponding lane in v3
and stores the result inv1
overwriting its previous contents. Let's look at psuedocode of the instruction.
|- Second parameter to dinoxor ------------------|- Multiplication table x First param ---------- |
v1 = [ 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 | 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00 ]
|- Multiplication table x First param -----------|- Second parameter to dinoxor ------------------|
+ v3 = [ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00 | 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ]
----------------------------------------------------------------------------------------------------------
= v1 = [ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01 | 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01 ]
The next instruction mov.d v1[1], xzr
, zeroes out the upper 8 lanes of v1
. We only require one of the halfs because they are exactly the same.
v1 = [ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
The next instruction tbl.8b v1, {v0}, v1
, performs a table lookup using the indices in v1
and the truth table in v0
and stores the result in v1
overwriting it's initial contents. There is an impressive explanation that includes a graph in ARM's documentation on lookup table instructions.
v0 = [ 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00 ]
v1 = [ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
When we use each value of v1
as an index into our truth table and overwrite v1
with the result we're left with the following register state.
v1 = [ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
Now we have the Exclusive Or'd value spread across the least significant bits of the v1
register and we need a way to compress these back down to a single byte in a multi-purpose register. I attempted several variations of loops and instructions and was unsucessful. I did however find a magic number that when multiplied by the least significant half of v1
has the effect of reproducing the byte pattern into the first byte sized lane of v1
when each of the lanes are summed together.
movz x1, #0x0201, lsl #0 // Load the lower 16 bits of x1 with 0x0201
movk x1, #0x0804, lsl #16 // Load the next 16 bits of x1 with 0x0804
movk x1, #0x2010, lsl #32 // Load the next 16 bits of x1 with 0x2010
movk x1, #0x8040, lsl #48 // Load the upper 16 bits of x1 with 0x8040
These instructions create the magic number, 9241421688590303745
in decimal or 0b10000000_01000000_00100000_00010000_00001000_00000100_00000010_00000001
. I find this particular pattern beautiful and was only able to formulate it by actually typing out the bit string and putzing about on a calculator.
Then the instruction mov.d v0[0], x1
, moves this value into the lower half of v0
.
v0 = [ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00 ]
The top half of v0
still contains our truth table so we can just ignore it. Next mul v1.16b, v1.16b, v0.16b
, multiplies v0
containing our abstracted XOR result by v1
which contains our magic number. Then the next instruction addv b0, v1.8b
, sums each lane of v1
and stores the result in the first byte sized line of v0
.
v0 = [ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
Finally, we move the first lane of v0
into the w0
register, which is the return value of our entire procedure.
(lldbinit) bits $w0
0b11111111
That's it! We've done it! Our expected return value is in the register that will return our result to a calling function. Now all that's left is to ret
back to our main _dinoxor
procedure and restore the Stack Pointer and Link Register, returning control of execution to the calling process along with our result in w0
, which if you don't remember is just a way to reference the least significant 32 bits of the 64bit register x0
.
ldp x29, x30, [sp], #16
ret
Future plans
I've already implemented this in Rust using inline assembly and utilizing quickcheck to provide generative testing. These posts take quite a lot of energy, so I'll have one ready as soon as humanly possible. I'd love to hear from you if you found this useful in any way or have any suggestions!
Generative Testing Inline Assembly in Rust
thechinesegovernment
Recently, I learned what a small amount of the RISC instructions provided by aarch64 processors actually do. Government's are constantly caught lacking by the security community. RC4 is still found obfuscating code in big hacks. RC4 is fast, and this is almost always used as the explanation on the writeups breaking down the reverse engineering of these tools. It always leaves me thinking, "Our computers are so much faster now than when you probably wrote this. Are you just copying source files from 1999 over and over again?" The answer is probably yes but whatever.
How hard is it to implement ChaCha20? It turns out that in Rust it's not hard at all. Even the C code I was using as reference seemed pretty simple, possibly more simple than the Rust implementation. Before we go into the encryption algorithms that I implemented to benchmark my stupid little routines, let's learn about Rust's inline assembly feature.
Introduction
First, I wrote aarch64 assembly that obfuscates the eor
instruction. You can find the source code on my Github if you'd like the C and assembly files. They are also available in a less comprehensive package in the reference
directory of this projects Github repository.
There is great documentation provided by Rust's maintainers. It is comprehensive and a lot to take in at once to someone new to the feature. That's why I find it easy to only take what I need. Let's not focus on the extraneous information and what could be done and instead we'll just focus on the parts we use.
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: src/lib.rs
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ #![feature(test)]
2 │ #[cfg(test)]
3 │ extern crate quickcheck;
4 │ #[cfg(test)]
5 │ #[macro_use(quickcheck)]
6 │ extern crate quickcheck_macros;
7 │
8 │ pub mod dinoxor;
9 │ pub mod chacha20;
10 │ #[cfg(test)]
11 │ mod tests;
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
We want our project to be a library, so that our dinoxor
function can be called from other projects using our code as a dependency, and can be easily shared via crates.io. It's already available, so if you'd like to just use it, then add a line for it under [dependencies]
in your Cargo.toml
file.
[dependencies]
thechinesegovernment = "*"
And use it like this:
#![allow(unused)] fn main() { use thechinesegovernment::dinoxor::dinoxor; let result = dinoxor(0b11101011, 0b11111111); assert_eq!(result, 0b10100 ) }
Philadelphia Urban Gardening
I moved to Philadelphia for the second time in the Winter of 2024. I was impressed to find that my little West Kensington apartment came with a relatively large back yard. Little did I know, the haven was a den of sin to poor mama Isis and an yet to loved babydady. I was also entirely unaware that when the the blankets of snow and ice cleared, the area would transform into a veritable jungle paradise.
I adopted a kitten from one of two litters, Huma Appeachalonis Abedin, in the span of a few months and did my best to take care of all the cats and kittens. Most kittens died in odd, mass waves of plague but the memories remain.
Introduction
I was introduced to the concept of Permaculture by a friend who took me to one of Sigi's Natural Building workshops on the Pennsylvania/Maryland border. This was my first opportunity to try out gardening of any kind but I do my best to adhere to the principals of sustainability, zero waste (turn outputs into inputs), and symbiosis (companion gardening).
Highlights
- Summer 2024
- Winter 2024-2025
Nushell Commands to Help with batch, filetype conversions
Convert HEIC
to png
and delete original files.
for file in (fd -e HEIC . | lines) { sips -s format png $file --out $"($file).png" }
for file in (fd -e HEIC . | lines) { rm $file }
Convert JPG
to png
and delete original files.
for file in (fd -e JPG . | lines) { sips -s format png $file --out $"($file).png" }
for file in (fd -e JPG . | lines) { rm $file }
Convert MOV
to mp4
and delete original files.
for file in (fd -e MOV . | lines) { ffmpeg -i $file $"($file).mp4" }
for file in (fd -e MOV . | lines) { rm $file }
Philadelphia Urban Garden: Summer 2024
06/26/2024
The Jungle Cats
Long before I dug up the garden beds the cats made friends with a squirrel. They're hanging out at what grew into almost a cave that protected the kittens from predators and elements. When I would reach my hand into the bush, I was consistently amazed to find a temperature drop of at least 10 degrees but it felt almost like walking into an air conditioned house in South Florida.
The Blackberry Bramble
I have a forearm wrapped in a blackberry bramble tattoo, owing to the fact that one of my favorite author's is Tom Robbins. I was elated to find the backyard came pre-installed with my very own blackberry bramble. This bramble makes up most of the cave that the cats spent most of their summer inside, keeping cool, dodging pterodactyls, etc.
The Magic Mormon Blackberry Lemonade
I was listening to Chris Wade and Matt Christman's wonderful Inebriated Past podcast series and a little obsessed with their materialist take on Mormonism. I vibe with the Chapo's take that Mormonism is the essential captitalist religion, in that it subsumes its doctrines and adapts them into tradition and practice. The amount of used syringes, empty dope bags, and God knows what else that litters this part of the city is indescribable. I was hoping that the soil had somehow brewed a magic fertalizer, that would immediately turn me Mormon if I could only get the potion right.
Ingredients
- Water
- Ice
- Dissolved orange blossom honey (heat the water)
- Fresh mint
- Blackberries
It didn't work but it's the best lemonade I've ever had. The honey hits like adderall.
06/28/2024
The Kittens Let Me Pet Them
Huma found me long before the rest of the kittens worked up the courage to let me pet them. It took hours upon hours of hanging out in the backyard jungle, tossing various kind of treats, and most importantly gaining the trust of their mom. Huma watches from the window for now, but she eventually rejoins us outside to play with her kin.
Face reveal, be nice pls.
07/13/2024
The Overgrown Garden Boxes
The yard came equipped with two overgrown and broken down garden boxes. I spent the summer and winter pondering what I could do with that space and whether it was repairable.
I purchased some lamb from my favorite grocery store, Al-Amana, a Turkish grocery store connected to the Islamic community center. The cats were not very interested in raw meat. Huma prefers it cooked these days.
07/17/2024
The Table and Umbrella
At some point I cleared enough space to place a newly acquired solar power umbrella that fits in the glass table that came with the yard.
08/03/2024
Backyard, Back Garden Bed, Overgrowth Overview
The prospect of clearing out my backyard was looking bleak. I had kittens to dodge, a full-time job to maintain, self-actualization to achieve, spiritual growth pulling me in all directions, little knowledge, and no help.
Who even knows what those crazy berry jawns are, growing out of what is actually a cat manure, compost pit that reaks of high heaven?!?
08/10/2024
Cleared Out the Front Garden Bed Area
At some point I had cleared out most of the overgrowth around the front garden bed area and purchased a backpack to tote Huma around in. It looks like an alien spaceship and doubles as a Gondula for moving kittens into and out of the apartment.
Isis Gives Birth to Another Litter
Isis gave birth to another litter. She decided to post up in an old pallet that was already on the property to nurse them.