decentralized identity blog post, plus some logseq support
This commit is contained in:
parent
90de593a38
commit
9046fcc57e
8 changed files with 189 additions and 17 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
/public
|
/public
|
||||||
/old
|
/old
|
||||||
/resources
|
/resources
|
||||||
|
/content/logseq
|
||||||
|
|
||||||
.hugo_build.lock
|
.hugo_build.lock
|
||||||
.direnv
|
.direnv
|
||||||
|
|
|
@ -5,7 +5,8 @@ html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection, ::-moz-selection {
|
::selection,
|
||||||
|
::-moz-selection {
|
||||||
background-color: $heading-color;
|
background-color: $heading-color;
|
||||||
color: $background-color;
|
color: $background-color;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +24,12 @@ body {
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
color: $heading-color;
|
color: $heading-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +69,9 @@ footer {
|
||||||
@media screen and (max-width: 672px) {
|
@media screen and (max-width: 672px) {
|
||||||
.flex-wrapper {
|
.flex-wrapper {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
.container { padding: 5px 20px; }
|
.container {
|
||||||
|
padding: 5px 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-nav {
|
.side-nav {
|
||||||
|
@ -77,11 +85,15 @@ footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
}
|
}
|
||||||
h1 { display: inline; }
|
h1 {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
.portrait {
|
.portrait {
|
||||||
max-height: 80px;
|
max-height: 80px;
|
||||||
}
|
}
|
||||||
.bio { display: none; }
|
.bio {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +101,9 @@ footer {
|
||||||
@media screen and (min-width: 672px) {
|
@media screen and (min-width: 672px) {
|
||||||
.flex-wrapper {
|
.flex-wrapper {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
.container { padding: 32px 40px 5px 40px; }
|
.container {
|
||||||
|
padding: 32px 40px 5px 40px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-nav {
|
.side-nav {
|
||||||
|
@ -111,13 +125,14 @@ footer {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1.title { text-align: center; }
|
h1.title {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-nav {
|
.side-nav {
|
||||||
|
|
||||||
.side-nav-content {
|
.side-nav-content {
|
||||||
.home-link {
|
.home-link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -173,7 +188,7 @@ blockquote {
|
||||||
|
|
||||||
.postlisting-row td {
|
.postlisting-row td {
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
line-height: 1.0;
|
line-height: 1;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
|
@ -245,7 +260,8 @@ table.table {
|
||||||
color: $background-color;
|
color: $background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody td, thead th {
|
tbody td,
|
||||||
|
thead th {
|
||||||
border: 1px solid $faded;
|
border: 1px solid $faded;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
@ -302,7 +318,9 @@ table.table {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.toc-list { display: none; }
|
.toc-list {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@media screen and (max-width: 520px) {
|
@media screen and (max-width: 520px) {
|
||||||
|
@ -327,10 +345,28 @@ table.table {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.post-content {
|
.post-content {
|
||||||
|
ul {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
min-width: 1px;
|
min-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc-draw #TableOfContents, .toc-list #TableOfContents {
|
&.logseq-post {
|
||||||
|
.post-content {
|
||||||
|
> ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc-draw #TableOfContents,
|
||||||
|
.toc-list #TableOfContents {
|
||||||
ul {
|
ul {
|
||||||
list-style-type: "\25B8\00A0";
|
list-style-type: "\25B8\00A0";
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
|
@ -344,9 +380,23 @@ table.table {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
|
||||||
|
thead {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.division .post-content, .post-content {
|
.division .post-content,
|
||||||
|
.post-content {
|
||||||
.heading {
|
.heading {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
|
@ -365,7 +415,7 @@ table.table {
|
||||||
}
|
}
|
||||||
|
|
||||||
.footnotes {
|
.footnotes {
|
||||||
font-size: .9em;
|
font-size: 0.9em;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ $monofont: "PragmataPro Mono Liga", "Roboto Mono", "Roboto Mono for Powerline",
|
||||||
$faded-background-color: lighten($background-color, 10%);
|
$faded-background-color: lighten($background-color, 10%);
|
||||||
$shadow-color: lighten($background-color, 10%);
|
$shadow-color: lighten($background-color, 10%);
|
||||||
$heading-color: lighten(lightskyblue, 20%);
|
$heading-color: lighten(lightskyblue, 20%);
|
||||||
$text-color: #BCBCBC;
|
$text-color: #CDCDCD;
|
||||||
$small-text-color: darken($text-color, 8%);
|
$small-text-color: darken($text-color, 8%);
|
||||||
$smaller-text-color: darken($text-color, 12%);
|
$smaller-text-color: darken($text-color, 12%);
|
||||||
$faded: #666;
|
$faded: #666;
|
||||||
|
|
|
@ -3,6 +3,8 @@ languageCode = "en-us"
|
||||||
title = "Michael's Blog"
|
title = "Michael's Blog"
|
||||||
enableGitInfo = true
|
enableGitInfo = true
|
||||||
|
|
||||||
|
ignoreFiles = ["logseq"]
|
||||||
|
|
||||||
[taxonomies]
|
[taxonomies]
|
||||||
tag = "tags"
|
tag = "tags"
|
||||||
language = "languages"
|
language = "languages"
|
||||||
|
|
54
content/posts/2022-10-27-dependent-types.md
Normal file
54
content/posts/2022-10-27-dependent-types.md
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
+++
|
||||||
|
title = "Dependent Types from First Principles"
|
||||||
|
slug = "dependent-types"
|
||||||
|
date = 2022-10-27
|
||||||
|
tags = ["type-theory"]
|
||||||
|
toc = true
|
||||||
|
math = true
|
||||||
|
draft = true
|
||||||
|
+++
|
||||||
|
|
||||||
|
It's frequently said that computers are just made of 1s and 0s. As programmers,
|
||||||
|
we induce structure into this sea of 1s and 0s to build a rich collection of
|
||||||
|
abstractions that can produce the entire software ecosystem as we know it. But
|
||||||
|
how does this work? Let's start from the beginning.
|
||||||
|
|
||||||
|
### Bits and Bytes
|
||||||
|
|
||||||
|
On the lowest level, your computer is actually a tiny network of many
|
||||||
|
components, but let's pretend for a second it's just a giant list of **bits**.
|
||||||
|
Something like this.
|
||||||
|
|
||||||
|
```
|
||||||
|
011101110110100001111001001000000110010001101001011001000010000001111001011011110111010100100000011001000110010101100011011011110110010001100101001000000111010001101000011010010111001100100000011011000110111101101100
|
||||||
|
```
|
||||||
|
|
||||||
|
This is often a mess, so we like to chunk these into groups of 8, called an
|
||||||
|
_octet_, and then represent it as a 2-digit base 16 number. For example, the
|
||||||
|
string above would look something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
77 68 79 20 64 69 64 20 79 6f 75 20 64 65 63 6f 64 65 20 74 68 69 73 20 6c 6f 6c
|
||||||
|
```
|
||||||
|
|
||||||
|
We've just turned our series of 1s and 0s into some numbers and letters. Great.
|
||||||
|
Now what? How do we get programs, images, and video from this? Well, we have to
|
||||||
|
induce some structure.
|
||||||
|
|
||||||
|
### Building Blocks
|
||||||
|
|
||||||
|
Suppose you had a pile of sugar and a pile of salt. They both look pretty
|
||||||
|
similar, but if you were to put them into the same pile, cooking would be a
|
||||||
|
disaster. You would not want to use salt where you wanted to use sugar, or vice
|
||||||
|
versa.
|
||||||
|
|
||||||
|
Same thing in computing. We have developed byte-level representations for
|
||||||
|
several basic kinds of data, but without distinction, it's hard to tell them
|
||||||
|
apart. So programmers developed **types**, ways of categorizing data so when
|
||||||
|
we're just reading a series of 0s and 1s, we would know how to interpret it.
|
||||||
|
|
||||||
|
|Raw|Interpreted as number|Interpreted as text|
|
||||||
|
|---|---|---|
|
||||||
|
|`68 65 6c 6c 6f`|448,378,203,247|`hello`|
|
||||||
|
|
||||||
|
So now we know how to
|
|
@ -0,0 +1,63 @@
|
||||||
|
+++
|
||||||
|
title = "Decentralized Identity, a Middle Ground"
|
||||||
|
date = 2022-10-30
|
||||||
|
|
||||||
|
logseq = true
|
||||||
|
+++
|
||||||
|
|
||||||
|
- With Twitter management changing, I'm starting to think about the small web again. The small web is a concept where you use the Internet to interact with people directly, rather than operating through the medium of megacorps. When we think about big monoliths like Twitter and Facebook, at the very heart of it is some kind of algorithm picking what it is we see. And with the power to control that gives us advertising and mass manipulation.
|
||||||
|
- For the rest of this blog post, I'll be talking about _microblogging_ specifically: short posts of several sentences, along with a few media attachments, of which Twitter is one of the largest monolithic implementations. But the things I talk about are also applicable to other applications, including long-form blogging (Medium), image sharing (Instagram, Snapchat), video sharing (YouTube), chat (Messenger)
|
||||||
|
- There's several projects out there that are already trying out other extremes. I'll cover two big types here:
|
||||||
|
- **Federation.** This style of application development is inspired by email. The idea is that you develop a common _protocol_ for apps living on different servers to talk to each other, so you can have people choose their own servers rather than trusting everything to megacorps like Google or Facebook. One notable example of this in the microblogging realm is Mastodon / ActivityPub.
|
||||||
|
- **Peer-to-peer.** This style of application development is rarer, but can be seen commonly in things like torrents. The idea is that _each_ client holds all application info, and interacts with everything else as if they were all clients. One notable example of this in the microblogging realm is Scuttlebutt.
|
||||||
|
- I'll go into more detail about these two styles later, but they both come with their advantages and drawbacks. However, I don't think any of the solutions that exist are sustainable for longer periods of time.
|
||||||
|
- ## Feature Evaluation
|
||||||
|
- One thing I've been doing recently when I think about software applications and system design is break things down into their **features**. This makes it a lot easier to compare applications or services to each other than a vague statement like "I've had a good/bad experience with this". So let's come up with some features of a good microblogging platform:
|
||||||
|
- Application design
|
||||||
|
- **Verifiability:** It should be easy to verify if I did indeed ever say something.
|
||||||
|
- **Freedom:** Within reason, I should not be limited in what I say or do on the platform.
|
||||||
|
- **Universality:** I should be able to communicate to anyone from anywhere (any device, any location).
|
||||||
|
- System design
|
||||||
|
- **Availability:** I want to be confident that the system will be around for many years.
|
||||||
|
- **Connectability:** I should be able to connect with people I don't already know easily.
|
||||||
|
- **Moderation:** I should be able to choose to not interact with a certain subset of users, and this process should not be painful.
|
||||||
|
- Scaling
|
||||||
|
- **User scaling:** Supporting more users should incur a relatively linear or sublinear cost, and should certainly not lead to resource consumption blowup.
|
||||||
|
- **Temporal scaling:** The system should support being run for an arbitrarily long amount of time.
|
||||||
|
- Development
|
||||||
|
- **Malleability:** How easy is it to introduce / roll out new versions and features? This may be important for updating cryptographic algorithms.
|
||||||
|
- **Version drift:** Is it possible to support users who are on different version of the service?
|
||||||
|
- Some features are certainly more important than others, and may have different importance to different people. But it gives me a base line to evaluate services, and lets me decide which features I consider to be critical.
|
||||||
|
- These are obviously not the only features, but I like to list them in this form because while some
|
||||||
|
alternative apps may tout certain features, it's useless if it falls short on something more important.
|
||||||
|
- ### Evaluation
|
||||||
|
- Now that we know what we're looking for, let's evaluate some existing services.
|
||||||
|
- **Mastodon**
|
||||||
|
- Satisfies:
|
||||||
|
- **Connectability:** It's easy to find other users based on their user ID, which looks like an email so it's easy to share.
|
||||||
|
- Doesn't satisfy:
|
||||||
|
- **Freedom:** While certain instances may be specialized (i.e hobby-focused), it's certainly not great when you are locked out of communicating with someone on another instance because the admins of your respective instances have beef with each other.
|
||||||
|
- **Availability:** For some reason or another, I've seen Mastodon admins give up on their instances. Running an instance is very costly in terms of money and time, so it's not surprising that if an instance owner decides it's simply no longer worth it, the users are simply hosed. While there are some options for migration like redirection, it's useless if the original server doesn't stay online.
|
||||||
|
- **Scuttlebutt**
|
||||||
|
- Satisfies:
|
||||||
|
- **Freedom:** This is the maximally free solution: your client is solely responsible for receiving and filtering all messages.
|
||||||
|
- Doesn't satisfy:
|
||||||
|
- **Connectability:** Connecting with someone must take place over an existing channel (i.e either meeting in meatspace or sharing a pub). If I don't have my Scuttlebutt client with me, then it's not possible to get updates.
|
||||||
|
- **Universality:** Since user identity is heavily tied to a single client, having multiple clients for a single user is not a well-supported workflow.
|
||||||
|
- The Matrix people have also developed [Cerulean], a playground for testing the idea of _relative reputation_, where instead of doing moderation of all users you can assign a web-of-trust-style reputation to people you follow. However, this may lead to further filter-bubbling, the implications of which I'm honestly not sure how to tackle.
|
||||||
|
|
||||||
|
[Cerulean]: https://matrix.org/blog/2020/12/18/introducing-cerulean#whats-with-the-decentralised-reputation-button
|
||||||
|
- ## Decentralized Identity
|
||||||
|
- My view for an ideal microblogging platform would be a federated server-client architecture, but where a user identity isn't tied to the server the same way a user is tied to their Mastodon instance. Essentially, you want your account to be promiscuous between several servers.
|
||||||
|
- This way, you gain all of the benefits of having a server-client architecture (easy to do multiple clients), while not relying on the server itself or its admins to stay around for a long time.
|
||||||
|
- The problem is, designing such a system securely is difficult. Ultimately, what I'm proposing is:
|
||||||
|
- A user identity model based on an asymmetric-key model. Users generate their own key locally and provide it to instances.
|
||||||
|
- Users should then have _client_ keys, which are independent of the user keys. These are signed by the user key to indicate that they belong to the same user.
|
||||||
|
- When a user wants to switch servers, they can begin requesting a checkout of their data from the server. The data can be signed by the server as well to provide an indicator that the client isn't trying to forge old history.
|
||||||
|
- One problem is if a server wants to deny a user from switching servers; they may try to keep the data hostage. One solution is just to scrape all publicly obtainable data, the other is to hope that this is socially discouraged by just having users avoid servers that engage in user-hostile actions.
|
||||||
|
- Users may also opt to replicate their identity entirely between two servers. This just means that this synchronization process is just happening incrementally or periodically rather than just at switch-time.
|
||||||
|
- This still has a number of open problems:
|
||||||
|
- **Key revocation.** Obviously, anything involving cryptographic keys requires a revocation protocol in the event that the keys are compromised. I'm not too sure of a good way of doing this that doesn't involve an infinitely growing append-only list of revocations on all of the people who have
|
||||||
|
- When I have some free time, I may take a crack at a proof-of-concept implementation of a system like this.
|
||||||
|
- ### Further applications
|
||||||
|
- Since this scheme only really targets the identity layer with (theoretically) asymptotically constant change required for other parts of the software, this should be able to be extended to things other than just microblogging. I'm not sure about the level of success this may have for things like sharing large data files such as video (maybe mix in something like IPFS?), but there is certainly room for exploration.
|
|
@ -25,7 +25,9 @@
|
||||||
- {{ .ReadingTime }} min read
|
- {{ .ReadingTime }} min read
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
<div class="post-container">
|
<div class="post-container
|
||||||
|
{{ if .Params.logseq }}logseq-post{{ end }}
|
||||||
|
">
|
||||||
{{ if .Params.toc }}
|
{{ if .Params.toc }}
|
||||||
<div class="toc-drawer">
|
<div class="toc-drawer">
|
||||||
<details>
|
<details>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
https://git.mzhang.io/michael/blog/src/branch/master/content/{{ .Page.Path }}
|
https://git.mzhang.io/michael/blog/src/branch/master/content/{{ .Page.File.Path }}
|
||||||
|
|
Loading…
Reference in a new issue