HN user

cel

128 karma

https://celehner.com/

PGP: 0xB8FF71DA2A375F8F93FCBBDA4D2E80213413F006

SSB: @f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519

Posts4
Comments56
View on HN

Anyone know why they used UTF-16 for the message type, instead of UTF-8?

It is an artefact of the original implementation, which was not discovered until the protocol was already in wide use and being independently implemented [1].

Also, I'm skeptical that two peers can exchange keys without a third party, without being susceptible to man-in-the-middle attacks. But maybe the paper linked in the article proves that it's possible?

SSB uses the Secret Handshake (SHS) protocol in that paper (with some errata [2]). SHS is a authenticated key exchange (key agreement) protocol [3]. The two peers authenticate eachother to their respective public key, and establish a shared secret that is used to bulk-encrypt the rest of the session/connection. With SHS, the client (the peer that initiates the connection) must know the server's public key ahead of time. Both parties must know and previously agree on an additional network capability key (that is usually hard-coded to a specific value in the SSB implementations).

It should be immune to MitM if the party's private keys are kept secret. There are ephemeral keypairs involved, so if a later compromise occurs of the long-term (identity) private keys, that should not reveal previous/existing sessions. SHS has been verified using Tamarin [4].

I wonder if anyone's made an STM that runs on a readonly transaction log like this, kind of like CouchDB, RethinkDB or Firebase maybe?

I'm not familiar with STM as such, but I am familiar with CouchDB. There are various ways of mutable data structures on SSB. Typically messages are indexed, in general ways (e.g. message type, author, backlinks) and/or application-specific ways. Applications query the indexes to construct some result. Graph processing is often done to handle concurrent operations by different feeds (i.e. using CRDTs).

Here is a document describing threads, a common data structure on SSB: https://hackmd.io/GQ8aTw6STpuSFu6oH5Z63w

Could this be used to build a web of trust? Or is it meant to be more transient, like maybe people broadcast on throwaway identities? Could we drop PGP into this?

Yes, the main SSB network constitutes a web of trust. People do create throwaway identities though, just trying it out and then not returning. But some persist, and people develop and express relationships. Some people share other public keys for PGP, OMEMO, Briar, RetroShare, Dat/Hyper, etc. PGP-signed messages have been published occasionally. Creating a temporary identity is not recommended for broadcasting, because it will not have much reach: message distribution and visibility depends on the social graph.

Maybe this is more like an RSS feed than something realtime like WebRTC?

Yes. A SSB feed is identified by its public key, and contains an append-only list of messages. Each message is identified by its content hash. However, the RPC protocol used for SSB could be extended to support ephemeral content.

WebRTC DataChannels could be used for gossip connections. But there is still the problem of needing to exchange message to establish the WebRTC connection. Historically SSB has addressed P2P network architecture using Pubs [5], more recently with Rooms [6].

[1] https://news.ycombinator.com/item?id=29675263

[2] https://github.com/auditdrivencrypto/secret-handshake/issues...

[3] https://en.wikipedia.org/wiki/Authenticated_Key_Exchange

[4] https://github.com/keks/tamarin-shs

[5] https://ssbc.github.io/scuttlebutt-protocol-guide/#pubs

[6] https://ssb-ngi-pointer.github.io/rooms2/

It seems weird that you would write a formal, generalized protocol specification relying on the idiosyncratic implementation details of JavaScript, for such an important thing as cryptographic signatures, as the Scuttlebutt specification seems to do here.

The Protocol Guide was created after the initial implementation and its protocol were already in wide use, and the quirks were discovered while re-implementing it. More info about implementations here (Node.js, Go, Rust x2, and Python; additionally there are implementations of varying states in Java, C, Haskell, Erlang and probably others): https://dev.scuttlebutt.nz/#/?id=implementations

---

If making a new protocol using signatures over JSON objects, one might use this: JWS Clear Text JSON Signature Option (JWS/CT) https://datatracker.ietf.org/doc/html/draft-jordan-jws-ct JWS/CT uses JSON Web Signature (JWS) [RFC7515], JSON Canonicalizion Scheme (JCS) [RFC8785], and I-JSON [RFC7493] (subset of JSON for interoperability)

