DimensionDev / Maskbook

The portal to the new, open Internet. ([I:b])
https://mask.io
GNU Affero General Public License v3.0
1.51k stars 310 forks source link

[Bounty] Unlock the imagination of online publication directly on Twitter with Unlock Protocol #2363

Closed yisiliu closed 3 years ago

yisiliu commented 3 years ago

Catalogue

Part 1: Problem Description

Mask offers a browser extension which lets users create encrypted tweets where the content of the tweet can only be “viewed” by other Twitter user if they use the Maskbook browser extension. These tweets can include text, but also images.

Unlock is a protocol for memberships which lets creators deploy a lock and sell access to this lock using the Ethereum blockchain. Locks can be added to websites, or applications in order to monetize them.

We are proposing an integration between Unlock and Mask where creators will be able to post encrypted Tweets and put them “behind” a lock, so that only members of the lock are able to view their content. If viewers are not members, then, Mask would offer the ability to Unlock these memberships. In that scenario, Mask is a referrer and should earn UDT.

For a more detailed description, you can refer to this.

Part 2: Resources

https://unlock-protocol.com/ https://github.com/unlock-protocol/unlock

Part 3: Contact and Support

Mask Discord Server @yisiliu @Jack-Works -> Mask @julien51 -> Unlock

gitcoinbot commented 3 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


This issue now has a funding of 2000.0 DAI (2000.0 USD @ $1.0/DAI) attached to it.

gitcoinbot commented 3 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


Work has been started.

These users each claimed they can complete the work by 265 years, 9 months from now. Please review their action plans below:

1) iamzubin has been approved to start work.

Hey, I read all the requirements and I think I will be able to do the job in a few week, The google doc is very helpful and the code is well documented which would be really helpful in for the development of the feature, We can discuss more about the project on discord.

Thanks, looking forward for working on this project 2) koosy79 has applied to start work _(Funders only: approve worker | reject worker)_.

Something like the limitless possibilities protocol or take out the possibilities Or something absolutely so amazingly pompous that people will have to investigate

Learn more on the Gitcoin Issue Details page.

gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

iamzubin commented 3 years ago

bump

gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

iamzubin commented 3 years ago

bump

gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

iamzubin commented 3 years ago

bump

iamzubin commented 3 years ago

bump

Jack-Works commented 3 years ago

So let me try to describe how this might be work:

  1. Creator:
    1. Let content be the content to be encrypted (input by the creator).
    2. Let K be a pair of randomly generated EC keys.
    3. Let AES be a random AES key.
    4. Let encrypted be encrypt(content, AES)
    5. Let hint be encrypt([K.priv, AES], localKey) (Note: localKey is an AES key in Mask. It is used to help the author to store some really private information. Question: Or the self public key?).
    6. Let id be a new UUID.
    7. Set Metadata of the post to contains id, encrypted, K.public, hint, pay_address.
    8. Listen to the channel unlock-ping-$(cut_hash(id))
  2. Customer:
    1. Get id, encrypted, K.public, hint, pay_address.
    2. Once paid to the pay_address, continue.
    3. Let K2 be a pair of randomly generated EC keys.
    4. Let req be encrypt([ customer_wallet_addr, K2.public ], K.public)
    5. Send req to the channel unlock-ping-$(cut_hash(id))
    6. Listen to the channel unlock-pong-$(cut_hash(K2.public))
  3. Creator: (receiving a message from the channel unlock-ping-$(cut_hash(id)) above)
    1. Let [addr, K2.public] be decrypted message with K.private, if failed, ignore the message.
    2. Verify if addr has paid on the blockchain, if not, ignore the message. (Maybe we should wait for the block confirmation?)
    3. Let key be encrypt(AES, pub).
    4. Send key to the channel unlock-pong-$(cut_hash(K2.public))
  4. Customer: (receiving a message from the channel unlock-pong-$(cut_hash(K2.public)))
    1. Let key be decrypted message with K2.private, if failed, ignore the message.
    2. Try to decrypt the unlock message
gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

gitcoinbot commented 3 years ago

@iamzubin Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

iamzubin commented 3 years ago

Bump

thisispalash commented 3 years ago

So, this is the protocol we have come up with. We think this should do the trick and allow for securely transferring the keys to a customer, even in the event of the creator being offline. Essentially, the customer, on receiving the keys once, listens for another customer to ping on a different channel and then transfers the unlock key(s) subject to verification of payment.

We realised that a customer may easily share the unlock-key or even sell them at a rate lower than the creator. Hence, we now create a new key for every post, and send that. The customer can still bootleg the keys but there is now more effort involved for the customer and hence, less incentive to do so.

Creator Steps [creator]

