
Twinkle Notes: Cross-platform encrypted notes app - twknotes
https://github.com/twinkle-labs/twinkle-notes
======
leppr
Just wanted to say I love this business model of providing a free open source
app, with convenient secure syncing being the paid option.

The trade-offs for a user who's committed to not paying for the premium
features are mainly about convenience and security (having to maintain a fork,
and missing out on automatic security updates), which ressembles those they
would have to make by pirating a closed-source app.

Right now the license is AGPL, is this temporary (since the website calls the
app "Source available" vs "Open-Source")?

PS: The submission title should begin with "Show HN:".

~~~
twknotes
We are definitely using AGPL because, for the paranoid, they should be able to
build their own binaries and distribute to their friends.

------
CiPHPerCoder
> end-to-end encrypted

[https://github.com/twinkle-labs/twinkle-
notes/blob/45206f9d6...](https://github.com/twinkle-labs/twinkle-
notes/blob/45206f9d61899a934c65db85f49a705730046fad/site-lisp/lib/space-
list.l#L53-L66)

For AES in CBC mode, IVs have two requirements:

1\. They must never repeat.

2\. They must be unpredictable.

Generating them from a SHA256 hash of some low-entropy data is not a good
practice.

[https://paragonie.com/blog/2016/05/how-generate-secure-
rando...](https://paragonie.com/blog/2016/05/how-generate-secure-random-
numbers-in-various-programming-languages#commonlisp-csprng)

Furthermore, not authenticating your ciphertext means padding oracle attacks
can be launched against the app.

[https://robertheaton.com/2013/07/29/padding-oracle-
attack/](https://robertheaton.com/2013/07/29/padding-oracle-attack/)

~~~
twknotes
Thank you for digging into the code. This is why we are going open source. The
encryption you are referring to is for encrypting a list of keys for your
local notes storage, which is not exactly part of the end-to-end encrypted
syncing. Since you have got this far, could you please have a look at:

[https://github.com/twinkle-labs/twinkle-
notes/blob/8ad7d9d0b...](https://github.com/twinkle-labs/twinkle-
notes/blob/8ad7d9d0b544f4027ec1c7fa16d4780ee7695a2f/site-lisp/lib/space-
storage.l#L264)

> They must be unpredictable

I am wondering if that is necessary, because the hacker can't perform those
attacks without the user's actively using the app at the same time. From what
I learned, the attacking process requires the presence of key somewhere. If
the attacker can get on user's device while one is using it, then it's almost
a hopeless situation. Please educate me if I am wrong.

~~~
CiPHPerCoder
> > They must be unpredictable

> I am wondering if that is necessary,

Yes, it is necessary. The IND security of Cipher Block Chaining (CBC) depends
entirely on the IV being from a cryptographically secure random generator.

CBC mode requires unique and random IVs. CTR mode requires unique IVs (but can
be predictable).

That's why we call the CTR input a nonce (number to be used once) and the CBC
input an IV (initialization vector). Since they have different security
requirements, we refer to them differently. Unfortunately, some cryptography
libraries just name the parameter IV.

~~~
metalliqaz
Is that distinction between nonce and IV held everywhere in the crypto
community? For example, rfc8439 which defines the ChaCha-Poly AEAD does not
require an unpredictable input nonce, and indeed calls it a "nonce", but many
of the common implementations I've seen use "initialization vector" instead.

~~~
CiPHPerCoder
Loosely. The majority have given up on the public understanding of nuances and
just phone it in with "just don't write crypto".

Because AES-CTR and ChaCha both refer to it as a nonce, and CBC calls it an
initialization vector, the IV/nonce distinction does matter. But if you misuse
the terms folks will know what you meant to say. Just don't mix it up when it
comes time to implement.

~~~
LookOutItsABot
Please don't ever stop this behavior. I'm just learning much of this in an
applicable way and people like you make this not just easier but possible for
those of us learning with little outside help.

The father I go down this rabbit hole the more I learn security should be like
a religion of security (only one without dogma).

Thanks.

------
wtmt
A few questions and observations:

* If I choose to use this notes app on multiple devices, and am careful enough to be the only person using it and complete any note taking on one device at a time (closing the app properly), I should be able to store and sync the sqlite database on any cloud storage service and wouldn't need the paid sync option, correct? In other words, the sync option makes multiple clients opening and making updates in the same time period a non-issue?

* The costing seems a bit weird when one digs in, because it defaults to counting in one GB increments even though the unit is stated as GBm and compared to things like KWh in the explanation. Even if you store only a few bytes of notes (or a few KBs), the documentation says that you'd still pay a minimum of 1GBm. So that works out to a $7.176 a year if you don't cross 1GB in storage used.

* Since this is open source with AGPL, anyone could fork it to support a custom sync mechanism that allows to store the database on cloud storage/sync services, but would have to make the source available if they distribute the app to others.

~~~
twknotes
> store and sync the sqlite database on any cloud storage service

It would be quite slow.

> a minimum of 1GBm

Our servers are quite dumb that if you are hosting your space with us, we need
to reserve some storage space for you. That's a fixed cost for us even if you
are not effectively using that storage.

~~~
wtmt
Why would a notes database, that’s mostly (or all text) even take up a lot of
space and make syncing the entire database slow? If someone is using just a
few MBs of data, the speed of syncing that is immaterial.

Your servers not being able to account for smaller storage sizes is a
technical limitation that you have built. You can take a look at tarsnap for
inspiration on how to account for very small amounts of data. I’m not saying
you should account for bytes, but even taking it at a fraction of what you’re
currently doing would be better and fairer to paying customers. You would also
discourage hoarders who thrive on utilizing a lot more and get subsidized by
those who barely store much.

------
torstenvl
I've seen a lot of these kinds of apps lately that have their own one-off sync
mechanism. Can I ask what were the design considerations that led to that
choice, rather than letting users sync a store via their own back end
(Dropbox, iCloud, rsync...)?

~~~
jlongster
I develop an app like this
([https://actualbudget.com/](https://actualbudget.com/)) and I'll give you my
reasons.

Those kinds of syncing work will files, and treat each individual file as a
blob. Apps don't work this way. Apps need databases and fine-grained change
tracking. You absolutely don't want to make a change in two places on two
separate devices and then have a sync conflict. If you throw the sqlite db
file on dropbox, that's exactly what will happen.

You could try to build your app around files, but now you are rebuilding a
database (and not a good one).

There are a few services that offer syncing more appropriate for apps, like
Apple's CloudKit (I think that's the one?). These could work, but in Apple's
case you can only run your your app on macOS/iOS.

There are a few generic syncing layers like PouchDB, and there are tradeoffs
with all of those. Some of these tradeoffs are deal breakers. (there aren't a
ton of good options yet)

But there are good reasons why you an app can't just eschew syncing onto the
user, and assume they'll find a good syncing service. It needs to be tightly
integrated with how the database works.

~~~
yoz-y
Those are all good reasons but I’d argue that starting from the desire to be
able to use existing sync services and building on that may be more user
friendly.

Yes you essentially need to rebuild a database, but this is for example what
1Password did.

~~~
jlongster
I disagree. I mean, it depends on the kind of app. The data requirements of
some apps might do well in a simpler model that can work OK with existing
syncing services.

But the majority of apps need more complex needs and you definitely should not
go and build a new database. The user experience will end up being flaky
(syncing problems) and/or slow (the database is not good). Not to mention that
now in addition to setting up the app, the user now needs to go sign up for
one of those services if they haven't already.

With integrated syncing, the user just fires up the app and syncing works and
they never have to care about how it works.

There's a reason a whole field of research exists into things like CRDTs.
Distributed apps are not trivial, and only ones with simple data needs could
get by without a more rigorous approach.

~~~
rpdillon
I generally agree with your reasoning, but recently experienced a counter-
example myself. I recently picked up Joplin for note-taking, and the fact that
it can sync reliably through my NextCloud instance via WebDAV was the deciding
factor in me sticking with it. If I had to rely on a company to stick around
to sync my notes, or I had to run a custom backend, I would have simply moved
on. As is, Joplin is pretty close to an ideal note-taking system for me.

~~~
jlongster
That's awesome, there's definitely room for apps like that. I have nothing
against them, but there are tradeoffs. Seems like that could work well for
that kind of app.

------
rhubinak
And an actually free (automatic sync with no limit on data capacity)
alternative: [https://standardnotes.org/](https://standardnotes.org/)

------
tobib
I'm assuming this is an app with a GUI. I wish there were screenshots showing
what it looks like.

------
urlwolf
Tried it on mint (LTS). uname -a (base) Linux q 5.3.0-28-generic
#30~18.04.1-Ubuntu SMP Fri Jan 17 06:14:09 UTC 2020 x86_64 x86_64 x86_64
GNU/Linux

I get: /opt/app.twinkle.notes/twinkle (base) dist:/opt/app.twinkle.notes
var:/home/q/.config/twinkle dist=/opt/app.twinkle.notes
var=/home/q/.config/twinkle __* Twinkle Lisp 2020 __*

DevTools listening on
ws://127.0.0.1:16780/devtools/browser/6d2dd982-a67d-4915-8517-83d4394054a3
error: file '/opt/app.twinkle.notes/lisp/lib/sqlite3.l': position 13622: line
386: invalid number #1: /opt/app.twinkle.notes/lisp/init.l:42: (load
"lib/sqlite3.l") [2020-02-05 23:23:09,394950 init#0] finished due to run time
error

This is the deb file on your website.

~~~
twknotes
This seems strange. Can't reproduce the problem here. Can you please help to
check what's on line 386?

------
vzaliva
I was in search of a good cross-platform notes app. Like Evernote, but
preferably free with the open data format. I concluded that for me,
personally, emacs org-mode with notes files stored in the Dropbox folder turns
out to be an optimal solution. YMMV.

~~~
c-smile
I think that my Sciter.Notes
([https://notes.sciter.com](https://notes.sciter.com)) will qualify that.

Notes are stored in local db yet notebooks in the db can be mapped on file
folders (e.g. folder on DropBox containing html files - each note is a single
HTML file).

The note db file can be protected/encrypted by OS means.

Windows/Mac/Linux.

~~~
urlwolf
Agreed. Sciter notes is a gem. It's fantastically fast. C-smile, congrats on
writing this masterpiece. I wish you best of luck. If you found a biz model to
support it and add features, it'd be great. So much low hunging fruit in a
world of electron apps and a crowd (HN) that mostly hates them.

------
paulcarroty
I prefer to write notes directly in VSCodium ans sync them to private git
repository. Very useful.
[https://github.com/patleeman/VSNotes.git](https://github.com/patleeman/VSNotes.git)

~~~
tobib
I can recommend [https://notable.md](https://notable.md) which I sync to a
private git repo.

------
thebeardisred
Kudos on the courage to go with the AGPL. It immediately raises my interest
quite a bit.

------
rkagerer
_On windows /linux, we have no choice but to use chromium embedded framework._

But, there are so many choices. Does it really have to be html-based?

~~~
twknotes
Sometimes you just want to make something work, as soon as possible.

------
sghacker
really like the cross-platform nature and the E2E encryption. a powerful
application masked by a humble appearance. ideal for creative workers. Would
be good see this extended to include password protections, audio conferencing,
etc.