Or for signatures over JSON-LD objects / RDF datasets: https://w3c-ccg.github.io/ld-proofs/ https://json-ld.github.io/rdf-dataset-canonicalization/spec/

Great questions, csense.

It is preferable that users bring their own DIDs, rather than you assigning them DIDs as a service provider, to ensure user autonomy. However, you can create DIDs via websites as you are suggesting, using did:web [1].

DIDs are structured or namespaced by DID Methods: the part after "did:" is called the DID Method name, and each Method has its own specification and implementations. There is a registry of DID Methods [2], although it is not a requirement that DID methods be registered. There is a document comparing some DID methods using a Rubric: [3].

[...] instead of registering a separate account with my website, she can instead type "did:identity.dns.xyz:123456789abcdefghijk" into my website?

It can obviate account registration per website, yes.

For usability reasons it is often considered desirable that users not have to know about DIDs, type them or see them. The functionality could instead be handled by the user's software. There is a browser standard and polyfill in development which can be used for this: Credential Handler API [4].

Does my site's software then contact identity.dns.xyz to ask it something? Or is all the information my site needs to do its thing contained in the DID itself?

If you have "did:identity.dns.xyz:...", it would depend on what the "identity.dns.xyz" DID method is. If you don't know what the "identity.dns.xyz" DID method is, you could ask a DID resolver that you trust; but they might not know either. If instead you had "did:web:identity.dns.xyz:...", you would indeed contact `identity.dns.xyz` over HTTPS to request the respective DID document. If you instead have a "did:key:..." DID [5], you would indeed have all the information contained in the DID itself, as did:key encodes the public key. In other kinds of DID methods, you may need to contact a peer-to-peer network to resolve the DID.

Is "123456789abcdefghijk" the hash of some document that's returned to my website by the identity.dns.xyz server?

It depends on the DID method. If you are using did:web, which is based on HTTPS as mentioned, there is no hash, although this could be handled using hashlinks [6], which is mentioned in the did:web specification as a TODO. In other DID methods, the method-specific-id (the "123456789abcdefghijk" part) is a hash which might refer to some static data or initialization state.

Or is Alice running some identity management browser extension that knows to present a document whose hash is "123456789abcdefghijk" to my website?

Possibly, depending on the DID method and how it is implemented. But DIDs are generally expected to be public, globally resolvable, and highly available.

[...] is "123456789abcdefghijk" the hash of a public key which signs something

Could be, again depending on the DID method. Some DID methods are based on decentralized ledger technologies where the method-specific-id represents an account id derived from public key hash, e.g. did:ethr [7] and did:tz [8].

