Revokable Shards
@dominic proposed a way to 'revoke' shards here %eYqUfFj... , but I didn't fully understand the process, so I'm going to have a go at expanding on it in this thread
@dominic proposed a way to 'revoke' shards here %eYqUfFj... , but I didn't fully understand the process, so I'm going to have a go at expanding on it in this thread
Something like:
Alice sends a request to Bob, "hi Bob, can you look after a secret share for me?" Bob replies "yes, encrypt it to this ephemeral public key bob_e". Bob's stores this key on disk, for now. Alice also generates an ephemeral key, alice_e and encrypts the share, sending bob alice_e.public, secretbox(share_bob, alice_e*bob_e) then deletes alice_e's private key. (note: alice sends the public key she used to bob, he'll need that to decrypt the share)
I think I see the intention of this, but I've got tangled on which keys are being used where.
I'm assuming all keys are assymetric, so there's alice_e.public
and alice_e.private
.
Re-writing the story with more detail it might then look like :
bob_e.public
". Bob's stores bob_e.public
and bob_e.private
keys on disk, for now.alice_e.public
, alice_e.private
and then sends Bob:secretbox(share_for_bob, alice_e.public*bob_e.public)
(encrypted share) alice_e.public
(he'll need that to decrypt the share) alice_e.private
Things I don't understand:
alice_e.private
is ever usedalice_e.public*bob_e.public
) now on the log? .. making it not the ephemeral cc: @keks @arj @cryptix @Powersource as I know they sometimes geek out on these details!
That is correct.
Important to know: NEVER use the same nonce twice with the same key.
It's okay to use the same key again, if the nonce is different. Nonce means "Number, used ONCE", btw.
I'd also add to your example:
// alice does this:
const boxed = secretBox(message, nonce, scalarMult(alice_e.secretKey, bob_e.publicKey))
// forget the secret key, now alice can't decrypt the message anymore.
alice_e.secretKey.fill(0)
// bob does this:
const unboxed = secretBoxOpen(boxed, nonce, scalarMult(bob_e.secretKey, alice_e.publicKey))
// forget the secret key, now bob can't decrypt the message anymore.
bob_e.secretKey.fill(0)
Once you have deleted the secret key, even if your computer is later compromised, they can't get the key.
(note: it might not work if your computer was already compromised, because the compromiser could change the code so it doesn't delete the secret key)
thanks for the example @peg + @dominic.
I don't understand how this code works. Have tried reading docs but haven't been able to find anything that really helps (npm libsodium-wrapper, libsodium.org
Educated guess and then testing for myself I can see that
scalarMult(alice_e.secretKey, bob_e.publicKey) === scalarMult(bob_e.secretKey, alice_e.publicKey)
Is scalarMult
then just a function which is defined to always have this property?
I'm kinda tempted to go down that rabbit hole and just understand what is happening with the maths, but not sure how wise that is
I've been waiting to cypherlink this again!
Aside: hey @peg we've got code syntax highlighting in patchbay now.
activate it by doing e.g. ```js to start a code block
hey @peg note I've shifted scuttle-dark-crystal
to using sodium-friends/sodium-native. There's a clearly marked commit relevant to this to see all the changes.
I think I might be leaning to not directly using scuttle-invite
. It feels like we have a very specific use case and we're trying to flex something general to fit. I like the idea of invites, I also just think it's fine to not use it. We've already been a little locked in because we assumed building around requesting returns, when we've identified that that's a more a nice-to-have path and the more general case is wanting to be able to not HAVE TO have requests.
I changed to sodium-native
@peg because @mikey (who is far senior as me as a programmer) pointed out it was more up to date, maintained, and better documented than chloride
. I also had a bad time using other wrappers, and I know and trust the people using and maintaining this sodium-native
.
Sorry to hear you had to write helper functions, I don't know enough to comment on that
Code you wrote seems to make sense @peg. I notice I'm reviewing something which we said was a "do it later thing" so maybe I shouldn't spend too much time on this.
I'd arrange the functions a little differently, like I feel like the boxing and unboxing are a little muddled with databases storage - I think there should be raw box/ unbox internally then publicly there should be "create" "delete" and "read" or something which is about creating an ephemeral keypair, dropping it, and using it to read something (give it the dbKey and a message). Seperating these things should make them easier to test too
I see you've written minimal tests which is a good plan.
here : https://github.com/ameba23/ephemeral_keys/blob/master/index.js#L63 you're making keys that you're not using (other than to wipe them!)
to echo what @mix says, i recommended using the sodium-friends ecosystem because it's actively maintained by our open source friends (e.g. Dat project maintainers), well-documented, and performant.
from the sodium-friends/sodium-native docs:
All methods exposed are more or less a direct translation of the libsodium c-api. This means that most data types are buffers and you have to manage allocating return values and passing them in as arguments intead of receiving them as return values.
This makes this API harder to use than other libsodium wrappers out there, but also means that you'll be able to get a lot of perf / memory improvements as you can do stuff like inline encryption / decryption, re-use buffers etc.
This also makes this library useful as a foundation for more high level crypto abstractions that you want to make.
it's intentionally low-level, so your preferred high-level abstractions can be decoupled from the solid low-level foundation, i think writing helper functions for your situation is a good thing!
i also notice that the crypto module powering Scuttlebutt, chloride
, is now powered by sodium-friends
underneath: sodium-chloride
. so that's another option to use, however it's undocumented and it's only a simple wrapper to be compatible with a previous abstraction so Dominic didn't have to re-write other code.
oh yeah, i forgot to mention: a major motivation for using sodium-friends/sodium-native
is that it has prebuilt binaries (using prebuild
) so you can install without having to compile from source (which is especially helpful when cross-building app releases for multiple operating systems).
@keks if it's possible that a*b == c*d
, is it possible that a == c & d != d
? i.e. can a*b = a*d
? who can construct c*d
? do you have to have one of the private keys of a, b
? or do you have to know a*b
?
on chloride vs sodium-friends. I've been meaning to rewrite secret-handshake and pull-box-stream to use sodium-friends. The perf difference would probably not be measurable except maybe in pull-box-stream, because the difference is just some memory allocations. But, I very much like the idea of something like this being closer to the C api, so that one set of documentation applies. in libsodium, you pass a pointer to where you want the output, and in chloride it's allocated and returned. Also, in C libsodium you must pass a length for each input. node buffers have that as a property, so it's not necessary.
@peg you could ask @mafintosh on Twitter potentially. mmm Github issue it probably a better idea though. If you need help getting in touch he's in FoaF (friend of a friend) range
crypto weenie in action!
@peg you are ameba23 on github right? I checked and I noticed you where "member" of ssbc,
I changed you to "owner" so that you can change the name your self.
(note, everyone is added as owners, because only owners can add more members.
It doesn't mean the policy is total anarchy, but it means there isn't a technical barrier to the social process)
@mix not sure if this message passed you by, I only just saw it! https://github.com/blockades/scuttle-dark-crystal/pull/44