step description variables next data-src
1 Create a post and UUID() post, id 2
2 Create AES (for post), ECDSA (for handshake) AES_post, ECDSA_handshake 3
3 Encrypt post with AES enc_post = encrypt(post, AES_post) 4 creator_1, creator_2
4 Create hint (in case all post keys are lost) with some localKey hint = encrypt([id, AES_post, ECDSA_handshake.priv], localKey) 5 creator_1, creator_2
5 Set metadata [visible by Mask users] with the id, encrypted post, ECDSA_handshake.pub, hint, and the contract address metadata = ( id, enc_post, ECDSA_handshake.pub, hint, unlock_address ) 5b creator_1, creator_3, creator_2, creator_4
5b Post the content 6 creator_3, mask-submodule
6 Listen on ping channel for a customer to ping listen unlock-post-ping-$(cut_hash(id)); { data: request_key } 6b
6b Decrypt incoming data with the ECDSA private key wallet_address, cust_ECDSA_handshake.pub = decrypt(request_key, ECDSA_handshake.priv) 7 customer_5, creator_2
7 Confirm that the address has indeed paid the contract (transaction confirmation?) 8 creator_6b
8 Encrypt the post encryption key with the incoming public key key_data = encrypt(AES_post, cust_ECDSA_handshake.pub) 9 creator_2, creator_6b
9 Ping the pong channel with the cut_hash of the incoming public key and key_data ping unlock-post-pong-$(cust_ECDSA_handshake.pub); { data: key_data } 10 creator_8
10 Unsubscribe from the pong channel del unlock-post-pong-$(...) 6

Customer Steps [customer]

step description variables next data-src
1 Get the metadata variables metadata = ( id, enc_post, ECDSA_handshake.pub, hint, unlock_address ) 1b mask extension
1b Lookup the key for id AES_post = lookup(id) 1c | 1d customer_1
1c Decrypt the encrypted post with the AES key and read the forbidden texts post = decrypt(enc_post, AES_post) 8 customer_1, customer_1b
1d If key not found, display unlock-button 2 mask-submodule
2 Pay with preferred wallet, through UI wallet_address = pay(unlock_address) 3 mask-submodule
3 Create two sets of ECDSA keys, for handshake and discovery cust_ECDSA_handshake, cust_ECDSA_discovery 4
4 Encrypt the wallet address (paid with) and handshake public key with the incoming public key request_key = encrypt([wallet_address, cust_ECDSA_handshake.pub], ECDSA_handshake.pub) 5 customer_2, customer_3, customer_1
5 Ping the ping channel with the request; ping unlock-ping-$(cut_hash(id)); { data: request_key } 6 | 7 customer_4
6 Listen on pong channel for the creator to send post decryption key listen unlock-pong-$(cust_ECDSA_handshake.pub); { data: key_data } 6b creator_9
6b Decrypt incoming data with ECDSA private key AES_post = decrypt(key_data, cust_ECDSA_handshake.priv) 6c customer_6, customer_3
6c Decrypt the post and read the forbidden text post = decrypt(enc_post, AES_post) 6d customer_1, customer_6b
6d Close the pong channel del unlock-post-pong-$(...) 6e
6e Delete the ECDSA keys del ust_ECDSA_handshake, cust_ECDSA_discovery 9 customer_3
7 If no response after t seconds, ping the discovery channel with the cust_ECDSA_discovery.pub if time > t: ping unlock-post-discover-$(cut_hash(id)) 7b
7b Listen on the private channel for a peer's public key listen unlock-post-discover-$(cust_ECDSA_discovery.pub); { data: handshake_data } 7c customer_3, customer_8c
7c Decrypt incoming data with ECDSA private key peer_ECDSA_discovery.pub = decrypt(handshake_data, cust_ECDSA_discovery.priv) 7d customer_7b, customer_3
7d Encrypt the wallet address (paid with) and post id with the incoming public key request_key = encrypt([wallet_address, id], peer_ECDSA_discovery.pub) 7e customer_2, customer_1, customer_7c
7e Ping the private channel with the request ping unlock-post-discover-$(cust_ECDSA_discovery.pub); { data: request_key } 7f customer_3, customer_7d
7f Listen on the private channel for the post key listen unlock-post-discover-$(cust_ECDSA_discovery.pub); { data: discovery_key_data } 7f customer_3, customer_8i
7g Decrypt incoming data with ECDSA private key AES_post = decrypt(discovery_key_data, cust_ECDSA_discovery.priv) 7g customer_7f, customer_3
7h Decrypt the post and read the forbidden text post = decrypt(enc_post, AES_post) 7i customer_1, customer_7g
7i Close private channel del unlock-post-discover-(...) 7j
7j Delete ECDSA keys del cust_ECDSA_handshake, cust_ECDSA_discovery 9
8 Listen on the discovery channel for an unsolicited peer's public key unlock-post-discover-$(cut_hash(id)); { data: peer_ECDSA_discovery.pub } 8b customer_1, customer_7
8b Generate new ECDSA keys and encrypt the public key discovery_ECDSA, handshake_data = encrypt(discovery_ECDSA.pub, peer_ECDSA_discovery.pub) 8c customer_8b, customer_8
8c Ping the private channel to handshake ping unlock-post-discover-$(peer_ECDSA_discovery.pub); { data: handshake_data } 8d customer_1, customer_8b
8d Listen on the discovery channel for the [encrypted] wallet address listen unlock-post-discover-$(peer_ECDSA_discovery.pub); { data: request_key } 8e customer_8, customer_7e
8e Decrypt incoming data with ECDSA private key discovery_wallet_address, discovery_id = decrypt(request_key, discovery_ECDSA.priv) 8f customer_8d
8f Confirm that the address has indeed paid the contract (transaction confirmation?) 8g customer_8e
8g Lookup the relevant post key AES_discovery = lookup(discovery_id) 8h customer_8e
8h Encrypt the post key with the incoming public key discovery_key_data = encrypt(AES_discovery, peer_ECDSA_discovery.pub) 8i customer_8g, customer_8
8i Ping the private channel with the key ping unlock-post-discover-$(peer_ECDSA_discovery.pub); { data: discovery_key_data } 8j customer_8, customer_8h
8j Unsubscribe from the private channel del unlock-post-discover-$(...) 8k
8k Delete ECDSA keys del discovery_ECDSA 8 customer_8b
9 Store the id, key, and contract address store(unlock_address, id, AES_post) 8 customer_1, customer_6b | customer_7g
thisispalash commented 3 years ago

