Compare commits
18 commits
53c0c6a9d6
...
f8c575caac
Author | SHA1 | Date | |
---|---|---|---|
f8c575caac | |||
b067f79e1c | |||
3f59c75523 | |||
41caa0573e | |||
c60ce1efdf | |||
f74480a2b0 | |||
d7469399ef | |||
14adc9fdf7 | |||
f6d73a1473 | |||
550c4613e7 | |||
b1ec578902 | |||
68530c58d9 | |||
bf3f2c4bf5 | |||
fd6b96f03d | |||
f46ca670fe | |||
278f5a8390 | |||
da4e562a06 | |||
4c3e514a14 |
19 changed files with 690 additions and 172 deletions
BIN
LICENSE.mp3
Normal file
BIN
LICENSE.mp3
Normal file
Binary file not shown.
3
blog
3
blog
|
@ -63,7 +63,8 @@ multi MAIN(
|
|||
#| The path of the database file
|
||||
IO::Path(Str) :$db-dir = $default-db-dir,
|
||||
) {
|
||||
read-db $db-dir;
|
||||
my $db = read-db $db-dir;
|
||||
$db.write: $db-dir;
|
||||
say "Database OK";
|
||||
}
|
||||
|
||||
|
|
7
db/meta.json
Normal file
7
db/meta.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"title": "Stranger Systems",
|
||||
"placeholder-id": 0,
|
||||
"base-url": "https://www.stranger.systems",
|
||||
"tagline": "Making software better by making it weird",
|
||||
"about-id": 2
|
||||
}
|
12
db/posts/0.json
Normal file
12
db/posts/0.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"slugs": [
|
||||
],
|
||||
"source": "/dev/null",
|
||||
"edited-at": [
|
||||
],
|
||||
"tags": [
|
||||
],
|
||||
"posted-at": "2025-02-05T04:54:41.218425-05:00",
|
||||
"hidden": true,
|
||||
"placeholder": true
|
||||
}
|
12
db/posts/1.json
Normal file
12
db/posts/1.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"tags": [
|
||||
],
|
||||
"slugs": [
|
||||
],
|
||||
"edited-at": [
|
||||
],
|
||||
"posted-at": "2025-02-05T06:00:49.553777-05:00",
|
||||
"hidden": false,
|
||||
"source": "/home/nathan/Projects/Blog/projects/Markdown/MyNewBlog.md",
|
||||
"markdown": true
|
||||
}
|
12
db/posts/2.json
Normal file
12
db/posts/2.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"posted-at": "2025-02-05T06:01:16.693698-05:00",
|
||||
"markdown": true,
|
||||
"edited-at": [
|
||||
],
|
||||
"slugs": [
|
||||
],
|
||||
"hidden": true,
|
||||
"source": "/home/nathan/Projects/Blog/projects/Markdown/About.md",
|
||||
"tags": [
|
||||
]
|
||||
}
|
13
db/posts/3.json
Normal file
13
db/posts/3.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"hidden": false,
|
||||
"posted-at": "2021-11-29T00:00:00Z",
|
||||
"tags": [
|
||||
"cryptography"
|
||||
],
|
||||
"source": "/home/nathan/Projects/Blog/projects/Markdown/CryptoSuite.md",
|
||||
"edited-at": [
|
||||
],
|
||||
"slugs": [
|
||||
],
|
||||
"markdown": true
|
||||
}
|
|
@ -35,9 +35,13 @@ method generate-head($title, BlogMeta:D $meta, $description?) {
|
|||
:href<https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap>;
|
||||
link :rel<stylesheet>,
|
||||
:href<https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css>;
|
||||
# Inline our style sheets
|
||||
style %?RESOURCES<main.css>.slurp;
|
||||
style %?RESOURCES<code.css>.slurp;
|
||||
# Link our style sheets
|
||||
link :rel<stylesheet>,
|
||||
:href</resources/colors.css>;
|
||||
link :rel<stylesheet>,
|
||||
:href</resources/main.css>;
|
||||
link :rel<stylesheet>,
|
||||
:href</resources/code.css>;
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ unit module DB;
|
|||
use Pandoc;
|
||||
use JSON::Class:auth<zef:vrurg>;
|
||||
use XML;
|
||||
use XQ;
|
||||
|
||||
use DB::Post;
|
||||
use DB::BlogMeta;
|
||||
|
@ -70,6 +71,12 @@ class PostDB {
|
|||
|
||||
#| Render the site to the provided output directory
|
||||
method render(IO::Path:D $out-dir, Config:D :$config = Config.new) {
|
||||
## Consistency checks
|
||||
# Check to make sure all the slugs are unique
|
||||
my @all-the-slugs = %!posts.values.map(*.all-slugs).flat;
|
||||
die "Duplicate slug detected"
|
||||
unless @all-the-slugs.unique.elems == @all-the-slugs.elems;
|
||||
## Rendering
|
||||
my $posts = $out-dir.add('posts/');
|
||||
my $by-id = $posts.add('by-id/');
|
||||
my $by-slug = $posts.add('by-slug/');
|
||||
|
@ -101,7 +108,13 @@ class PostDB {
|
|||
# Render the rss/atom feed
|
||||
my $atom-path = $out-dir.add('atom.xml');
|
||||
my $atom = posts-to-atom self;
|
||||
$atom-path.spurt: ~$atom;
|
||||
$atom-path.spurt: format-xml(~$atom);
|
||||
# Create the resources folder and copy over our style sheets
|
||||
my $res-dir = $out-dir.add('resources/');
|
||||
mkdir $res-dir unless $res-dir.e;
|
||||
$res-dir.add('colors.css').spurt: %?RESOURCES<colors.css>.slurp;
|
||||
$res-dir.add('main.css').spurt: %?RESOURCES<main.css>.slurp;
|
||||
$res-dir.add('code.css').spurt: %?RESOURCES<code.css>.slurp;
|
||||
}
|
||||
|
||||
#| Get a list of posts sorted by date
|
||||
|
|
|
@ -36,6 +36,8 @@ DateTime:D @.edited-at
|
|||
= [];
|
||||
#| An optional list of extra slugs to use for this post
|
||||
has Str:D @.slugs is json = [];
|
||||
#| An optional list of tags for this post
|
||||
has Str:D @.tags is json = [];
|
||||
#| Should the post be hidden from the main list
|
||||
has Bool:D $.hidden is json is rw = False;
|
||||
|
||||
|
@ -55,10 +57,14 @@ method updated(--> DateTime:D) {
|
|||
#| Get the list of slugs for this post, including ones auto generated from
|
||||
#| the title, as well as any additional slugs
|
||||
method all-slugs(--> Array[Str:D]) {
|
||||
my $long-title-slug = self.title.lc.trim.subst: /\h+/, '-', :g;
|
||||
my $title-words = self.title.lc.trim.words;
|
||||
my $long-title-slug = $title-words.join('-');
|
||||
my $six-word-slug = self.title.lc.words.head(6).join('-');
|
||||
my Str:D @slugs = @!slugs.clone;
|
||||
@slugs.push($long-title-slug);
|
||||
@slugs;
|
||||
@slugs.push($six-word-slug);
|
||||
@slugs.=unique;
|
||||
@slugs
|
||||
}
|
||||
|
||||
#| Render this post to an html body
|
||||
|
|
|
@ -79,7 +79,16 @@ sub markdown-first-paragraph(IO::Path:D $file --> Str:D) is export {
|
|||
$para ~= $component<c>;
|
||||
}
|
||||
when "Space" {
|
||||
$para ~= " ";
|
||||
$para ~= ' ';
|
||||
}
|
||||
when "Code" {
|
||||
$para ~= $component<c>[*-1];
|
||||
}
|
||||
when "SoftBreak" {
|
||||
$para ~= "\n";
|
||||
}
|
||||
when "Link" {
|
||||
$para ~= $component<c>[1][0]<c>;
|
||||
}
|
||||
default {
|
||||
die "Invalid component type: $_";
|
||||
|
|
10
lib/XQ.rakumod
Normal file
10
lib/XQ.rakumod
Normal file
|
@ -0,0 +1,10 @@
|
|||
#| Interaction with xq
|
||||
unit module XQ;
|
||||
|
||||
#| Format an xml string
|
||||
sub format-xml(Str:D $input --> Str:D) is export {
|
||||
my $xq = run <xq>, :out, :in;
|
||||
# Inject the xml
|
||||
$xq.in.spurt: $input, :close;
|
||||
$xq.out.slurp: :close
|
||||
}
|
|
@ -8,11 +8,16 @@ module Posts.HelloWorld
|
|||
|
||||
Here is an example function that prints to the standard out:
|
||||
|
||||
|
||||
function debug null byte compile syntax error protocol stack overflow cache memory leak parse integer void pointer exception handler runtime deploy code fragment database query optimize algorithm refactor git commit push merge conflict
|
||||
function debug null byte compile syntax error protocol stack overflow cache memory leak parse integer void pointer exception handler runtime deploy code fragment database query optimize algorithm refactor git commit push merge conflict
|
||||
function debug null byte compile syntax error protocol stack overflow cache memory leak parse integer void pointer exception handler runtime deploy code fragment database query optimize algorithm refactor git commit push merge conflict
|
||||
|
||||
function debug null byte compile syntax error protocol stack overflow cache
|
||||
memory leak parse integer void pointer exception handler runtime deploy code
|
||||
fragment database query optimize algorithm refactor git commit push merge
|
||||
conflict function debug null byte compile syntax error protocol stack overflow
|
||||
cache memory leak parse integer void pointer exception handler runtime deploy
|
||||
code fragment database query optimize algorithm refactor git commit push merge
|
||||
conflict function debug null byte compile syntax error protocol stack overflow
|
||||
cache memory leak parse integer void pointer exception handler runtime deploy
|
||||
code fragment database query optimize algorithm refactor git commit push merge
|
||||
conflict
|
||||
|
||||
```idris
|
||||
main : IO ()
|
||||
|
|
65
projects/Markdown/About.md
Normal file
65
projects/Markdown/About.md
Normal file
|
@ -0,0 +1,65 @@
|
|||
# About Me
|
||||
|
||||
My name is Nathan, I'm an engineering psychologist by training, and a systems
|
||||
engineer by trade.
|
||||
|
||||
I've had the good fortune to work professionally with rust for some time, as
|
||||
well as some other oddball languages like Haskell and F# back in the day. I
|
||||
current work for a state university's disability support center doing pretty
|
||||
mundane, but worthwhile webdev work.
|
||||
|
||||
I've previously worked in, and greatly enjoy working with, distributed systems.
|
||||
I also have deep interests in cryptography, authenticated data structures,
|
||||
archival, and formal verification methods.
|
||||
|
||||
Much of my recent hobby programming has revolved around a neat little language
|
||||
called [Idris2](https://github.com/idris-lang/Idris2), which is notable for
|
||||
revolving around dependent types while still being programmer focused rather
|
||||
than theorem proving focused. Dependent Typing has a lot of potential benefits
|
||||
for normal every day programmers, from being able to more easily express
|
||||
constraints in the type system to more easily getting the type system out of the
|
||||
way when you need to without losing its benefits, and you can expect to see a
|
||||
lot of programmer oriented content on dependent types on this blog.
|
||||
|
||||
## My Projects
|
||||
|
||||
### Rust
|
||||
|
||||
I don't do hobby work in rust very much anymore, but I've been around the
|
||||
ecosystem and still kick around in some rust spaces.
|
||||
|
||||
You may remember me from my work on
|
||||
[Asuran](https://sr.ht/~thatonelutenist/Asuran/), which has been on indefinite
|
||||
hiatus for a while now. Rust's type system's relative lack of power,
|
||||
particularly in the area of preventing common cryptography bugs without becoming
|
||||
overly verbose or relying on the library programmer to pinky promise to uphold
|
||||
their own invariants was a big motivator for me moving away from rust, and I
|
||||
hope to eventually pick Asuran back up some day and rewrite it in Idris or some
|
||||
other fun new language.
|
||||
|
||||
### Idris 2
|
||||
|
||||
I've written a few libraries and utilities for Idris 2 already:
|
||||
|
||||
- [rope](https://git.sr.ht/~thatonelutenist/idris2-rope)
|
||||
|
||||
A sized rope data structure for text manipulation
|
||||
|
||||
- [Structures](https://git.sr.ht/~thatonelutenist/Structures)
|
||||
|
||||
A collection of implementations of useful data structures
|
||||
|
||||
- [iutils](https://git.stranger.systems/Idris/iutils-raku)
|
||||
|
||||
A collection of prototype tools for working with Idris projects. Currently
|
||||
provides comment-based unit testing capability. Currently written in Raku, I
|
||||
hope to eventually rewrite this in idris.
|
||||
|
||||
### Books
|
||||
|
||||
- [Idris by Highly Contrived Example](https://static.stranger.systems/idris-by-contrived-example/)
|
||||
|
||||
A very work in progress project to explore functional programming and
|
||||
dependent typing concepts by solving every advent of code problem in one big
|
||||
literate Idris project, only taking small steps in understanding with each new
|
||||
day.
|
211
projects/Markdown/CryptoSuite.md
Normal file
211
projects/Markdown/CryptoSuite.md
Normal file
|
@ -0,0 +1,211 @@
|
|||
# Why I have settled on XChaCha20+Blake3 as the AE suite of choice for my projects
|
||||
|
||||
This might get me some looks, but I have pretty solidly decided to go in on
|
||||
using XChaCha20+Blake3 as the AE of choice for my future open source work. There
|
||||
are numerous reasons for this decision, but it mainly comes down to the desire
|
||||
for defense in depth, and a deep dislike of fundamental properties of polynomial
|
||||
MACs.
|
||||
|
||||
## The Why Nots
|
||||
|
||||
### Why not just use poly1305?
|
||||
|
||||
The burning question, I can hear it now:
|
||||
|
||||
> Why not just use ChaCha20-poly1305? Its standard, and its good enough for
|
||||
> \<insert application here>? Why roll your own crypto?
|
||||
|
||||
The reason for this gets at a fundamental property of polynomial MACs[^1] that
|
||||
opens them up to all kinds of fun attacks, like the partitioning oracle[^2], you
|
||||
didn't even know you needed to worry about. Polynomial MACs violate intuitive
|
||||
expected properties of cryptosystems, and are so finicky to work with that even
|
||||
the specification for AES-GCM contained invalid proofs of its security[^3].
|
||||
|
||||
There is a not-infrequently important property of cryptosystems, referred to as
|
||||
"commiting to their keys", or simply "being commiting"[^4]. Simply put, a system
|
||||
has this property when it is impractical to produce a message that will
|
||||
successfully decrypt or verify under multiple chosen keys. As a fundamental
|
||||
result of their construction, polynomial MACs lack this property, and its even
|
||||
worse than simply being able to construct a message that will decrypt under two
|
||||
chosen keys. Even for the more well behaved polynomial MACs, such as Poly1305,
|
||||
it is not only practical to construct garden variety collisions, it is practical
|
||||
to construct multi-collisions that will decrypt under a large number of chosen
|
||||
keys[^5] .
|
||||
|
||||
This lack of even a facade of collision resistance can actually turn into quite
|
||||
a big deal, just as Mega[^6] famously experienced a loss of security due to
|
||||
their inappropriate use of CBC-MAC (another type of MAC that also lacks
|
||||
collision resistance) polynomial MACs, in practice, worm their way into all
|
||||
kinds of places they shouldn't be, places where a collision resistant MAC would
|
||||
have been the only appropriate choice. Even in the context of more seemingly
|
||||
sane systems, this lack of collision resistance can cause no end of problems,
|
||||
such as the partitioning oracle attack [^1], which was practically exploitable
|
||||
for over the network password recovery in Shadowsocks, and the always
|
||||
interesting Invisible Salamander[^7].
|
||||
|
||||
These issues alone are, personally, enough to turn me off from using poly1305 or
|
||||
any other polynomial MACs in any of my future projects, given that it's 2021 and
|
||||
hashes are fast now, but, it is my opinion that polynomial MACs being
|
||||
non-collision resistant represents a huge foot gun, and as I am not a fan of
|
||||
handing foot guns to the consumers of my code, I will refrain from offering this
|
||||
one, and provide a committing, collision resistant scheme instead.
|
||||
|
||||
### Why not use AES
|
||||
|
||||
This one should be a little bit easier to answer, its not exactly a hot take to
|
||||
say that AES is a lot closer to the bottom of the acceptable ciphers barrel than
|
||||
ChaCha20[^8]. Even discounting the standard complaints, like how AES's
|
||||
construction is somewhat-intrinsically vulnerable to cache based timing attacks
|
||||
when implemented in software[^9] (though bit-slicing and other tricks mitigate
|
||||
this, they are surprisingly rare to see in the wild, even in software running on
|
||||
devices that lack hardware accelerated AES), and how the block size is too
|
||||
small[^10], AES still has other concerning factors in its corner, like how the
|
||||
PRP-PRF distinguishing attack reduces the effective security of AES in counter
|
||||
mode.
|
||||
|
||||
AES just, all around, isn't ideal. Sure, ChaCha is naturally vulnerable to
|
||||
electromagnetic side channel attacks[^12], which have been an item of, ehm,
|
||||
_increasing concern_ for me[^13], AES is just as vulnerable in that regard, with
|
||||
even side-channel resistant hardware implementations being a rare thing, and for
|
||||
most practical purposes, only existing in the literature[^14]. ChaCha20's much
|
||||
larger block size (512-bit) and more timing side channel resistant construction
|
||||
just lends itself to fewer foot guns, and while hardware assisted AES is a bit
|
||||
faster, I don't think there is enough of a speed differential to warrant the
|
||||
loss of misuse resistance in most applications.
|
||||
|
||||
### Why not Panic
|
||||
|
||||
This is not intended to be an indictment of any particular protocol, while the
|
||||
issues I've brought up are real, and can result in vulnerabilities in the real
|
||||
world, none of them are automatically going to lead to an exploitable
|
||||
vulnerability. The people making the systems you rely on to keep your private
|
||||
data safe by and large understand the state of the research on the matter, and
|
||||
are careful to design systems to avoid the foot guns. Your AES-GCM or
|
||||
ChaCha20-Poly1305 TLS stream is not in immediate peril.
|
||||
|
||||
Cryptographic primitives don't exist in a vacuum, any analysis of
|
||||
vulnerabilities must be done on complete systems, as decisions on any level
|
||||
above the choice of fundamental primitives may sink _or_ save the ship[^15].
|
||||
|
||||
My interest in writing this post is in informing the design of new systems,
|
||||
where I much prefer foot guns be avoided categorically instead of case-by-case,
|
||||
when practical, and I believe the time has come where the use of cryptosystems
|
||||
that categorically avoid these foot guns is practical in all but niche edge case
|
||||
scenarios.
|
||||
|
||||
## The Whys
|
||||
|
||||
### Why use XChaCha20
|
||||
|
||||
ChaCha20 has a number of benefits over AES, and I don't really feel the need to
|
||||
go _too_ deep into them, but lets give the overview. ChaCha20 is a stream
|
||||
cipher, but it acts like a block cipher being used in CTR mode. In this respect,
|
||||
it has two major advantages over AES-CTR:
|
||||
|
||||
1. The block size is 512 bits, compared to AES's 128 bits, making a wide variety
|
||||
of attacks, such as birthday bound or PRP-PRF distinguishing attacks _many_
|
||||
orders of magnitude less practical to pull of against ChaCha
|
||||
1. The nonce is provided to the underlying cipher independently from the stream
|
||||
position. This has the nice practical effect of making accidental nonce-reuse
|
||||
_that_ much harder, since while a given AES-CTR stream consumes a range of
|
||||
nonces, a given ChaCha stream consumes only one
|
||||
|
||||
ChaCha20 also has other advantages, like being more energy efficient when
|
||||
dedicated hardware isn't available, and being naturally resistant to timing side
|
||||
channel attacks. The only real disadvantage is that it is slower than commonly
|
||||
available hardware accelerated AES, but not by an amount that I think makes a
|
||||
critical difference for all but the pickiest of applications.
|
||||
|
||||
The choice of XChaCha20 over that of plain ChaCha20 is also easy to explain.
|
||||
ChaCha20 only gives you a 64 bit nonce, which, while enough to encrypt the world
|
||||
with a given key, means that choosing a nonce at random can be incredibly
|
||||
dangerous, even AES-GCM's 96-bit nonce is much too small, leading to concrete
|
||||
failures in production[^16], and even the 128-bit nonce of straight AES-CTR
|
||||
leaves me feeling uneasy, the birthday bound there is a lot lower than it feels
|
||||
like it is. XChaCha20's choice of a 192 bit nonce, however, leaves plenty of
|
||||
headroom to feel safe, even when randomly selecting nonces, taking another foot
|
||||
gun out of the equation.
|
||||
|
||||
### Why use Blake3
|
||||
|
||||
This is another easy one to answer. The biggest reason, is, well Blake3 is
|
||||
_fast_, several times faster than ChaCha20 on my machine, and having an HMAC
|
||||
that can out run your cipher several times over is always handy when building
|
||||
HMAC based cryptosystems. In my opinion having a hash, like Blake3, that's truly
|
||||
_fast_ changes the trade off analysis, making it much less worth the trade off
|
||||
of using a polynomial MAC.
|
||||
|
||||
Blake3 also has some other nice properties, its a modern, secure,
|
||||
length-extension resistant hash based on a merkle tree construction, which
|
||||
provides lots of other side benefits, such as the ability to use the hash for
|
||||
verified streaming. It additionally has the nice property of not _really_ having
|
||||
variants, with the HMAC, KDF, hash, and XOF modes all operating in a very
|
||||
similar and consistent manner, easing the cognitive load on the programmer.
|
||||
|
||||
Being effectively an HMAC, Blake3 also provides a scheme that commits to its
|
||||
keys, almost for free as a side effect of collision resistance, directly
|
||||
sidestepping my concerns about polynomial MACs.
|
||||
|
||||
## Conclusion
|
||||
|
||||
I believe that using XChaCha20-Blake3 in the encrypt-then-hmac construction
|
||||
provides a more-than-fast-enough base to build more than useable cryptosystems
|
||||
on top of, and acts as a primitive for doing so that presents substantially
|
||||
fewer foot guns than other competing options, while still remaining more than
|
||||
useably fast, even in the absence of dedicated hardware acceleration. Humans are
|
||||
such fallible creatures, and accidental de-footings are _much_ less likely to
|
||||
happen when we are provided fewer chances to do so.
|
||||
|
||||
[^1]: A family of very closely related Message Authentication Codes, including
|
||||
AES-GCM's [GHASH](https://en.wikipedia.org/wiki/Galois/Counter_Mode),
|
||||
AES-GCM-SIV's Polyval, and
|
||||
[Poly1305](https://en.wikipedia.org/wiki/Poly1305)
|
||||
|
||||
[^2]: Julia Len, Paul Grubbs and Thomas Ristenpart:
|
||||
[Partitioning Oracle Attacks (USENIX '21)](https://www.usenix.org/conference/usenixsecurity21/presentation/len)
|
||||
|
||||
[^3]: Tetsu Iwata, Keisuke Ohashi, Kazuhiko Minematsu:
|
||||
[Breaking and Repairing GCM Security Proofs (CRYPTO 2012)](https://www.iacr.org/cryptodb/data/paper.php?pubkey=24296)
|
||||
|
||||
[^4]: [OPAQUE protocol specification section discussing this](https://datatracker.ietf.org/doc/html/draft-krawczyk-cfrg-opaque-03#section-3.1.1)
|
||||
|
||||
[^5]: Kryptos Logic:
|
||||
[Faster Poly1305 key multicollisons](https://www.kryptoslogic.com/blog/2021/01/faster-poly1305-key-multicollisions/)
|
||||
|
||||
[^6]: [Megafail](https://fail0verflow.com/blog/2013/megafail/)
|
||||
|
||||
[^7]: Yevgeni Dodis, Paul Grubbs, Thomas Ristenpart, Joanne Woodage:
|
||||
[Fast Message Franking: From Invisible Salamanders to Encryptment (CRYPTO 2018)](https://eprint.iacr.org/2019/016.pdf)
|
||||
|
||||
[^8]: Source: My Ass
|
||||
|
||||
[^9]: Daniel J. Bernstein:
|
||||
[Cache-timing attacks on AES](https://cr.yp.to/antiforgery/cachetiming-20050414.pdf)
|
||||
|
||||
[^10]: Even AES256 has a block size of 128 bits, which means you can start
|
||||
expecting collisions after 2^64 encryptions. This sounds like a lot, and the
|
||||
exact details of how this can cause a mode of operation to break down depend
|
||||
on the particular mode, but that's a not an unachievable amount of data, the
|
||||
internet does that much every few months (assuming 1 block per encryption),
|
||||
and the security can start to break down well before the 2^64 mark.
|
||||
[https://www.youtube.com/watch?v=v0IsYNDMV7A](https://www.youtube.com/watch?v=v0IsYNDMV7A)
|
||||
|
||||
[^12]: Alexandre Adomnicai, Jacques J.A. Fournier, Laurent Masson:
|
||||
[Bricklayer Attack: A Side-Channel Analysis on the ChaCha Quarter Round](https://eprint.iacr.org/2017/1021.pdf)
|
||||
|
||||
[^13]: Giovanni Camurati, Sebastian Poeplau, Marius Muench, Tom Hayes, Aurélien
|
||||
Francillon:
|
||||
[Screaming Channels: When Electromagnetic Side Channels Meet Radio Transceivers](https://www.s3.eurecom.fr/docs/ccs18_camurati_preprint.pdf)
|
||||
|
||||
[^14]: Raghavan Kumar, Vikram Suresh, Monodeep Kar, et al:
|
||||
[A 4900-μm2 839-Mb/s Side-Channel Attack-Resistant AES-128 in 14-nm CMOS With Heterogeneous Sboxes, Linear Masked MixColumns, and Dual-Rail Key Addition](https://ieeexplore.ieee.org/document/8952789)
|
||||
|
||||
[^15]: One good example of it _saving_ the ship is HMAC-MD5. While the MD5 hash has
|
||||
been blown pretty widely open, the common HMAC construction gets many of its
|
||||
security guarantees from the first-preimage resistance of the underlying
|
||||
hash, and as there are no known practical first preimage attacks against
|
||||
MD5, HMAC-MD5 remains largely secure (please do not use it for new systems
|
||||
though)
|
||||
|
||||
[^16]: Hanno Böck, Aaron Zauner, Sean Devlin, Juraj Somorovsky, Phillip Jovanovic:
|
||||
[Nonce-Disrespecting Adversaries: Practical](https://eprint.iacr.org/2016/475.pdf)
|
|
@ -1,23 +1,110 @@
|
|||
# My New Blog
|
||||
# Blogging In Gremlin Mode
|
||||
|
||||
This is a blog that uses a static site generator written in raku!
|
||||
Due to a number of factors, including the uncertain future of the `.io` TLD, its
|
||||
growing negative connotations, and my development focus switching to lil baby
|
||||
languages like [Idris](https://github.com/idris-lang/Idris2), I've found myself
|
||||
in need of a new blog. I've been using [Raku](https://raku.org/) lately for
|
||||
personal tooling projects, and decided to go full gremlin mode and write a hack
|
||||
together a cursed static site generator in it.
|
||||
|
||||
## A sub headings
|
||||
## Motivation
|
||||
|
||||
With some text under it
|
||||
The domain change has obvious enough reasons, I've actually had this domain for
|
||||
quite some time and not been using it for much beyond email. The reasons for
|
||||
building a new static site generator are much more interesting.
|
||||
|
||||
### A third layer
|
||||
As I've recently taken up working pretty heavily in Idris, I've had to deal with
|
||||
quite an interesting problem with sharing code snippets and writing
|
||||
documentation. Idris is a very... interesting language to provide quality syntax
|
||||
highlighting for, regular functions being able to appear in type signatures
|
||||
makes providing semantic highlighting quite difficult, but the dependently typed
|
||||
nature of the language also makes semantic highlighting _extremely_ attractive.
|
||||
|
||||
Even more text
|
||||
Every source forge or off-the-shelf highlighting library I have tried either
|
||||
just completely has a stroke when presented Idris code[^1], likely due to using
|
||||
a slightly modified, but not entirely correctly done, version of Haskell
|
||||
highlighting rules, or has consistent syntax highlighting, but on low battery
|
||||
[^2].
|
||||
|
||||
## Back up
|
||||
Fortunately, Idris helps us out here, the compiler contains a semantic
|
||||
highlighter built in, it can compile markdown files directly[^3], and there is
|
||||
even a tool, [Katla](https://github.com/idris-community/katla), that can process
|
||||
source files, literate markdown or just plain Idris alike, and bake the
|
||||
highlighting into the html. Not so fortunately, this only provides us part of
|
||||
the puzzle. Katla only syntax highlights, it doesn't do any of the rest of the
|
||||
processing to produce html from markdown, and it's a little bit silly with also
|
||||
baking css styling into its output, but not allowing that css styling to be
|
||||
fully configured. For Idris heavy blogging, using literate/markdown Idris source
|
||||
files as the blog posts themeselves, I need a static site generator that has
|
||||
excellent support for mangling markdown and html at several points along the
|
||||
process.
|
||||
|
||||
function debug null byte compile syntax error protocol stack overflow cache memory leak parse integer void pointer exception handler runtime deploy code fragment database query optimize algorithm refactor git commit push merge conflict
|
||||
I've been using Raku for more and more personal tooling tasks recently, and
|
||||
growing increasingly fond of it, it truly warms my little gremlin heart to use,
|
||||
so it was a natural target for hacking together a basic static site generator
|
||||
from stuff I just had laying around.
|
||||
|
||||
### Back down
|
||||
## Method
|
||||
|
||||
here we go
|
||||
The source code for this new blog is available
|
||||
[here](https://git.stranger.systems/thatonelutenist/website). This code _is not_
|
||||
shared in the hopes that you will reuse it, it is instead shared so you can
|
||||
learn from it, be inspired by it, or maybe just be a little less scared of
|
||||
writing the cursed code that just gets your current personal project done after
|
||||
you see the fresh hell I'm shipping into my personal production. If I catch you
|
||||
using this code for your own website, or even worse, asking for help using it, I
|
||||
will personally revoke your ability to type the letter `f`.
|
||||
|
||||
#### even further
|
||||
This is, overall, a very basic markdown based static site generator, with the
|
||||
markdown → html conversion being handled by [pandoc](https://pandoc.org/). Some
|
||||
handrolled html and css is glued around the pandoc output, and some very basic
|
||||
html generation is done for the index and archive pages. To allow the literate
|
||||
Idris posts to live in a proper Idris package, the site generator assumes no
|
||||
structure to the markdown files, and stores metadata about posts, including the
|
||||
location of the source files and what type a given post is, in a directory
|
||||
structure containing JSON files.
|
||||
|
||||
weeeeee
|
||||
The really fun part is processing the output from Katla. Katla's markdown mode
|
||||
is used to provide syntax highlighting for the Idris code blocks in a literate
|
||||
Idris post, the markdown output from Katla is fed into pandoc, and from there, I
|
||||
go full gremlin mode and just
|
||||
[completely mangle the html with regexes](https://git.stranger.systems/thatonelutenist/website/src/branch/trunk/lib/DB/IdrisPost.rakumod)[^4]
|
||||
to remove the katla generated css, massage the generated tag structure to match
|
||||
the css I want to write, and clean up a bizarre issue where this pipeline is
|
||||
erroneously adding way more backslashes than it should to escape some
|
||||
characters.
|
||||
|
||||
The generation of the Atom feed is actually handled somewhat properly, using a
|
||||
proper XML library and everything!
|
||||
|
||||
This is all horribly, _horribly_ cursed, and should probably never see the light
|
||||
of day, but because this is just for me, and I control all the inputs to the
|
||||
system, It's Fine ™.
|
||||
|
||||
## Fun notes
|
||||
|
||||
At the time of writing, my `IdrisPost.rakumod` module, for reasons unknown to
|
||||
me, breaks forgejo and causes a server-side index out of bounds error when you
|
||||
try to use the source code for that module, so sorry if the above link takes you
|
||||
to an error message instead of the source code. If this isn't fixed the next
|
||||
time I get around to updating forgejo on my server, I'll file a bug report I
|
||||
promise.
|
||||
|
||||
The handrolled css for this site is light-mode/dark-mode aware, and, at the time
|
||||
of writing, uses selenized[^5] white/black for the main content, and dark/light
|
||||
for code blocks.
|
||||
|
||||
[^1]: Forgejo is frequently guilty of this
|
||||
|
||||
[^2]: Sourcehut falls in this category
|
||||
|
||||
[^3]: Idris's
|
||||
[Literate Programming](https://idris2.readthedocs.io/en/latest/reference/literate.html#literate-programming)
|
||||
support is honestly amazing. Not only can it handle markdown files exactly
|
||||
as if they were the source files you could get by extracting the idris code
|
||||
blocks, it supports several other formats, like org mode, latex, and even
|
||||
typst now.
|
||||
|
||||
[^4]: I can not be stopped and I will not apologize
|
||||
|
||||
[^5]: <https://github.com/jan-warchol/selenized>
|
||||
|
|
|
@ -1,45 +1,22 @@
|
|||
/* Set the font for code blocks */
|
||||
code {
|
||||
font-family: "Iosevka Web", monospace;
|
||||
background-color: light-dark(#fbf3db, #103c48);
|
||||
color: light-dark(#53676d, #adbcbc);
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
/* Styling for inline code blocks */
|
||||
:not(pre) > code {
|
||||
padding: 0 0.25rem;
|
||||
}
|
||||
|
||||
/* Styling for fenced code blocks */
|
||||
pre > code {
|
||||
display: block;
|
||||
white-space: pre-wrap;
|
||||
padding: 1rem;
|
||||
border-radius: 0.55rem / 0.5rem;
|
||||
white-space: pre-wrap;
|
||||
overflow-x: auto;
|
||||
word-wrap: normal;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hl-type {
|
||||
color: light-dark(#ad8900, #dbb32d);
|
||||
}
|
||||
|
||||
.hl-module {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-function {
|
||||
color: light-dark(#428b00, #84c747);
|
||||
}
|
||||
|
||||
.hl-bound {
|
||||
color: light-dark(#ca4898, #f275be);
|
||||
}
|
||||
|
||||
.hl-keyword {
|
||||
color: light-dark(#0072d4, #4695f7);
|
||||
}
|
||||
|
||||
.hl-comment {
|
||||
color: light-dark(#909995, #72898f);
|
||||
}
|
||||
|
||||
.hl-data {
|
||||
color: light-dark(#d2212d, #ed4a46)
|
||||
width: 90%;
|
||||
}
|
||||
|
|
98
resources/colors.css
Normal file
98
resources/colors.css
Normal file
|
@ -0,0 +1,98 @@
|
|||
:root {
|
||||
color-scheme: light dark;
|
||||
/* Selenized White/Black for main content */
|
||||
--bg-0: light-dark(#ffffff,#181818);
|
||||
--bg-1: light-dark(#ebebeb,#252525);
|
||||
--bg-2: light-dark(#cdcdcd,#3b3b3b);
|
||||
--dim-0: light-dark(#878787,#777777);
|
||||
--fg-0: light-dark(#474747,#b9b9b9);
|
||||
--fg-1: light-dark(#282828,#dedede);
|
||||
--red: light-dark(#d6000c,#ed4a46);
|
||||
--green: light-dark(#1d9700,#70b433);
|
||||
--yellow: light-dark(#c49700,#dbb32d);
|
||||
--blue: light-dark(#0064e4,#368aeb);
|
||||
--magenta: light-dark(#dd0f9d,#eb6eb7);
|
||||
--cyan: light-dark(#00ad9c,#3fc5b7);
|
||||
--orange: light-dark(#d04a00,#e67f43);
|
||||
--violet: light-dark(#7f51d6,#a580e2);
|
||||
/* Selenized Light/Dark for code content */
|
||||
--code-bg-0: light-dark(#fbf3db,#103c48);
|
||||
--code-bg-1: light-dark(#ece3cc,#184956);
|
||||
--code-bg-2: light-dark(#d5cdb6,#2d5b69);
|
||||
--code-dim-0: light-dark(#909995,#72898f);
|
||||
--code-fg-0: light-dark(#53676d,#adbcbc);
|
||||
--code-fg-1: light-dark(#3a4d53,#cad8d9);
|
||||
--code-red: light-dark(#d2212d,#fa5750);
|
||||
--code-green: light-dark(#489100,#75b938);
|
||||
--code-yellow: light-dark(#ad8900,#dbb32d);
|
||||
--code-blue: light-dark(#0072d4,#4695f7);
|
||||
--code-magenta: light-dark(#ca4898,#f275be);
|
||||
--code-cyan: light-dark(#009c8f,#41c7b9);
|
||||
--code-orange: light-dark(#c25d1e,#ed8649);
|
||||
--code-violet: light-dark(#8762c6,#af88eb);
|
||||
/* Set basic colors */
|
||||
color: var(--fg-0);
|
||||
background-color: var(--bg-1);
|
||||
}
|
||||
|
||||
/* Set link colors */
|
||||
a:link {
|
||||
color: var(--cyan);
|
||||
}
|
||||
a:visited {
|
||||
color: var(--magenta);
|
||||
}
|
||||
|
||||
/* Color our main content elements */
|
||||
.site-header {
|
||||
background-color: var(--bg-0);
|
||||
}
|
||||
.site-logo {
|
||||
color: var(--red);
|
||||
}
|
||||
.site-tagline {
|
||||
color: var(--dim-0);
|
||||
}
|
||||
.post-body, .post-header, .post-blurbs {
|
||||
background-color: var(--bg-0);
|
||||
}
|
||||
.post-blurb {
|
||||
background-color: var(--bg-1);
|
||||
}
|
||||
.post-title, .post-blurbs > h1 {
|
||||
color: var(--green);
|
||||
}
|
||||
.post-body > h2, .post-body > h3, .post-body > h4 {
|
||||
color: var(--fg-1);
|
||||
}
|
||||
blockquote {
|
||||
background-color: var(--bg-1);
|
||||
}
|
||||
|
||||
/* Colorization for code blocks */
|
||||
code {
|
||||
color: var(--code-fg-0);
|
||||
background-color: var(--code-bg-0);
|
||||
}
|
||||
.hl-type {
|
||||
color: var(--code-yellow);
|
||||
}
|
||||
.hl-module {
|
||||
font-style: italic;
|
||||
color: car(--code-fg-1);
|
||||
}
|
||||
.hl-function {
|
||||
color: var(--code-green);
|
||||
}
|
||||
.hl-bound {
|
||||
color: var(--code-magenta);
|
||||
}
|
||||
.hl-keyword {
|
||||
color: var(--code-blue);
|
||||
}
|
||||
.hl-comment {
|
||||
color: var(--code-dim-0);
|
||||
}
|
||||
.hl-data {
|
||||
color: var(--code-red);
|
||||
}
|
|
@ -1,150 +1,126 @@
|
|||
:root {
|
||||
color-scheme: light dark;
|
||||
color: light-dark(#474747, #b9b9b9);
|
||||
background-color: light-dark(#ebebeb, #252525);
|
||||
font-family: "Open Sans", sans-serif, serif;
|
||||
/* Variables */
|
||||
--content-width: 60rem;
|
||||
--header-width: 35rem;
|
||||
--box-padding-vert: 1rem;
|
||||
--box-padding-horz: 1rem;
|
||||
--box-margin-vert: 0.5rem;
|
||||
--box-margin-horz: 0.5rem;
|
||||
--box-gap: 0.5rem;
|
||||
--box-radius: 1rem;
|
||||
}
|
||||
|
||||
/* slightly larger than content-width to account for padding/margins */
|
||||
@media screen and (max-width: 62rem) {
|
||||
:root {
|
||||
--content-width: 95vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main Body and Post Flexboxs */
|
||||
body, .post {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
gap: var(--box-gap);
|
||||
}
|
||||
|
||||
/* Style the site header */
|
||||
.site-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: var(--header-width);
|
||||
padding: var(--box-padding-vert) var(--box-padding-horz);
|
||||
border-radius: var(--box-radius);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.site-logo {
|
||||
font-size: 2.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.site-tagline {
|
||||
font-size: 0.9rem;
|
||||
font-style: italic;
|
||||
}
|
||||
.header-links {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
gap: var(--box-gap);
|
||||
font-size: 1.1rem;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0.5rem;
|
||||
margin-top: var(--box-margin-vert);
|
||||
}
|
||||
.header-links > a > span {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.header-links > a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.site-header {
|
||||
width: 50%;
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
border-radius: 1rem;
|
||||
background-color: light-dark(#ffffff, #181818);
|
||||
|
||||
/* Style the post header, body, and blurbs */
|
||||
/* TODO: Style footnotes and get footnote hover working */
|
||||
.post-header, .post-body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.site-logo {
|
||||
color: light-dark(#d6000c, #ed4a46);
|
||||
font-size: 2.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.site-tagline {
|
||||
color: light-dark(#909995, #777777);
|
||||
font-size: 0.9rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.post-body, .post-header, .post-blurbs {
|
||||
width: 66%;
|
||||
display: block;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-radius: 1rem;
|
||||
background-color: light-dark(#ffffff, #181818);
|
||||
/* text-align: justify; */
|
||||
}
|
||||
|
||||
.post-blurbs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.post-blurb {
|
||||
gap: var(--box-gap);
|
||||
width: 100%;
|
||||
display: block;
|
||||
border-radius: 1rem;
|
||||
padding: 0.5rem;
|
||||
background-color: light-dark(#ebebeb, #252525);
|
||||
/* background-color: light-dark(#cdcdcd, #3b3b3b); */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
/* gap: 0.25rem; */
|
||||
max-width: var(--content-width);
|
||||
padding: var(--box-padding-vert) var(--box-padding-horz);
|
||||
border-radius: var(--box-radius);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.post-header {
|
||||
padding: 1.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
.post-body > p {
|
||||
margin: auto var(--box-margin-horz);
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.post-title {
|
||||
text-align: center;
|
||||
color: light-dark(#dd0f9d, #eb6eb7);
|
||||
}
|
||||
|
||||
.post-blurbs > h1 {
|
||||
color: light-dark(#1d9700, #70b433);
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: light-dark(#009c8f, #41c7b9);
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: light-dark(#dd0f9d, #eb6eb7);
|
||||
}
|
||||
.post-title > h1, .post-blurb-title > h2 {
|
||||
.post-title > h1 {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.post-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
color: light-dark(#909995, #777777);
|
||||
gap: var(--box-gap);
|
||||
font-size: 0.9rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.post-read-time {
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
.post-body > h2 {
|
||||
.post-body > h2, .post-body > h3, .post-body > h4 {
|
||||
text-align: center;
|
||||
color: light-dark(#282828, #dedede);
|
||||
}
|
||||
.post-blurbs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--box-gap);
|
||||
max-width: var(--content-width);
|
||||
padding: var(--box-padding-vert) var(--box-padding-horz);
|
||||
border-radius: var(--box-radius);
|
||||
}
|
||||
.post-blurb {
|
||||
width: 100%;
|
||||
display: block;
|
||||
border-radius: var(--box-radius);
|
||||
padding: var(--box-padding-vert) var(--box-padding-horz);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.post-body > h3 {
|
||||
text-align: center;
|
||||
color: light-dark(#282828, #dedede);
|
||||
}
|
||||
|
||||
.post-body > h4 {
|
||||
text-align: center;
|
||||
color: light-dark(#282828, #dedede);
|
||||
}
|
||||
/* .post-body > p { */
|
||||
/* text-indent: 2ch; */
|
||||
/* } */
|
||||
|
||||
a > span {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
/* TODO: Nice fancy blockquotes */
|
||||
blockquote {
|
||||
width: 90%;
|
||||
border-radius: var(--box-radius);
|
||||
padding: var(--box-padding-vert) var(--box-padding-horz);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue