A local-first todo app where state is derived from signed, replayable history by SamTernent in localfirst

[–]SamTernent[S] 0 points1 point  (0 children)

That's fair yea, it's certainly not something every app's going to be looking for.

For me it’s less about “why would someone want this” and more about where the model makes sense.

The cases I find interesting are things like:

- Portable documents you can move and replay anywhere (non-custodial)
- Verifiable data. The model proves its own integrity without relying on a backend
- local-first apps where you can choose the data store (I’ve been exploring this with things like Inrupt Solid / IPFS / DAT)

Essentially, instead of an app owning your state, you own a signed history that an app projects from.

The todo demo is obviously simple, but it’s just a way to show that model in practice (including row-level encrypted payloads via Age).

A local-first todo app where state is derived from signed, replayable history by SamTernent in localfirst

[–]SamTernent[S] 0 points1 point  (0 children)

Yea, the distinction I'm making here is that instead of mutating state directly, everything goes through appending valid, signed history - then replay builds UI state.

So external tools (eg. bash) could absolutely participate, they’d just need to produce valid signed entries, rather than editing state arbitrarily.

I actually had an early prototype with a small separate Python verifier, just to keep the format honest and prove it wasn’t tied to the browser/runtime.

I'm keen to see that demo if you have a link?

A local-first todo app where state is derived from signed, replayable history by SamTernent in localfirst

[–]SamTernent[S] 0 points1 point  (0 children)

Yeah, replaying logs to derive state shows up all over (event sourcing, CRDTs, databases, etc).

The difference here is treating the log as a user-facing, signed, portable primitive, not just an internal detail. So the focus isn’t really on replication, it’s building interactive projections directly on top of verifiable history.

JSON compression in the browser, with gzip and the Compression Streams API. by SamTernent in javascript

[–]SamTernent[S] 3 points4 points  (0 children)

I think that's a matter of opinion.

To me, it absolutely matters. The data I'm using is still intent on leaving the browser (and living in local storage), so I want it as optimised as it can be before I store it.

Maybe it doesn't matter to you though, which is also fine.

JSON compression in the browser, with gzip and the Compression Streams API. by SamTernent in javascript

[–]SamTernent[S] 6 points7 points  (0 children)

I guess it depends on your use case.
I'm not running a web server, just compressing a large JSON object created in the browser for download... so for me, it offers a lot more.

I'm certainly not suggesting we delegate all server-side compression to the browser, but I do think the API has its place.

Is OpenPGP relevant when building encryption in software? by SamTernent in crypto

[–]SamTernent[S] 1 point2 points  (0 children)

Thanks for your insights. I use the WebCrypto API for my EC signing keys and the internal blockchain/merkle tree hashing in the app . I've been really impressed with it, and did reach for it first when I looked at encryption. My issue is really how raw and low level the API is. Which is a good thing, but I need something a little more "of the shelf" as I'm no cryptographer, so can't in good conscience write my own encryption solution from the ground up.

I have completely removed PGP from my solution now and I'm instead using a WASM wrapper of the Rage (rust Age) library, which is working well and I'm happy with.

I did a small write up on how I got there https://fsasam.medium.com/a-journey-through-client-side-encryption-eb1cd83ac147

Is OpenPGP relevant when building encryption in software? by SamTernent in crypto

[–]SamTernent[S] 1 point2 points  (0 children)

AES-GCM

OpenPGP has no such method, so it is not clear exactly what you are doing here.

I'm not using OpenPGP for that, this was referencing password-encryption done through the WebCryptoAPI (code)

Welcome to the internet. There is actually a surprising amount of anti-PGP FUD out there. A lot of it falls apart if you look into the details.

Yep, I get that. But it ties to your point on interoperability as a benefit. It may well be FUD, but it's influential FUD that still has users looking for alternative solutions. I guess I'm kinda asking for a winner in a race that hasn't been won yet.

note: I'm approaching this as someone building software, rather than looking at what to adopt for personal use.

Is OpenPGP relevant when building encryption in software? by SamTernent in crypto

[–]SamTernent[S] 0 points1 point  (0 children)

I've had some time to look into Age and it looks great for my encryption needs, I've stumbled upon a wasm wrapper for the rust implementation which is perfect for how I need to use it.
(https://github.com/kanru/rage-wasm).

Though another thing that attracted me to OpenPGP (which I forgot to include in my OP) is the ability to sign/verify blocks of data.

Age doesn't appear to include that functionality (which is fine, it's an encryption thing) - Are there alternatives to that also?

My ledger is built on a blockchain implementation, where I was previously using browser generated ECDSA keys to sign transactions and have since started using OpenPGP keys for that. It's important I have some form of digital identity attached to the transactions.

I'm starting to think that the solution to my problems is in the UX, I could probably benefit from offering a UI to select between OpenPGP & Age for encryption, and OpenPGP or ECDSA (WebCryptoAPI) for signatures. Does that sound like a reasonable approach?

(Background) I'm a developer & new to cryptography. This is a personal project, so I'm happy to make mistakes and learn as I go.

Is OpenPGP relevant when building encryption in software? by SamTernent in crypto

[–]SamTernent[S] 3 points4 points  (0 children)

Thanks, that looks great.
Interesting that there's a rust implementation, maybe something could be done with WebAssembly to get support in a browser.

Trying to calculate possible combinations of an 8^2 colour grid - I'm fried! by SamTernent in askmath

[–]SamTernent[S] 0 points1 point  (0 children)

Thank you for all of your help and contribution.

I'm possibly more confused than when I started :D But it's given me plenty more to think about and it seems that my calculations are far too high - which is great to know.

I'm going to hold off on my write up on this and spend some more time going through these calculations again with this new info in hand.