Also, the updated bounty quote as per the new requirements with a [rough] time breakdown and payment milestones, as discussed with @iamzubin.

updated bounty quote [160h ⇒ 6000 USD]

ideation 10 March ⇒ 500 USD

server 20 March ⇒ 2000 USD

client 28 March ⇒ 2000 USD

rendering 31 March ⇒ 1500 USD

Payment Milestone

yisiliu commented 3 years ago

@iamzubin @thisispalash the bounty size is updated. Good luck guys! If you need our help to expedite your development, please let us know. Our team would like to help!

Jack-Works commented 3 years ago

@yisiliu hi please review the https://github.com/DimensionDev/Maskbook/issues/2363#issuecomment-794435705 algr. I stay up late and my brain is not clear now

yisiliu commented 3 years ago

@iamzubin hey do you guys have any updates?

Tedko commented 3 years ago

also cc @thisispalash

iamzubin commented 3 years ago

Hey, yeah there's been some delay. We're working on it.

thisispalash commented 3 years ago

Hi,

I apologise for the lack in communication, my schoolwork piled up significantly. We should be on track to finish up by next weekend (ie, by Apr 4) instead of Mar 31.

Presently we are working in parallel with @iamzubin handling the client side features and me handling the web socket server. For the server specifically, I need to implement a Trie to store the UUIDs of the channels (and addresses subscribed to the channel as a list). Post that, just a simple server sync would be left (either via redis, or manually).

As for the client side, @iamzubin has finished the verification of transactions. He'd be doing the logic for displaying the tweet / unlock button next. Post that, the key management by talking to the server.

After integrating everything, we'll write the tests (which is probably bad practice but what the hell) to submit the PR. We may need assistance in writing said tests.

We mostly will not be working this weekend due to Holi (for @iamzubin) and me having two exams early next week. Hence, the shift in deadline.

I apologise again for the delay in response.

yisiliu commented 3 years ago

@thisispalash thanks for syncing with us and you guys are totally fine but please do let us know if you need any help since we would like to prioritize this feature in our plan. @julien51 what do you think?

julien51 commented 3 years ago

Works for me! Please do let me know if you get stuck...

yisiliu commented 3 years ago

Hey @thisispalash @iamzubin any update? Please create a pr so that we can start reviewing it ASAP

thisispalash commented 3 years ago

Hey, so we have been working in a separate repository. I've made it public and you can view the code. I've been on the server branch while @iamzubin has been working on the frontend on the unlock branch.

We still have to write tests and integrate a bunch of things. Sorry about blowing through the weekend deadline, but you can review the code at least. I think this should be done in another week, but I am not certain as there are a lot of firsts for me in this project and my estimation has clearly been off.

yisiliu commented 3 years ago

Thanks @thisispalash we will start reviewing it later and see if we can assist you guys there

thisispalash commented 3 years ago

Sure that works. Let us know if there are discrepancies you see in conventions or if there are better practices. Off the top of my head, I know some files have mismatched spacing but I am not too sure if that affects anything. Also, my discord is k!ller#6839 (notice the !) if you don't want to make this thread super long (already have to scroll quite a bit).

Jack-Works commented 3 years ago

