Morphis FAQ, 2nd draft WIP



What is Morphis, and how does it work?
What is Dmail, and how does it work?
What interfaces does Morphis provide?
How do uploaders remove files from the network?
What happens when the network runs out of storage space?
How does Morphis scale with the number of nodes in the network?
What makes Morphis resistant to Sybil attacks?
Where are you getting all these http://localhost:4251/'s from?
Morphis doesn't work with Noscript!

What is Morphis, and how does it work?

Morphis is a Distributed Hash Table (similar to Bittorrent) over a custom SSH protocol that allows users to upload files to and download files from the network. It is a very fast, encrypted, uncensorable and decentralized datastore that is resistant to Sybil attacks. It uses Kademlia's routing algorithm (the XOR metric etc.) - the specification is much more useful than the previous link - but not it's network algorithm.

Every node on the network generates an RSA-4096 private/public keypair on creation, and the public key is hashed with SHA-512 to give the node's ID. Each node devotes some storage space to the network - 1gb by default, this can be changed by running morphis with python3 node.py --dssize X, where X is in megabytes.

The URL used to download files/pages is the static or updateable key created when uploading it. So, with http://localhost:4251/sp1nara3xhndtgswh7fznt414we4mi3y, sp1nara.. is the key. A static key is the root hash of the Merkle tree of all the (unencrypted) blocks that make up the file (explained below) - if the file changes, so does the key.
An updateable key is the public half of a private/public key pair generated on the fly for each upload (different from the node's RSA keypair) - the key doesn't depend on the data being uploaded, which means the data can be updated after being uploaded and still be accessed at the same address.

In either case, the whole file is broken into 32 kilobyte blocks if it's bigger than 32k. The hash of the hash of each block is the block ID. The blocks are stored on nodes that have node IDs closest to the block ID. Because any hash is unpredictable, blocks are stored randomly across the network. They are also stored on a minimum of 3 different nodes across the network (the uploading node doesn't count itself as one of the 3).
The encryption key for each block is just the hash of the block. The block is encrypted (again with AES-256), and the key thrown away. It is assumed that anything uploaded is unencrypted, because there is no way to conclusively prove that data has been encrypted. If nodes thought all uploads were already encrypted, unencrypted data could be passed to the network, which would be forced to store it. This unencrypted data could be illegal to possess. The only way to be sure that this can't happen is for storing nodes to assume it's all unecrypted, and encrypt the blocks themselves.

The static/updateable key is hashed, like the individual blocks, to give the file ID. This ID is searched for, the blocks relating to it are found, downloaded and decrypted, and the file is reassembled. Morphis itself actually only handles and stores the 32k blocks, the rest is done by a different file, multipart.py

Morphis has a feature called prefix key search. This means that, unlike the regular internet, you don't need to type a page or file's full address to access it, just a few characters (7 minimum). For the page above, http://localhost:4251/sp1nara is enough to access the page. The network will find the full key just as fast as if you'd typed the full thing in.

A seeding feature will soon be made, where your node will check the availablility of blocks it stores over time and ensure that they remain on the network. This feature will also allow you to essentially 'like' any link, file or webpage and then your node will contribute to storing that file, as well as maintain it's existence on the network.