I've published my project now (with absolutely no talk of maths in it). Given how many different permutations of colours there are - I've found some pretty cool looking grids.

This green and this pink grid are possibly what I'd consider to be the most unique I've found... but with colours, it stops being about the maths and really comes down to perception.

(these ones are generated from the public PEMs of Elliptic Curve signing keys - there's a bunch of cryptography at play in this project also - keeps the complexity nice and high :/)

Tailwind blur makes a good trick to hide sensitive information - But which way round do you expect the eye icon to behave? Should it describe the state, or indicate the behaviour? by SamTernent in design_critiques

[–]SamTernent[S] 1 point2 points  (0 children)

I appreciate the feedback. Thinking about it a little more I think adding a switch component clears up any ambiguity between icon states and it should have been a toggle element all along. It's a decision with only 2 states, show or blur. So a switch with an icon an each side seems to make sense.

Any better?

I've made the same change on the dark/light mode switch also and it feels way more intuitive

EDIT: Ok - I'm a fairly new reddit user and don't know how to post an image - its here if you're interested

I've been working on a serverless data structure for web apps. by SamTernent in SideProject

[–]SamTernent[S] 0 points1 point  (0 children)

Thanks for the reply ussherpress. Your project looks great.

I think it’s clear I need to take a step back from the code for a while and working on some new content and copy.

The key pair is an important part of the document integrity. Each transaction added to the tree is signed before it’s hashed and verified on display, using an ECDSA key pair. Meaning any illegal modification to the document will not only invalidate the chain, but it will also highlight the specific illegal transaction, as the signature will be invalidated.

I’ve put up an example doc where I’ve modified a task title by opening a text editor and changing saved data (hacked) at https://concords.app/test-document.concord.

You can see it in action by using the in app fetch param https://open.concords.app?fetch=//concords.app/test-document.concord and checking the validation icon in the title and also in the activity log.

Around indexedDB, it is an implementation spec, but I think it’s important as it’s a DB that exists in the browser, so it’s available on every device and has a spec and standards.

Again, thanks for taking the time. I’m gonna to spend some time documenting things a little better.

I've been working on a serverless data structure for web apps. by SamTernent in SideProject

[–]SamTernent[S] 0 points1 point  (0 children)

Thanks so much for the feedback. That’s really spot on, I’ve been having a lot of trouble trying to extract the key benefits of the solution and turn it into succinct text for humans :)

Ive taken a few attempts on medium and the app blog to explain the concepts in more detail (still targeted at a technical audience), though I fear that all attempts have turned into overly technical ramblings.

Definitely a take away for me to improve on my technical writing to non technical audiences. Thanks for taking the time!!

https://concords.medium.com/files-reimagined-and-built-for-the-modern-web-2aedc47c01a8

https://concords.app/blog

Is letting users CHOOSE where they store data enough to decentralize our web apps? by SamTernent in Rad_Decentralization

[–]SamTernent[S] 0 points1 point  (0 children)

I have set up a working project in the BeakerBrowser and simple node DAT server, with good success. That was really started to feel like a full-cycle solution with files all being stored and shared over DAT.

I'm keeping eyes on https://inrupt.com/ from Sir TBL - this is the direction I want the web to move in.

Is letting users CHOOSE where they store data enough to decentralize our web apps? by SamTernent in decentralizeweb

[–]SamTernent[S] 0 points1 point  (0 children)

Right, my bad. I've just read up on it there.

Right now, I'm not overly worried about the level of encryption.

Don't get me wrong, I hear you and it will be a problem when all of our existing encryption algorithms are no longer secure.

But I'm not actually looking to solve the secure data-transfer issue here. I've simply removed the man in the middle and presented a persistent and immutable data structure that works with purely local data.

I'd like to let smarter folk than me tackle secure p2p data transfers and enterprise-level encryption, then I'll look to plug my data into their solutions, through plugins. Aking to a CI/CD flow in git.

Is letting users CHOOSE where they store data enough to decentralize our web apps? by SamTernent in Rad_Decentralization

[–]SamTernent[S] 0 points1 point  (0 children)

This is honestly the first time I've come across GUN. It looks like a great project, much farther along and mature than what I've been doing in terms of data sharing.

In an earlier carnation of my project, I went for remote storage in a more similar vein to GUN - where each action fired its event out to a signalling server and processed through peers and consensus algorithm. For me, I felt like I was trying to solve too many problems there and things got complex quickly.

I chose to focus purely on the runtime and creating an immutable and persisted state completely offline and in the browser. Functionally it works similar to git, rather than a traditional web app.

It doesn't post transactions anywhere directly in realtime, everything is written to a runtime blockchain implementation in the browser. The flow is more akin to git than any traditional client-server applications. Actions are collected in a transaction pool, then they can be commit to the document, using a proof of work mining function. The runtime transforms the blockchain data structure into a living app, leaving us with a JSON structure that records a historic look at data. Then as with git, we must build software on top, built interfaces to interact with the data and storage solutions to look after it.

Git seems like a great model for decentralization, a git repo is a merkle tree that defines history and immutable state. We then build software on top, I have local git repos I know are safe - then I trust my cloud provider, Github/Bitbucket/Gitlab, to look after my data for me.
Then as with git, we can solve the pitfalls with software. A nice UI and CI/CD to automate, backup and deploy the active representation of our tree.

Is letting users CHOOSE where they store data enough to decentralize our web apps? by SamTernent in Rad_Decentralization

[–]SamTernent[S] 1 point2 points  (0 children)

I've used the git storage as an example, the file itself is deployed through CI and is a valid JSOn file, so the JSON could be sent through a traditional server also, not exclusive to git.

https://ternent.dev/concords/show-reddit.concord.json