please cc me if u need a review on https://github.com/thisispalash/bounty-maskbook

yisiliu commented 3 years ago

@iamzubin hey man what's your update on this bounty? I was reading your unlock branch but didn't see much update there.

thisispalash commented 3 years ago

@Jack-Works yes please. Specifically within this folder (server-ts on the server branch).

iamzubin commented 3 years ago

@iamzubin hey man what's your update on this bounty? I was reading your unlock branch but didn't see much update there.

Umm yeah, I've been working on my fork of Maskbook Ran into some issues, resolved now. Will PR soon.

yisiliu commented 3 years ago

@iamzubin thanks! Looking forward to it!

Tedko commented 3 years ago

Good job guys @iamzubin @thisispalash looking forward. pls keep us updated

yisiliu commented 3 years ago

@thisispalash @iamzubin hey guys I hate disturbing people but can you have us updated please? It's been a while and we really want it to be merged, soon.

iamzubin commented 3 years ago

Yeah, apologies for the delayed response on github, I'm being active on the discord group.

here are some screenshots of the progress image image

we'll be trying to finish up the project ASAP.

iamzubin commented 3 years ago

Hey @Jack-Works @yisiliu,

I just finished with all the client side logic and UI elements. Meanwhile @thisispalash was working on the server for the key sharing.

As you explained in the issue #2520

It must meet the following requirement:

  • Have none or very low network traffic when there is no message for this client wants.
  • Opt-in Subscribe to certain message types (e.g. plugin/unlock/key_hash_partition_x).
  • Privacy concerns, no meaning info leak to it.

It would be better if it meets the following requirement:

  • Decentralized like matrix (multiple servers) can connect with each other
  • Can store and replay the messages for a certain time in case the client wants to receive the event when it is offline.

We decided to build a web socket client and chose Redis for different server hosts to sync.

Is there any other way way we can write the server so we can also hold the message and so the Decentralised network is not essentially centralised (Redis).

iamzubin commented 3 years ago

Oh! By design as discussed in the discord chat This service could replace the current system in place (gun database). So it should be designed keeping in mind.

Jack-Works commented 3 years ago

Oops, I reviewed that in the wrong branch. Let me do that again

Jack-Works commented 3 years ago

Hi @thisispalash can you write a README in the repo to explain what are UserAction UserChannel Trie and how those things composed? I'd like to understand this correctly before review this.

iamzubin commented 3 years ago

Hey, @thisispalash won't be working on this project anymore, So I would be taking over the server code as well. This is basically the structure for the request example for a request for a post with the cut-hash-id = 123abc

{
    "identifier" : "123abc",
    "action" : "join",
    "channel" : "ping"
}

about trie, it's a data structure @thisispalash decided to use to speed up the lookup for the room identifier Wikipedia Trie

iamzubin commented 3 years ago

What I'm actually more concerned about is the basic working of the server, as it being a websocket server we don't currently have a way to relay the messages to perform the key exchange in multiple sessions(/parts if one of the user disconnects in middle of the exchange ). we decided it should be fine as long as any one user that has the key to unlock the post is online would share the key.

another concern of mine was about the redis database, and the usage of a pub/sub client to sync up multiple websocket server if someone(or later we) want to add new servers. this was the best solution we could come up with, if you have any other suggestions. ( as explained above it matches the "must" requirements but not the "would be better/nice to have" ones)

iamzubin commented 3 years ago

Hey, @yisiliu @Tedko I’ve been trying to contact you guys on telegram but @yisiliu hasn’t been replying since a few weeks and @Tedko stopped replying as well :(

Can I please get a split of the payment as discussed in the issue here https://github.com/DimensionDev/Maskbook/issues/2363#issuecomment-794577313

Also @Jack-Works please take a look at the server so I can continue working on implementing the feature

cc @julien51

Jack-Works commented 3 years ago

Also @Jack-Works please take a look at the server so I can continue working on implementing the feature

Yes sure, sorry for the delay

Jack-Works commented 3 years ago

@iamzubin Hi can you open a PR in your repo from the server branch to the main/master branch? Therefore I can provide my review suggestions in that place.

iamzubin commented 3 years ago

Okay, will do.

I just want you to confirm about the plans for using this codebase, this is essentially a key exchange server. We’ve been using gun server for doing that till now. Would this server be replacing gun or would work along with it?

as mentioned here https://github.com/DimensionDev/Maskbook/issues/2363#issuecomment-842136214

Jack-Works commented 3 years ago

I just want you to confirm about the plans for using this codebase, this is essentially a key exchange server. We’ve been using gun server for doing that till now. Would this server be replacing gun or would work along with it?

Maybe both.

iamzubin commented 3 years ago

https://github.com/thisispalash/bounty-maskbook/pull/2

Here’s the PR @Jack-Works