Nostr: Notes and Other Stuff Transmitted by Relays

--

Just like in 1984, our world of communications is often controlled by centralised authorities. This can, of course, be a good thing, as it can stop bad people from posting bad things. But, what happens if you have something that is important to be said, but have been banned from comunication playforms? What if Google or Microsoft decide that you are saying bad things about them? Could they kick you off their networks?

Say you had just published a Penetration Testing tutorial for your students on YouTube, and they thought you were a hacker. Could YouTube just ban you for life on their platform?

We are moving into a scary world of untrusted communications. Overall, it will be difficult in the future to tell what is real and what is fake. So, if Rishi Sunak declares, “We are now at war with the world!”, can you trust this or not? And, what happens if YouTube or LinkedIn decides that it doesn’t like what you say about them, and bans you from their platform?

The answer should be to create a digital world where every message can be checked for its validity, and carries a digital signature, and where there is no centralised control of messages.

To overcome these issues, Nostr brings a new censorship-resistant global “social” network, and where there is no trusted central service. It uses digital signing to verify messages, and where someone’s private key signs a message, and where their public key verifies it. In this case, Bob signs a message with his public key, and then Alice verifies the signature with his public key:

So what is Nostr?

Nostr was first defined in 2019, with [here]:

Nostr uses clients and relays, and where users run clients, and where anyone can be a relay. Users identify themselves with these public key, and every post to a relay is then signed. There is no communications between relays, and each relay only services its associated clients. A client then subscribes by posting their public key to the relay, and then receives updates in a chronological manner. With this, a user could be banned from a specific relay, but they can still post to other relays. Followers of a banned user, can then still follow them on another relay as their public key will not change. When a user is following someone, their recommendations for relays can then be added automatically to the user’s list of relays for querying. Someone who is leaving a relay can then publish a recommendation, so that their followers can follow them there. A user, too, can publish to one or more relays, and so the infrastructure is less easy to censor. A cost for publishing can also be integrated, and which can limit the spamming of a relay.

How does it work?

Unlike many other decentralised propotols it is fairly simple, and where Bob can publish notes on one of more relays. Those who subscribe to the associated relays can then read the notes. This is basically the protocol, and where it only defines the basic formatting of the notes:

Figure: https://github.com/nostr-protocol/nostr

Overall, anyone can create a relay, and define the access policy that they want. This is similar to a bulliten board approach, and where those who want to consume the messages would subscribe to the relay. Public key encryption is then used to validate the messages which appear on the relay, so that those who read them can check their authenticity.

Some sample code to create a key pair, and then sign a message is [here]:

package main

import (
"fmt"
"os"

"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip19"
)

func main() {

msg:="Hello world!"

argCount := len(os.Args[1:])
if (argCount>0) {msg= string(os.Args[1])}

sk := nostr.GeneratePrivateKey()
pk, _ := nostr.GetPublicKey(sk)
nostr_priv, _ := nip19.EncodePrivateKey(sk)
nostr_pub, _ := nip19.EncodePublicKey(pk)

fmt.Printf("Private key {%v}\n",sk)
fmt.Printf("Public key: {%v}\n", pk)
fmt.Printf("Private Nosstr encoded: {%v}\n",nostr_priv)
fmt.Printf("Public Nosstr encoded: {%v}\n",nostr_pub)
fmt.Printf("Message: {%s}\n",msg)


ev := nostr.Event{
PubKey: pk,
CreatedAt: nostr.Now(),
Kind: nostr.KindTextNote,
Tags: nil,
Content: msg,
}

fmt.Printf("\n\nEvent (Before signing): %v\n",ev)
ev.Sign(sk)

fmt.Printf("\nEvent (After signing): %v\n",ev)
}

And a sample run [here]:

Private key {5a9ffddb1cc3a53ef3d2fedec9249eec6d2b3790886853d9d39fe1ab6f4cebd3}
Public key: {0e0efc61c352519fd488377431aa22de84b435a4833c4188c2636edb313d052d}
Private Nosstr encoded: {nsec1t20lmkcucwjnau7jlm0vjfy7a3kjkdus3p598kwnnls6km6va0fsc3x60x}
Public Nosstr encoded: {npub1pc80ccwr2fgel4ygxa6rr23zm6ztgddysv7yrzxzvdhdkvfaq5kskqnxwz}
Message: {Testing 123}


Event (Before signing): {"kind":1,"pubkey":"0e0efc61c352519fd488377431aa22de84b435a4833c4188c2636edb313d052d",
"created_at":1714897532,"tags":null,"content":"Testing 123"}

Event (After signing): {"kind":1,"id":"db6250b4929e526c89cce027639a6f21e70a53332a74b1aaaaa832ebaa58b35d",
"pubkey":"0e0efc61c352519fd488377431aa22de84b435a4833c4188c2636edb313d052d",
"created_at":1714897532,"tags":[],"content":"Testing 123",
"sig":"de2998fee002fe085fdb9d8fc193f8645e0772b4c907fcc77caebae9ebdc0b7b584d8ceb4eddb28b2dd369471f5e77017d7e6a386a6d1b73b14d19fb56796d1f"}

We can see that the event after signing has signature, the public key and and ID. These will then verify the signer once it has been posted to a relay.

--

--

Prof Bill Buchanan OBE FRSE
ASecuritySite: When Bob Met Alice

Professor of Cryptography. Serial innovator. Believer in fairness, justice & freedom. Based in Edinburgh. Old World Breaker. New World Creator. Building trust.