From dee68043d18980f079d99658f5ae351c0260706a Mon Sep 17 00:00:00 2001 From: ycc Date: Tue, 1 Mar 2022 10:37:11 +0100 Subject: [PATCH] Curve25519 --- asymcrypt.go | 2 +- doc/protocol.tex | 28 +++++++++++--- endtoend_test.go | 4 +- go.mod | 2 +- go.sum | 11 ++---- https.go | 37 ++++++------------- invitation.json | 1 + invitation.png | Bin 0 -> 530 bytes network.go | 6 +-- peer.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 140 insertions(+), 45 deletions(-) create mode 100644 invitation.json create mode 100644 invitation.png diff --git a/asymcrypt.go b/asymcrypt.go index 41556b9..0728f6e 100644 --- a/asymcrypt.go +++ b/asymcrypt.go @@ -19,7 +19,7 @@ type KeysArray []KeyPair func NewKeyPair() KeyPair { var kp KeyPair - keys, err := crypto.GenerateKey("name", "mail", "rsa", 4096) + keys, err := crypto.GenerateKey("name", "mail", "x25519", 0) if err != nil { log.Error().Msg("Key generation failed") } diff --git a/doc/protocol.tex b/doc/protocol.tex index 1a1c67b..deef7fa 100644 --- a/doc/protocol.tex +++ b/doc/protocol.tex @@ -4,16 +4,25 @@ \title{ \textffm{Meow} messaging protocol} \author{Author - \texttt{author@address.net}} + \texttt{meow@redroom.link}} \date{\today} \maketitle \begin{abstract} -The \textffm{Meow} protocol is a privacy driven instant messaging protocol. + + + The \textffm{Meow} protocol is a privacy driven instant messaging protocol. That protocol might be used for creating secure and distributed chat services or allowing machine to machine communication. This document describes the services provided by the protocol, the messaging structures and the transport protocols that might be used. +\begin{quote} + \centering + \emph{"Nous ne vivrons pas d'utopie collective, nous arrivons trop tard, le grand marché est déjà là. +Nous devons élaborer des stratégies de survie et de contamination, par la prolifération d'utopies privées, cryptées, qui se substitueront à l'ancien ordre social. +Tout ce que je sais, c'est que nous vivons dans un monde dont on ne s'évade pas"}\\ +\footnotesize{Maurice G. Dantec for NOII (1997)} +\end{quote} \end{abstract} @@ -60,23 +69,21 @@ In return your contact will provide the exact same data, encrypted with your pub \subsection{Contacts forwarding} Using the \textffm{Meow} protocol a user won't be able to forward your contact information without your consent. -Each user knows you as a different identity, thus forwarding a known identity to another user is meaningless, any message to that identity signed by another user would be discarded. +Each user knows you as a different identity, thus forwarding a known identity to another user is meaningless. Any message to that identity signed by another user thna you would be discarded. \subsection{Group conversation} A very basic group messaging service is available. It allows to exchange group information between users. After that, a message to a group will send a copy of the message to each member. - \subsection{Emergency broadcast} -The +A local (server based) emergency broadcast service will be provided. It will provide the ability to send/receive broadcast messages to all users connected to the current server. \subsection{Public networks shortage resilience} \textffm{Meow} may run without Internet connection, either on an isolated wifi access point, either on a meshed network of wifi routers or even via serial IOT transport layers (LoRa,...) - \subsection{User directory service} This service allows to restore a lost functionality of Internet historic chat services (like ICQ). You could simply set a "Free for chat" status that allowed other people to contact you, either randomly or based on a short description that you might provide. @@ -98,6 +105,8 @@ Let's call that one the User Key Pair (Ukp) \subsection{Contact identity} Each of your contacts will know you as a different identity, we'll call that one the Contact Key Pair (Ckp) +That contact Key Pair will not change once it's agreed between the two peerr : An initial key will be exchanged as part of the peer invitation process. +As other people myth have seen your key This means that : \begin{itemize} \item none of your contacts will be able to forward your id to another person without your consent @@ -176,7 +185,10 @@ TODO \section{Server Features} \subsection{Server catalog} +Each server will cache a list of all the servers that it is aware of. + \subsection{Antispam} + \subsection{Self defense} @@ -188,6 +200,10 @@ TODO \section{Very secure devices} You don't trust your phone ? +\section{Roadmap} +\subsection{Nations} +Beyond the scope of user directories, we plan to implement the concept of virtual Nations. +Today still, most people don't really choose the nation they live in. \end{document} \ No newline at end of file diff --git a/endtoend_test.go b/endtoend_test.go index 328dee5..2e0f9e3 100644 --- a/endtoend_test.go +++ b/endtoend_test.go @@ -31,7 +31,7 @@ func TestEndToEnd(t *testing.T) { a, _ := json.Marshal(invitation) fmt.Println(string(a)) // TODO : Convert invitation to QR Code - + invitation.WritePng("invitation.png") // // Simulate peer invitation response : generate the friend's keypair fmt.Println("Simulating first friend answer...") @@ -64,6 +64,8 @@ func TestEndToEnd(t *testing.T) { ioutil.WriteFile("id.json", a, 0644) fmt.Println(string(a)) } + // go me.CheckMessages() + //myFirstFriend.SetComMethod() //msg := myFirstFriend.SendText() diff --git a/go.mod b/go.mod index 72497a1..f07383c 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( github.com/ProtonMail/gopenpgp/v2 v2.2.4 github.com/go-resty/resty/v2 v2.6.0 github.com/google/uuid v1.3.0 + github.com/makiuchi-d/gozxing v0.1.1 github.com/rs/zerolog v1.25.0 github.com/stretchr/testify v1.4.0 - github.com/tidwall/gjson v1.10.2 google.golang.org/protobuf v1.27.1 ) diff --git a/go.sum b/go.sum index fac4706..a2a9892 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/makiuchi-d/gozxing v0.1.1 h1:xxqijhoedi+/lZlhINteGbywIrewVdVv2wl9r5O9S1I= +github.com/makiuchi-d/gozxing v0.1.1/go.mod h1:eRIHbOjX7QWxLIDJoQuMLhuXg9LAuw6znsUtRkNw9DU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -33,12 +35,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= -github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -72,8 +68,9 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/https.go b/https.go index 2160fd7..f9222a1 100644 --- a/https.go +++ b/https.go @@ -2,48 +2,35 @@ package meowlib import ( "crypto/tls" - "fmt" - - "github.com/tidwall/gjson" "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" ) -var Address string - -func Configure(url string) { - Address = url +type Https struct { + url string } -func Send(msg []byte) (string, error) { +func (https *Https) Send(msg []byte) ([]byte, error) { client := resty.New().SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) resp, err := client.R(). SetHeader("Content-Type", "application/json"). SetBody(msg). - Post(Address + "/message/add/") + Post(https.url + "/message/add/") if err != nil { log.Error().Msg(err.Error()) } - serverUuid := gjson.Get(resp.String(), "serveruuid").String() - return serverUuid, err + return resp.Body(), err } -func Receive(key string) []byte { - client := resty.New().SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) - - resp, err := client.R(). - SetHeader("Content-Type", "application/json"). - Get(Address + "/message/" + key) - fmt.Println(" StatusCode :", resp.StatusCode()) - fmt.Println(" Cookies :", resp.Cookies()) - fmt.Println(" Error :", err) - msg := resp.Body() - return msg -} - -func Start(callback *func() []InternalMessage) { +func (https *Https) Start(callback *func() []InternalMessage) { + for { + + } +} + +func (https *Https) Stop() { for { } diff --git a/invitation.json b/invitation.json new file mode 100644 index 0000000..30b737c --- /dev/null +++ b/invitation.json @@ -0,0 +1 @@ +{"name":"Bender","contact_public_key":"LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tClZlcnNpb246IEdvcGVuUEdQIDIuMi40CkNvbW1lbnQ6IGh0dHBzOi8vZ29wZW5wZ3Aub3JnCgp4c0ZOQkdJQ2R2VUJFQURORlRBSkhvOHNWWm0zMG9DRWhDM2VIL0dXKzhlZFdRZHEzNXd2RmtaV1lPRjNrTU5pClBGazhQVDhHbDNVSmpqWDNvYnRrSjh6eGpQY2xIdnlDYUk5VFJpUEc2U3J5dmdlYUIyZVRnRktnVFNjWmhtdGkKZWVKM0N0Q1hkQ29wSEtpd094V1BEVlhKL2xEQ3RiMkk4MnRTLzR0WVNwRGUxTFNlU0Z5R09tTjRlRVZKSktySwp0dEk1V0lLMGJBSzVYUm9CZC9HdHIvYmVtbXNiYnhJTmZhMlkwckZnRjdPaGZFcW11L1BZMGdOdnFnSUJWQThCCkxLMFRoMHVlVGQ0eHNKSWljczVTVHBUSitsdEViV1JnL216b3ZPQ04rM3g2d3RWanVTeENqUzYzQUhYRnYxVGYKMWtwMWhVblJRb2tmWnU2RGxGTUNNQW9pa3NKcVQ4OHN2Lys1b3hBSlNBZFo3MTJiSGt0NjU0WTB1Sk5LOVI0dgprbk5veGNEajZCMU8rWlROcis1cWhkeDlGTHNsdlZwVU5ETnY4M0lwZTlCVHZiRjFhcEJTd1RZL2VzVzNVakhLCjI0RFpjRktFcnVRa0c4ZXk0bDNnUU5WNmMzUDF1SXNFaWlCeEM4N0I1MW9VbWxlUlk2RWhOTjdncUZNWlU2MUMKTUhkNEtQdEtod040NWo3blBQMmlQSWFYc0lvMlN2OUh4SWZvSTRZYlFvVHpWVkprY1N4bVo0dkdCMnEzalNwQgpUK2pEUWNSNHZaTFJvK1BPNHBsM0lsdkZrZFBXdTBYU0tFMkpLdXN0TXJ4UFJHUGJPQzdFYWw0bG9tRVBNZHppCktZa1dqV3lYSzdYUVVnb2k2SVlnSGRkeFZOOTlMdm0vcVJ6RW1SY2tRd2NSNjhvVDRVRWJ4M2UzcndBUkFRQUIKelF0dVlXMWxJRHh0WVdsc1BzTEJpZ1FUQVFnQVBnVUNZZ0oyOVFtUVhOMjlqVVRmZlNVV29RVEdTTUx0MnNydwo3cEdHbVNSYzNiMk5STjk5SlFJYkF3SWVBUUlaQVFNTENRY0NGUWdERmdBQ0FpSUJBQUJMMXhBQXJEVFpZYjNtCmxiN0tCdGd2MzE0S0hZdHI4dzByREkvUUR1T0piNk1zUjZOeFk0UnovOHFuWUoxN0JzS3FIaVN5amMvSWNqUGsKSlp4WmhlQ0FZT2U1YVRPRUpYaVFlRUdKVnRIT2hrQUJJNEdrRnY2M2hWMDU4ZWF3akd1akJNV1ViRVRSQlMydQorOVJTTWh5aVQ0dVhnamhWQkFCRVl3VUxKalI2RS81Rk9zQytkUUl4TW1DNk5JampQVlZxOTlScTlvRDQ0a1VvCm8vbG8xQnVueFVsaXd5QndrQkZkYVluNzhDYklxQTZaZFl5RTBudFRtdFdXcXZYSkpKblVuZjJhZEI0M1czNmoKZDlPVVl6Ui9FdG9rUE01a3dmc2t3RWdQRzZEelpnVDdQN2dOME9MSzRTaUUyOU40M1UxemtxcWdYMkFpUkNFNgo3UlpneEVUaGo0bTBaWkVrbnRENHJIK0d1UjdrZVZhc3NyQ2I1ZVBuL2NXWnBObmNsNkxMTzV3RjVzQmlLOXZkCjN2Z2Y4clAvTjdoYWR4OTN6R0duQUZBYXh2YndTa3pUWVRhVnZMUjIwb1ZJejlIaFExSEZBbXRZdEdGaXUwSzAKSnJjakN2SDVLVHZMZ2VkNTFleUF3QmFuMnBUc0FuNmgzS2dQU1c4SFpDQkZ3bjlST1ZKOTZZVi9lZmhuZnQ1Ywo4ZUYva2pObEZYeVZKK0VBaTVTcVN6Vy9ucmtEb2pnMHRQNjBWbHM4TGF3SW5yNE90VUpBQUc2Z0FiaXJQWVB5CkdlR1dQcmVmMU5PY1VpamQ1OW90Q0lsMHZGY1d6ZHhJUVQ1VG9MeDNTYnlMNTNsOUJ1eVhyYTZidzBINUdtKzQKK0h6dWx2NklYV2RlVWhUWThlTUNhQW1HSVppaGM0anRmenJPd1UwRVlnSjI5UUVRQU5WdFFTWjN6WEJlVnZlOQorUndoVnVxb3BBcEVBTzZRdEFlWEx0NzdQS05GUmJJbUpFOEh5enZHRENhL2EvOXBRTm9YQTZXVXhlZXp2MlR1CmdZS1pkcWpqODFZU2lOZXFVa2g2TVFaZUk2TGdtSUh5LzVkdUFodmFORmc5Y1YvYnlnd0FyNjFnMGsvRnlObE4KNzQxVlRCUUN1bWpuYlhzQjFhWTM2ZmRFQ1JBMjVDcXY0OEc4NFBpdGdicHh3cCtyUG8zK3dKNnBJTjdUellDZwp5TytHN215Ni9nTWczVkFJUjhTQUdVRlNJVHk4RmwzNnZsOUtoMTQvMXo4ZWRaNmgwb0wybHpaellqT25yRmc2Cnppa09Kdm9hVFYzYnJ3NktQTndTOGRhNmdoeE5NS1h2SVlTK2EwTlpYVWNUbThNK3I3cmxyTS9LYXhBNDJtdVEKczVuUExIdWlDV3ViYUpaaCtUOTFTMTRwQWJHNnFvcmZyWUFwK1VDUmNpVHBOVGRIckxuSEdJNkc1UlVBNTlmawpvNHd0Q2NiclZVZTZocmZDTmlSZFhLYW5EM2JMSnhicGtOTkYzakExOHdFdVltajNDVC9TaHQ2enlXaUg5YTV6CmZ5aTYzdUZQRVpieUVBUkoya3JjVGcrT2pFQmlVYjAwODVIdDl6RlhiNHlLSnVVaWlOSUt5TkZXWDVnK05MQTcKN29oRnFiY0xiWGJDQVRwRU1KUmVidzBCKzRGdzAzbjVhUFFDdGwzaUxMMlo2YnduZm5KUUp3UjB2VHUrMmJrSgpMTHFsbFNNTFNlZXlZY2pwbGdBRW9MUitseGpCT0xaTVMwbUZDNUNnQmNFMnN0T3E1cUFLNDFCdVpta0daclhmClVzNDl6V3ZlNm1JQWdXem5BWTBwOHROQ1FTemhBQkVCQUFIQ3dYWUVHQUVJQUNvRkFtSUNkdlVKa0Z6ZHZZMUUKMzMwbEZxRUV4a2pDN2RySzhPNlJocGtrWE4yOWpVVGZmU1VDR3d3QUFPYjNFQUNoM1U5b3VtTGZ5bkcrbk44NApOT1crT3A0UXJoT0Yzc1JRRXpLUmlVM1pXaUlyOEM4OFM0aFNrdGduMTFPdFlpUVVCWjlOZnZreU1zSEorUmpBCnlXSnczQTlJdUl4TFVURSs2OWpVTkhKb1Z0TE5ZQ3k3ZVBQejdVTDBlTllPRDg5cDlSdmowT2V0cDllQnpGUjQKMHB1QzJaUTgxbURMUmFUZkVIM1NjYXVUZXV5emhOMHJPR2tOK3NSWWZUd2Fsc1RjOXBFN1U1cE4zVjB1SGRDagpGQkhhcjAweHljaW9qV1VXVk9ZUGl5RUxjMit1VjJFL3NEOFZQWG80YnM5dFljWElCZnRPS0NURVI3dDFRclJhCjhuZzU0bGVya01JSHhYOSt0M1hnL2dBSkhVZW1XU0pzZW15QzdKM0ZtMzEzTXdGd0l0WkJkZmVjbXM3bGdmSHYKVEhYWTFwb2tlajZHN1JoenZ6N0t3eEE5cWttdTlFcDRMQUx6dmo3V1pXekZid3Z1MlNCZGtXeGxDbFVtZkRnYQpOQ1ozN1VsVzNlWUNMU1JWbkl3bGh0ck5iUUtQWURsZGRMVHhpT0d6VVZMZ1dMQ1MzMndZMTIrNjRtbHNwbkZiCjBCSlp5Lzl2SktHUkFIRjUvYkJEdGFRak80dHFmRjJMc1d5aFVrcnQ1ZkllTmJoZFlzWDhucXhIbWY3VGMxT2kKbHlYNDlnUXpZWmhhKzNLKytCWHp0ZzFyTmtyLytCY0x0UjRZY3lPRHRod2k0bGt2RWZXanF4anMzSFl3SVROSQpKaEFGeXRzc2pQZ2xRdTRNaWpUcDFBc3V0MmY2Z2Y4UE0wS1JuWTlsZ2NBVG1mZ0I3ckxBVXA3SnpxQnA3K0pqCkVNMzZ6c1BGdlJRWWJ0SGdmWUxsTjNGRWhRPT0KPUt2U1EKLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQ==","encryption_public_key":"LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tClZlcnNpb246IEdvcGVuUEdQIDIuMi40CkNvbW1lbnQ6IGh0dHBzOi8vZ29wZW5wZ3Aub3JnCgp4c0ZOQkdJQ2R2c0JFQUNxdkF3SXEwNGZ0d05LeGhsRitoTkQxaE81cFhaM3dBVXpNMmVPUmZyc0l0bHRBa0RSCnErcmt0K3FtK0NteHl1K25JYjlvMzNoMEhlNklvSGMzR2k1NXpPNE4zVkVPMmpTUFlqOEt3ZXpiSHphTnZUR20KaHIrQmtnVys1ZlNTa0FSR3RFTG43bUx0VDk4ekNnWk1wYWhOOEY5WnExdTR1YjZzd3J4RTY2WVJqWjN4SUE1cwp6b1dwZEpvYlVxVXFtMURVSkVPVTk2QWhkT0JGaURONDk1UnR1MDduYWR3eEY3dkk0dVpFRW95WUowL1h1eGRwCnpWQjB5R2NYT2poTDZISXBjU0xXd3VYUjh5THJMRnR3aEt3Yy9Sa2toOTB5Q0MxcnpUN1hQYXBrMmdvaGV4QkwKV2dUV1hWUUVBYm0xNzlTQk1lZzhTN0dlZk5nMk42L0QzOTV0NlJENXZMblFlcDV1M3AyczMrNmFmbTlCUDlFMwpQUGhZU0VOTmhRUkpRc2pGUWp0VTE4SllyN0EzZU82MWgwcG51T1FxZEtNOWtUbkxBN1Q3eTlabysrblBJRUJ2Cm9lUE9PT205UlBUcHFYZnBaY2lqaXRqYmhobko2RitxMlkwblJlUDhaMzNXdU9LS3RHWnV4MWFUU0JTaWt6dHgKVWQ5ZU9Ldm9xTVVLTmQzNmpRbEJiUjZCbG40Um5vNkJVTXM1SUJ6MlVKd3BQaGs2N0RvNi82MUUybEVQM2U0Sgo4Znh1UFBaNXZFeWFWUzhUTjZxOVlEQkl0ZEh1WW5OVjQvWTlCZW5QNFd6Y0ZOTWVoREtoM1lldzFxZW5vMUI2CjBRUXdBck9lQ0NleEhQZVVJQjZGQlBFUkc5bmhMYktFVTVTV1RYS0o0Q001aDBKZHgzMnhjMlRjWVFBUkFRQUIKelF0dVlXMWxJRHh0WVdsc1BzTEJpZ1FUQVFnQVBnVUNZZ0oyK3dtUWxtdjkzV1hNTk9BV29RU1RUQU5qNGtrTgpJRjBTSjVpV2EvM2RaY3cwNEFJYkF3SWVBUUlaQVFNTENRY0NGUWdERmdBQ0FpSUJBQUFsYkEvK1BtWUhmTVN2Ckg2cjRjQW5YSFozQ2k3Sm04Q3NSa2ZTQUU1ZnFPdytHdHlGQ2RBZ3hTRWVrTWZvbmhXSWhqY0N4V1REWVhUNHAKNmdGZDFvYzJRN0k1d1ExSlpKY1FEZDFEdEVDeXZzZnRSWnBkc0VUQ1hzbktJVERUUmsyZzV4OGJxMHRNMW5WbApCdmhpZFVRMUVOWDhiM3diQTErQnRhZURIVS9CYldBZmxCQlpwdFNXVk9HSzdHVm4veTV2OFRBanNFcmhlVjBHCjFxbDFLTW1yMVZiSWdIWFg2a3JmTkxCVENVZDdhUzNlaWtwVEM0OVdQeTBJcDl2b0pDZVE0bTRpbGlKcHdUSGsKMllPSHQ2bUJXaUt6Ulk4V2N4MzNzYzE4eUJlM1FLWGNrWFJnb1BDbkNwR1BEZmlnM0kzOVl2d29UYUJ6SzlpUQprOWREWFNHaW5hdjc3QUFBbEo1TUljRktZRVgxNnBQa2cwV2N1QWNnVGUrVUtLemV1YXFpZnVmZWFLa1l6N2VDCjB3WUlqREZHSUFGb0JncWpaTVc3MG1mb1ZnYU1OdEFxM2xEOTAyUFg2a1hTRk5pMG5zbWlrRTJYc2VyWEpOR3cKWmxuekQySE1QZ2xRdnkweDZaKyticDh0L2xva0p4S1dPSUxQMGMrWGZVNndzRU9vdkk0U1hHbHRRWWhnbnRtVgpBRmVYd3NuNzF5SzdOOE9CM3VrcjFGc3pxeHk5M0I0YTRMNnZ0aFkxbDJOL3NjbDRjOWJHL2tIeHphT1AxWXZYCjIzSUdWVEpRZVhrbTRlazdkZTd2aWhNeThiMVpnWDJTVzNGNGE5RzVSdThaMmw2OHgwL3ROU3Q2VWNUcjNkUG8KUVVlTzJaQ3N0NEJDdnZOekpiZ0VOQXl4aUpRTHNTNXV3VlhPd1UwRVlnSjIrd0VRQU1GTHk5WFgyME9RL1QwTQo0SVR4M0FlTjVsR3B1bVlpZXQ4eGZ3UFhwdGt3eVBBWVcrVHlKR2VoK253MkpwQklGUjNNQnZXMEVUMVFUMlBhCjlTMVdmZFZabXgxZDlNU3RuZlM0NUxHajJ1RVZDWXBXYklNLzNwdW9pWk5zeTRHT2V3VkJNUlZVUGhDZDUrRWUKQW1UdGxGQW5kdllxRlZGQTR2ZEdFMms3aUY3bEZHTkc0ZjlGd0IxZG04NUlkVW81L1NzNkVQMmc0a2xrTmwzRApDYWg5R01BMGViYnNCa042MDREYzZEWjJYNExuNDcxMjNpOHBsMGhnQld6MlBCZ05EM2FLVTd1Y3VUUzFuSk1jCko5U3JGVXZ4ZmpFQXdKZ1YzcVNOZDVRSU8wbGxpditCMHBoMmVkOVFKRDdPR016OFBrSUFTUTZQWGtiUVRWUloKYkE4Y0k5Y1lieTdBNmtLY1dtR0k2blRxV3hiN3NlQ2s4ME9qK2hZN0hMeStPTnVBWTY2akVDOVpCQUxvSjFRTApTanNIN1F0d2l0ZGp3UFNYYzVvTWU5TlhzT3h1WWM5NVZrSXdyc1RISVlLTUFtVUxCVTQ2TjVNYUI1Z2VJOFdBClI2bmVjeDBkT2h0eHF5cEo5a2dsWjRMQU1MUnVYdmRnbnhqMWFrMUkwZWhiV2puUXRHVHh5TzJmSXRHUno5Y2cKQ0hKL0pvRHB0eUc5Tmc5a2lmV1dSaERsUzRFWE5IOUZvSVVUK283eTAxL0NpRGVpWHlKcmRjbUFhRUw5NThrcQpXNnBzYXMyeDlzYUhKN0puS0RqeTkxbnhVVVU1d1FmT01GVzlOaDRrbkFpTW5scER1UnZWbVZRVzFiUFNwS0p5CnhTVzhZOXNsV29ucGVhbTZ1MExrZmJNTVhmcmpBQkVCQUFIQ3dYWUVHQUVJQUNvRkFtSUNkdnNKa0paci9kMWwKekRUZ0ZxRUVrMHdEWStKSkRTQmRFaWVZbG12OTNXWE1OT0FDR3d3QUFKMUtELzBkMTZEdDlXYytXT3dCb1NiZQprSU8rVldkTGJ6aERzY2o1SjIvTGVTY0NvTzdFd1ZWeTY0NkEvckVsYXFMcHRzbTZ2eCt0OC9HSXZiWE9aYUFFCnZTT0Jobmw0NTgwdXdIV3NWL3RuKzdRK2h2SWFpZ01sZi85eXVhaXdhbHdhZGpQNDJ4ZUZRbk5rR2RMTFlEL28KUE1hOVEwcFNXcDlwY3lyNHdBbi9XcVRxUUlZUWgwVVhnUFRXYlpUaXkxR1poMCtDdHlzMDBMUU1GYUdpQUhuWApBSCt5ZWxTTXBDWlVRRWVKOUZ3bzlKNm5CVmU1WkN2V25LR3NOWUpBZUVoY2k0VTFaZnBtcVVhT25RMktVNmxPCnF6MVRzTDVtRU5oMG55Vm90QnQvdjJzTjY3QTM1TkhZV2ZqU00zNUNtK0UyNDQ1ZnhOa2ZSTnAzRnQvTFpHbEEKaGcvTmVtMUgxbG1sbW9ZV1BWaWFRZy81bTJIK2ZOQ2VFSHpFZzhiSlNLNWtRc3RVSFVrZ01ZWHFyZjFmdjlyKwpaZm1yWS8xUmhOV0VyV1RHb2ZyK1h0dFN3S3JKbnB4QTFCV3ZOcUtaMUl6WWRVcDkyZzJEUXRXNnV5WjdDT2kxCnVGWVdLVWJueXhBZ09VbzJrZjd6Uk5LMTlGSmo1cnRycUptRDU3S2MxNWxnQmZqUFdkY1lIeHVmbldyZWR3NFQKR1pJL3JBbzR2bVVVRDBkaFJlMDJFRVREQTNLa0IzZmNvNWprRitFalluZFlnSDl1UUlqbjEyQ1ZGMm53QzhocQozMVBXSzBQdTY5TDFleG1CYTRmWGgwY2ZlcjZ0K3NpbUl4NUxXYXJSVmFvYUk3YzJWOVBrM0hWNmw2U2s0VjJ6CmFNcVhzWEpaWERXalR6VC9MZGZnaUZONHlBPT0KPXZLcGIKLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQ==","lookup_public_key":"LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tClZlcnNpb246IEdvcGVuUEdQIDIuMi40CkNvbW1lbnQ6IGh0dHBzOi8vZ29wZW5wZ3Aub3JnCgp4c0ZOQkdJQ2R2MEJFQUM1WGRqa29jc2Z1eHZKN3Q3elQ4MkhROGJodENwL0hNSXFhQWx0em1ZSmVjbkZsNHFrCmNDaFVTc1h0N2hLL3hiSENxb0Z6dnNiUStuTTkxWHRKdEwrYis2YzFUZ0Erd3ZqL2FFdWZvMXNCbFY3dUtUSGoKOHdjOVRseG1BWHNpTTY3OVVIMTkwbHNwSTZsb2o3MkRPclBNUVU2ejBhVDRpQ0JmQTVBQzhPVnhhd2ptdXlDMgpkZGR2TURXa3ExSHVSU2V3OWdtdE9OZ1hlSUJ3eUkwbmxVS2c4d1ZFMVdiY0pGVkYvaFdJek80Z1FZV3Zyb0VMClVodFd6THVZb0w0cVdTY09Cb08vNFJKeDMzZ1JGL1VZSHpKWkI3QTdSUDRnTURjQXJxM1dOOTJRN1JKT2RnWHEKWTh6bmdINFlxNmNhMWE0RllybnJsYktLS2R3dGNhaFNNR0MxVjcyc0JNN2xjN2NUSnhKcXVTNjF6d2JpWjlGYwpYRlMycytFYk40YlNSSHY3b291Y3orYWxiSDg5b0k1Mm5JYVE3S2VEN3Q1VGUySVZqeVNPR05qci8yTUI4Nzl2ClF5T0RPOVVCNVl2dHAxRjYwTGJZWklRSTBMYVBWazI3Q0hBbHdPRlFYU2U5REZseUdoaXAvZmd5N28wRFdtbVIKTE95dTNHMzdrYnp0V1ZGR3hORXA0Zk9CUWtiNjVRaU5LQjQzUkZ6MTBIbnMrVk5RUTFWdlRmRC84ZjV3aENNTwpsekp6dk82UTJYK2FDVWVXRnlvb2RyQW85TithZU5lN0RNVFVWMVVZSEdwRS8xaENBL21hclc4MTFsNFR4Q0MzCk9Eai9haU80OHNBVEJCWXlPUmFlUVlDNUVnQ0RkR2RmNnBYWnB5Y3E1ak4ydHVMYzVhTlNpbjVtalFBUkFRQUIKelF0dVlXMWxJRHh0WVdsc1BzTEJpZ1FUQVFnQVBnVUNZZ0oyL1FtUWFCYmlKT2dWTW5RV29RU2FhckgzUzI4bgpBdlV0c3Fwb0Z1SWs2QlV5ZEFJYkF3SWVBUUlaQVFNTENRY0NGUWdERmdBQ0FpSUJBQUNvanhBQW9Eak9wUUlsClRRQlBiaHJtTis5V1kvNWk3MGVUWXZqOGFUeWIySUl5RGVqY250TmdzY056WGFQVkJ6MUd6UlVIRDFQM1o5NFUKdXZ3NEJ4SmhQSHRTbk1RcGRvRDhTaXRrOWxWMzl4V2g4L3krZThUak16Z2lCdGdEaUk4dEpFK0RZWmh3Vjc3Nwp1Tm5xVGhTUXZaVngwbHAyMGJsemtvWHZkZHJ5clJ5bXVsTGRqWk1MblM2RzN6VVJWQUQzK0FQZENDM1lta21sCmEwM3RoUWgxRkQvcVA1RTJyNDJwRlpZdHFvNkFHWFFCUUhLZWpndkthZmk5K2lqaGUrbUdJdTZibzVuLytUVTEKS0p1TWlFU0ZBOFd3RmcrMVJ6MS9yaDI4cmxQVmhyb1p0bStWd0lJdkVDUUVyaXh6TERLY2NVYjhkeDlNVUtxTwpkdFJBMFdlV1lETEduOTNHWDdITS9Ea0NrdGlXUHhVUEZlQXQzb3RGcVFyU2ZZa0lpRVROMmtEdWRyVXM5b2JJCjN4OUpLdi9uTUU1SmhTeHlaS21aYzJiL25sanMzck5xYUlPRXh1dTE2QUlGQ0JiV0paZVkwYVRpRUwvUUpoS2MKdjRla1Z1cGtXdWVjT2hmQ01OaUNoWU15NWJtRFJYMWlIZ2JDZnV6V1grMXgrd2RaVk5xdWJSYVVodG4rV0RLNQpBdk9hazdWdTRIVUQ2U3JYa1htWEhNY0d0STRTV1U3amcrM2NkR3pIOHZRR1JCUmE4YWt3MzFxM2Jqb0p5NXZiCnh5eXM5bkxQdm9CV0hxZ2JHNjl0L2trTEhMdmZ1MDRlSDF1a1Y2ZGFLOWFoSDQzNisvdldxRUZFT2NFUGtMMDEKa0xPYXJBbFA1aHFmdXF4ejliWVIwRTM0d2dURXZtMVZqL0xPd1UwRVlnSjIvUUVRQU9RRXhZSXJuYVNJUmJnOAo1RWxKQUJJR0lsdmQyWUpiQWJxUkxOa2lDR1JwbVpVdUlwRnlvMXdJc0Uvb3Z0bTZTRWJuNmRNNjBFUzZ0S1NCCmhBQTJpTUNMWUNlYnQ3NUVPeWJxaWZJV2xCWUh0VjQ2Vzl3MURhdjBLVjdxWW1aSDRveHp3bW9JNnhCT0w1OUQKZDU4eWdQMkl2dUdYTll4TExrZmVkMlVubStSNTBqODZZekxaZnNYSHRMZnZPSDhSaG1JSEtMN3lPdUpsMGIzYQo2TWxLK0JBNnIwSjYwUUU2ZGkyYnZJWUdVYUkzdlMvc21RZTVFcTJmT040VmM3aFlxbmFxV0dnZi8zWVZ4ZDAzCkhreVdtMFRBMzN6UkNHQytWQnN6RmpobWJBRWt4dTRlWlpDZFpCRTJnb0preFlLZXpoOXVTRUZKWjJHaG5uSDIKdXE2MDdlMXRUR0NBOXZ6U2xWV0tpV1RJYzl0OGtYUDgvNGcyZUY4c0I3RzZWdEY5cUlrVXp0SXJkbFh5dGpBTwpqTGxvZzN4ZmlWR2ZSdGxDR2w2MVliUjd2ZUlWelVJaEtsUHVVbUNuWlJPS0NuZzJyQ1RlcmVkcm85M1gybFNwCm5IR3ZuWWhGY3lLekVtcEpXZlcxbzZJb0pQTkk4VU1CVGxaOVgxbURPVnM2enE0K1djMHcvS3ZmNXMvVHJuUTUKWlpqUkdkWWR6N2YxaGozUzd0TzFzeHkvU3MzV2ZlMVZKOTJCbklRQVNFcXJrdis3azd1ellzK251VUlzMlVGWQpRNjM3UnNlQ0pHczJWQm5QK2FlUXIrOFoySEswV3ovVGtYbXZML1BBeUNKSWhvaXJzbVVYM0lQWCs2cktNT2ZPCjZFK0pyb0gzblp6VzIxYzc2UFhCYnNpZkwxUS9BQkVCQUFIQ3dYWUVHQUVJQUNvRkFtSUNkdjBKa0dnVzRpVG8KRlRKMEZxRUVtbXF4OTB0dkp3TDFMYktxYUJiaUpPZ1ZNblFDR3d3QUFFbkhFQUNkQnZQU3NwUDIyaXVOSFlMbwpEd2NUSUQvV1VhY21FOHNWK3BrVWJ0U25VeEtLZHo4ajJrWWpLQXVzRWErWFNlekxBbmVwQmZTTkFCQ1FUREt5Cm1saWVNdUhRMjc4N0VNYmx6SHBaZGQvTlNTWEtoaTNFQW44QUJYdFRXV0tSeXFuVWdFY2tacXMzNFBPNXRUZ3gKR3F1cjF4YzJWc2QveGN1L1ZETU5sNFZDVkNOZ3R4SEJLZ05wMFdtZDVQY0U1bHo2cVloZ0phTmFQMUhleUVrMwptZUlqd0N4amdxK1kxeGI3YXRGTWpZd29YbnBTMWRjN0tDQU9nZGpJenpYOW9qWGJVc0ljaVA5cFNPekFrN08zClRtT3o0SEQxV3R1NitYR29lZWpsVWZFUUZZMjdmY2g3ZXFhKytCWGhEQWtvZlVsY1UwZUJEOEkzQjNDL1ZQWTUKM0RSeHEwa1VlMWNOTGNiUnVKbmhMbHg2ZCsyRmNaZ2R4L096K3ZSSnpRcHlQcW5mOUlpLzcyNUsyS3NJTTlucApLN2htbGc5SG0wcGZBUXFkVXJNWHlOQjVFM0R6MkJ2bHN4Y2FTZklIU2RkR1JLOWZ4QkpIK0lPOTB0dVkvNitpClFQUE5xVjh4SnpKeUFybGl2eEFrZ0NBRzhZa2w0dzA4blhFTXJGOFBGRVJLckd0VVk2U09IRzM2dkVTOGZHYWoKR2RQZkJzK0FTRlA1cnB2V1VDTjR6MDRjRnRNSnp0UForRkRWL1RiNEV6TEE4WUFZTnVpVDVyZ1FHbEduR3JBSwpDclVma2NpS2RHMEJsOWFRZ0Z2cXMxUkdrektINzA2SFhzalA3RlhNc2lGS2p1clNuSFhscmJHK2dMc0pYQ2Y3ClNIUlZFRnFwdmd5S3g0ckFaNjdweXd3THhRPT0KPVJvUUYKLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQ==","pull_servers":[{"Url":"mqtt://127.0.0.1"},{"Url":"meow://127.0.0.1"}]} \ No newline at end of file diff --git a/invitation.png b/invitation.png new file mode 100644 index 0000000000000000000000000000000000000000..d9bde5902d183e1206ab712636a8920b95d5ee09 GIT binary patch literal 530 zcmV+t0`2{YP)U8PPD4 zxfv0ujP}P^{|rmp&-tHf5)r{ zc{2EVTHQ@3_r;;R-QV-JthX^ND($nDnXoD}d{N(|uKXJY9GW<}*&7vKEA-j4;-=yE zi|V2Gb~Vb&2RsuU7$aRN^VE;p0(fvAcwF$f?|!T%onu4##B%A3#m0?@{U?-*{tKB& zs!Z5sEH@db1K|NQ$NoU8`>ffB3{7Jei-Wz6S`C`;z;{BMT^V`URh;xx$#5QZ6 zU#CwqvnqGl8FN2U0tnNXbRjTT$+EdjF2togX8qc^=v$1qyxS4VgU*<{?0l}6DR<|( zKrr!J&}tNEmdxrqK`j45fL2(n@?Ud;SWX@hOx!1!_)~(3rwAs#Aei`sVB!Lt7}=VE@b&08cu=lwa{=5daVW;ZbPe~q2U2EG#L#yL6cQ9d<(MLM#B$5 zZI{sSCA3RA8lHoauA$-YLDv*CoPwq_(Qp@(rizBwp{dr;a0b-c5gLB