Morphis not being completely a carbon copy of Kademlia, but only based off of it is important; if you read the specification there (it's not long), you will see this in a note under STORE:

As the transport may be UDP, the message needs to also contain at least the nodeID of the sender, and the reply [needs] the nodeID of the recipient.
Obviously, this is a massive anonymity failure, and it's what allows and requires the list of seeders and leechers to be visible for any given Bittorrent file. Morphis does this a bit differently, similar to how Tor works; If you read how Tor works, you'll see the way they route messages from Alice to Bob is by Alice picking the route through the network to Bob, and encrypting the route so that every intermediate node only knows who the next receipient is. Because Morphis is based off Kademlia, where every block is stored relates to the block itself, nodes don't need to route their request through the network; it's done automatically by the intermediate nodes. A route will look like requester -> node 1 -> node 2 -> storing node.
Every download request in Morphis consists of the block ID to be downloaded, and 512 bit ID of the request. It is sent to the storing node through a series of intermediate nodes. With Kademlia, for the request to be returned the storing node needs to know who requested it. In Morphis, all a node does is reply to whoever send it to them when it was being relayed to the storing node the first time: storing node -> node 2 -> node 1 -> requester - they find this out by comparing the request IDs. In this way, no node needs to know who made the original request. Not even the first node that receives the request can know or figure out that they received it from the requester; it looks identical either way. You could say that it's onion routing without the onions.
You can think of it like this: I want to ask your mother's boss' dog a question, so I ask you, you ask your mother, your mother asks her boss, and her boss asks his dog. His dog will tell him the answer, who tells your mother the answer, who tells you, and you tell me. Neither you, your mother, your mother's boss or your mother's boss' dog know how originally asked the question.
This is what makes Morphis different, and allows it to combine the speed and reliability of Kademlia-based DHTs with the anonymity of Tor.


What is dmail, and how does it work?

Dmail is Morphis' built-in email system, and is inherently spam proof, encrypted (with AES-256 at present) and pseudonymous, with authenticated senders.

Dmail is a bit like Bitcoin in that it also uses proof of work, although a sligtly different kind:


What interfaces does Morphis provide?

Morphis provides a few different interfaces:

  1. HTTP: The default, most used interface is HTTP; open localhost:4251 in a browser
  2. SSH: SSH can be connected to with ssh 127.0.0.1 -p 4250. ssh 127.0.0.1:4250 won't work, so don't try it.
  3. mcc.py: You can also run mcc.py to control a node


How do uploaders remove files from the network?

Currently you can only do this with updateable keys. To remove a file from the network, just go to the appropriate upload page, don't select a file, path or mime-type, and press "Upload". Your client will then upload the empty byte string to network, and any nodes that store the previous version will overwrite it with the now-empty new version. You might have to do this multiple times, because offline nodes obviously won't see your update.


What happens when the network runs out of storage space?

As of today, the oldest data stored by a node will be deleted once their storage space becomes full. Once this happens, nodes only accept new keys that are closer to itself, and throw out keys that are further away, increasing the accuracy of the network. In the future, once that distance becomes small enough ("enough" is based on the size of the network) they will overwrite data according to when it was last requested, how much it was requested, etc. The above seeding feature will ensure that certain data will never drop off the network even if it is rarely requested, as long as someone is seeding it; only the redundancy would decrease (possibly only the seeding node would store it) until it gets requested/popular again.


How does Morphis scale with the number of nodes in the network?

Morphis, like Kademlia, lets you control the routing table expansion. The routing table gets bigger with log(base (2^b)), and 3 to 5 are reasonable values for b. This enables O( log(base (2^b)) ) efficiency, so with the lower value of 3 for b, the scaling is log(base 8). That means, with 1000 nodes, the load would be 3.3, but only 10.9 with 7 billion nodes, one for each person.

By the time there are 7 billion nodes, the amount of memory and processing speed will have increased, so b can be raised to 5, giving a load of 6.54 with 7 billion nodes.


What makes Morphis resistant to Sybil attacks?

Morphis is not yet invulnerable to Sybil attacks, just resistant to them. Node IDs aren't RSA public keys, but the SHA-512 hash of the public key, which makes it much harder to forge a specific node ID. Morphis also tunnels stable connections with tit-for-tat fairness: a node uploads data to a small set of neighbouring peers which are providing it with the best download rates, discouraging freeriding (downloading without uploading) and promoting fairness (the ratio of the amount downloaded by a node to what it uploads).
Nodes, as normal behaviour, relay upload and download requests from other, close, nodes, as well as generating their own requests. The closeness of a node is determined by xor-ing their own node ID with the other node's ID. To prove whether a node is generating a request themself, or just relaying it, a malicious attacker must then create many nodes with IDs that are close to that of the target. This allows them to see if requests from the node were relayed to it, as they would likely be the one who would relay it to them.
As was said above, it is hard to forge specific node IDs - there are 2^512 different IDs. This greatly reduces the chances of nodes being deanonymised, and is why Morphis can be described as pseudonymous. Similar to the regular Internet, anonymity can be built on top of Morphis, like Tor and Freenet provide.

Using the horrific analogy from earlier at the end of the 1st question, one of the only ways you would know if I was the one who asked the original would be to surround me with loads of your friends so you would know if someone else had asked me the question first and I was just relaying it to you. The other way would be to follow the chain of communication and see that it stops with me - i.e. I don't relay the question or the answer to someone else.


Where are you getting all these http://localhost:4251/'s from?

You can access Morphis and the files on the network through localhost:port (the default is 4251, and set in maalstroom_server.py). The Maalstroom plugin converts localhost:port into http://localhost:4251/, so download that. It's only for Firefox at the moment though.

If you want to change the port SSH listens on, meanwhile, run morphis with python3 node.py --bind *:4250, and change the 4250 to any number beside 4251.



Morphis doesn't work with Noscript!

It doesn't, until you put in a few things to Noscript's options: Open Noscript's options, go to "Advanced", then XSS, and put "http://localhost:4251/" at the bottom of the text box. Then, go to "ABE", click on the "System" ruleset, and make it look like:

# Prevent Internet sites from requesting LAN resources.
Site LOCAL
Accept from LOCAL

Site http://localhost:4251/
Accept from http://localhost:4251/

Deny