[...] {returned by the identity.dns.xyz server | presented by Alice's software}?

Yes, if you are authenticating the user with a DID, generally you would ask them to sign a challenge using authentication key material from their DID document. The DID document is what the DID resolves to, and it includes public keys. In the case of did:key, the DID document contains a single key as encoded in the DID. In the case of a DID method based on a public key hash, the public key must be provided or looked up somehow, or the signing algorithm must support public key recovery [9].

Or is "123456789abcdefghijk" just a string your webserver happened to generate to identify Alice uniquely that came from /dev/urandom or a PRIMARY KEY column in your database that has no cryptographic meaning?

The DID method determines the structure and meaning of the method-specific-id (the "123456789abcdefghijk" part). If you are using did:web, the string is not cryptographic but corresponds to a HTTPS URL.

If Alice's DID document is cryptographically linked to her DID, how does she update it?

She performs a DID document update operation [10]. If the DID method is based on a decentralized ledger technology (e.g. btcr [11], ethr, tz), she might publish a transaction to the corresponding network or make a call on a "smart contract". in the case of a did:key, the DID document cannot be updated.

If the DID is the hash of the document, does that mean Alice gets a new DID whenever she edits her profile on dns.xyz?

If the DID method is static (basing the DID on the document hash entirely), it would probably have to be a new DID, but if it is only an initial document hash, the DID method could provide for verifying and applying updates somehow. There are also some properties for indicating equivalence between DIDs which might be useful [12].

A DID document could also be updated while still using hashes for integrity protection and referencing if the DID method uses the hash as the DID document version ID. A DID can be resolved at a given version ID using the versionId parameter [13].

For privacy, generally DID documents should not include personal data [14]. Edits to a profile on would then only affect DID documents if they are updating keypairs, or indicating relationships with other DIDs (e.g. using alsoKnownAs), or updating service endpoints, etc.

For decentralization and user autonomy, users should be able to update their DID documents with their software directly, rather than having a website in control of their DID and having to ask the website to update it. In the web context that may mean a browser extension or key management API. But there are institutional use cases where the website is expected to have control.

How does my website know that the user presenting Alice's DID document is Alice sending her most up-to-date DID document, rather than Eve sending an outdated DID document with the compromised Ethereum address that once belonged to Alice [...]

Often DIDs are resolved publicly or by contacting a network rather than via asking the user (did:peer [15] is a different case). But the concern still applies. Updating a DID document to remove a compromised key is called revocation [16]. The DID method should have some protocol for how updates are performed, which may include how they are ordered, such as by being witnessed or confirmed by some entity or network. The question of the valid state of a DID document should be abstracted by your DID resolver [17].

Is a DID like a generalized Bitcoin address, a generalized IPNS name, a generalized email address, or something else entirely?

More like a generalized Bitcoin address I think, although there are comparisons to be made with the others. Another idea: generalized PGP keys. It is primarily about identity, rather than about communication, storage or payments.

For more info I recommend checking out the Decentralized Identity Foundation (DIF)'s FAQ: "What is a DID?" [18].

[1] https://w3c-ccg.github.io/did-method-web/

[2] https://www.w3.org/TR/did-spec-registries/

[3] https://w3c.github.io/did-rubric/

[4] https://w3c-ccg.github.io/credential-handler-api/

[5] https://w3c-ccg.github.io/did-method-key/

[6] https://datatracker.ietf.org/doc/html/draft-sporny-hashlink

[7] https://github.com/decentralized-identity/ethr-did-resolver/...

[8] https://did-tezos.spruceid.com/

[9] https://crypto.stackexchange.com/questions/18105/how-does-re...

[10] https://www.w3.org/TR/did-core/#method-operations

[11] https://w3c-ccg.github.io/didm-btcr/

[12] https://www.w3.org/TR/did-core/#equivalence-properties

[13] https://www.w3.org/TR/did-core/#did-parameters

[14] https://www.w3.org/TR/did-core/#keep-personal-data-private

[15] https://identity.foundation/peer-did-method-spec/

[16] https://www.w3.org/TR/did-core/#verification-method-revocati...

[17] https://www.w3.org/TR/did-core/#dfn-did-resolvers

[18] https://identity.foundation/faq/#what-is-a-did

GitHub was down 9 years ago

Marak It sounds like you are working with private repos. With git-ssb currently a repo is either public or private. Private repos are encrypted to a fixed set of recipients so only those keyholders can access it. Public repos are unencrypted.

The quoted 150 MB is for all messages in one's network. On my local node there are 91773 messages, going back roughly a year and a half, taking up 147 MB - of which about 72 MB is the actual messages, and the rest are indexes. gzipped, the 72 MB of messages goes down to 29 MB.

It can take a while to index the database.

In places lacking internet bandwidth, people could run pubs in hackerspaces, schools, offices, homes, Actual Pubs, etc. A pub in a place that people frequent would gossip messages for the people, so they would not all need to connect to the internet all the time. Even the pub itself doesn't have to connect to the internet for it to be useful, as it would still help messages spread when people connect to it. As long as someone in the network connects to the Internet at least once in a while, people will be able to communicate with the broader network. With this architecture we can make more efficient cooperative use of network bandwidth.

What problem are they solving? That facebook and twitter can delete and alter your messages?

that using those services for one's communications places too much power in the hands of centralized authority. (I speak just for myself here).

https://www.scuttlebutt.nz/stories/design-challenge-avoid-ce...

Meanwhile I'm in search of a long-range, wireless communication system that can function like a network without the need of an ISP. Anyone know anything about this?

On SSB we have discussed doing gossip connections over long-range wireless connections: https://viewer.scuttlebot.io/%2547H0BQQHAXvvqf8K3ngdeMtAHQdP...

Of course if you are looking for a network in a more traditional sense, something lower-level may be more appropriate.

The distinction of binary and non-binary posts on Usenet is paralleled by the separation of messages and blobs on Scuttlebutt. As staltz [explained](https://news.ycombinator.com/item?id=14051181), we can garbage collect ("expire") blobs, but not message logs (although a client could do so with the current APIs, it would have security/trust and UI implications, and I'm not aware of any clients doing so).

We are also basically betting on the size of our message logs to generally grow slower than our individual storage capacities, and it is interesting to know that that worked for Usenet too. For blobs, we will likely develop some garbage collection or expiring approaches. Since the network is radically decentralized, each participant can choose their own retention policy. You can, in fact, delete all your blobs (`rm -rf ~/.ssb/blobs`) and assuming some peers have replicated them, your client will just fetch them again as you need them.

So, if I post a GB worth of diary entries, who ends up caching it by default? Just my followers? People I follow? Pubs I connect to?

your followers, their followers, and their followers (assuming everyone is using the default replication settings). These may include pubs or people you follow. If you are able to connect to a pub then most likely it is willing to replicate your feed.

Each message includes a signature by its author of its content, so it can't be falsified (unless the author's key is compromised)

The equivalent to a bootstrap node is the pub to which you used an invite code to connect to when joining the network (unless you connect to the network in a different way, like by being followed by someone else on your LAN). When you use an invite code, you publish a message with the pub's address on your feed. When peers replicate your feed, they see those messages, and thereby find out about new pubs to connect to.

With SSB, you could make a UI that renders the content in a different way, such as a HN-style thing, and use it on the existing network alongside people using other clients.

The social aspect is important though because in this architecture what you see is determined by who you follow (and who they follow, etc.)

For me, just a master branch. Commit before/after destructive or cross-cutting changes, and "once in a while" in the course of adding regular activity. Also I use a script to mount a remote on an encrypted file system and push to it, for backup.

Here's a good one: http://www.dgp.toronto.edu/~mjmcguff/research/#mcguffin_info...

It combines a tree of decendents from one person with a tree of ancestors of another person, to make a "dual-tree" with two foci. It preserves the property of people of the same generating being on the same level.

For instance a couple with three kids, each of them marries someone, how do we represent the parents of who they marry without crossing lines?

The dual-tree approach wouldn't be able to show all of this at once, but with some affordances for navigating the tree (see the video) and indicators for where there are more nodes not shown, it should be reasonable to follow the relationships.

Also here's another interesting approach, using a radial tree with time information. I found this while trying to find the other paper: http://vis.berkeley.edu/courses/cs294-10-sp10/wiki/images/f/...

We didn't do the full procedure, just a subset of the questions. We were not forming intimate relationships, just developing a sense of closeness in a short amount of time and learning about what that involves (e.g. reciprocal personal self-disclosure). So I don't think it was harmful or unethical.

Cursors 12 years ago

Awesome app. It reminds me of a thing I made, http://www.theinfinitemaze.com/

One thing I did on that site which could be useful here: aid the mouse movement with a A* search with limited depth, so that the game cursor moves toward the actual cursor a little more instead of blocking when there is a wall in the way.

Yes, the bash script could be made more portable. Also there are some GNU-specific sed features used, but I'm sure that could be changed to be more portable as well. Python or openssl is used for some base64 encoding.

I like using shell scripts for projects like this because of the power of piping commands/functions and doing line-based processing with e.g. sed.