-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Conversation
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
@burdges would appreciate your review as well |
I cannot see https://github.com/paritytech/labs/issues/3 btw but afaik a conventional ECIES mode would not be suitable for mixnets if that's what this references. It'd employ the same pieces of course, but they're glued together slightly differently. If you want encrypted information stored in the chain then ECIES works fine, but if nodes hold the keys then I guess you want the secrecy to be only temporary? |
@burges It is intended to work offchain. See https://github.com/paritytech/substrate/tree/master/primitives/statement-store#readme, which is basically same description as the labs issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good except I got a serious interrogation (from my understanding of eceis only): I would not use a random nonce but kdf derived data and use it in aad.
@@ -114,6 +121,13 @@ std = [ | |||
"futures/thread-pool", | |||
"libsecp256k1/std", | |||
"dyn-clonable", | |||
|
|||
"ed25519-dalek", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, ed25519-zebra
provide a limitied API for signinig/verification only. We need ECDH exchange here.
fn aes_encrypt(key: &[u8; AES_KEY_LEN], nonce: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, Error> { | ||
let enc = aes_gcm::Aes256Gcm::new(key.into()); | ||
|
||
enc.encrypt(nonce.into(), aes_gcm::aead::Payload { msg: plaintext, aad: b"" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we use aad
to some additional kdf content?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I understand aad
is not that useful as long as we use a new unique ephemeral key for each encryption.
let ephemeral_pk = x25519_dalek::PublicKey::from(&ephemeral_sk); | ||
|
||
let mut shared_secret = ephemeral_sk.diffie_hellman(pk).to_bytes().to_vec(); | ||
shared_secret.extend_from_slice(ephemeral_pk.as_bytes()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be ephemeral_pk then shared_secret. I don t think it matter (and found it describe in the order you use).
I'm confused why substrate needs a non-transport encryption. Do you want a host call for this? If you do not want a host call, then folks should use the AEAD crates directly, not this interface. If you do want a host call, then you should make them future proof. Imho, this means:
I'm dubious about the use cases list in https://github.com/paritytech/substrate/tree/master/primitives/statement-store#readme too. I doubt ECIES fits all those, like maybe not revealing the secret key matters somewhere? As for your question, associated data likely becomes important somewhere. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I misunderstood the use of aad, looks good this way.
It is intended to be used in statement-store, so not a direct host call.
Makes senes. I'm going to remove it from |
We should hammer down more concretely how one uses the statement store in those applications imho, like how would state channels use this? Also, some questions:
I suppose the "fee payment by another party" use makes more sense, in that you provide the transaction that pays the fee, and transfer the secret key inside the statement store. In principle, soft key derivation works as here too, and seems simpler, but not all schemes support soft key derivation. Soft key derivation breaks BLS for example, but really accounts should never use BLS anyways. Btw, Ed25519 has soft key derivation if you do things Tor's way, not Cardano's way. I'll give some concerning examples: I'm dubious "ring signature aggregation" makes sense. In say a zkAMM or MimbleWimble, you'd send ring-like signatures on some Pedersen commitments directly to a collator, but also reveal the opening, so then the collator makes a block which hides your opening, but produces their own zk proof using the opening, like they create the UTXO or aggregate transactions. An account provides encrypted metadata for its future self, like say an opening of a pedersen commitment in ome zk chain. We could store this data on-chain, but doing so maybe larger. We could store this off-chain, but then we could lose user data more easily than the whole chain dying. In between, we'd want some erasure coded statement store, but likely with the signatures paying some on-chain fee, and reconstruction when nodes disappear. A sender provides a signed transaction with an encrypted component, which contains a transaction they claim satisfies some properties. There are penalties if these claims are false, so decryption must happen on-chain. Also, a receiver should not provide their secret key, only the key exchange result. If the AEAD's MAC fails, the chain cannot tell if the the sender lied about the encryption, or if the receiver lied about the key exchange. Instead, the receiver should supply a DLEQ proof of doing the key exchange correctly, which works exactly like the DLEQ proof in sr25519 or VEd25519. Btw, you need slightly more if you want this scheme to be composable with VRFs. An MEV defense in w3f/Grants-Program#1660 and elsewhere has parachains insert encrypted tx into a block, and then decrypt the transaction in the future. Aside from inner and outer signature, their scheme cannot fit the statement store:
Anyways, we should understand the actual use cases for the statement store, but avoid making exaggerated claims. |
This one is for @gavofyork, as he wrote the original spec. There's going to be a statement store PSP where we can discuss this further.
This is for parachains and other substrate-based chains as far as I understand.
Statement store provides things like the network protocol, database storage with indexing. Implementing all of that on top of substrate is not a trivial task. We also provide a standard runtime event for submitting a statement. There's going to be an integration with the mixnet for network level anonymity.
Wallet integration will probably still need some customization for each use case anyway. The statement store itself is designed to be generic enough. You can put anything into the data field, including, for example, a custom signature scheme or encryption. |
Alright cool, so this is really more about message transport, and these messages arriving at where they should go, which maybe everywhere. As an aside, I really know little about it but https://openprivacy.ca/work/cwtch/ uses https://docs.rs/fuzzytags/0.6.0/fuzzytags/ and you might find that interesting. It's not really privacy preserving, but it's one way to keep messages form going to every node. It might find your real applications here better than it fits cwtch.. or maybe cwtch itself could just be used somehow. It might otoh not work very well since if you've like 10 accounts when you only want to talk to one RPC node, and if cwtch is sending all those accounts messages to different RPC nodes because they have different keys then that sucks. |
This implements simple encryption scheme that uses x25519 key exchange and AEAD. Required for https://github.com/paritytech/labs/issues/3 and #13893