Bitmessage / PyBitmessage

Reference client for Bitmessage: a P2P encrypted decentralised communication protocol:
https://bitmessage.org/wiki/Main_Page
Other
2.83k stars 576 forks source link

Blind signatures as an alternate proof a message is not spam #1409

Open PeterSurda opened 5 years ago

PeterSurda commented 5 years ago

Rationale

Underpowered devices (e.g. on ARM architecture) take very long to calculate the PoW. As time progresses, the difference in hashing capacity may diverge even further, some people unable to communicate with each other. This proposal provides an alternative method for proving a message is not spam, using blind signatures added to the protocol. The exact details will be updated as the proposal evolves.

The purpose of the blind signatures isn't to replace the PoW mechanism, but to augment it, and to allow alternative method for accessing the network, for example by paying for the blind signatures. The payments can be used to finance the infrastructure and development.

TLDR;

The protocol will contain a parallel inventory of objects which are signed using blind signatures, instead of having a nonce for a PoW. A miner would be able to replace the blind signature with a nonce, allowing the object to be transferred to the "normal" inventory, providing backwards compatibility. If the blind signature was obtained against a payment, the miner can participate in the revenue.

If you're familiar with bitcoin, an analogy would be a permissioned unidirectioinal sidechain (or sidepool since Bitmessage has no chain), which can be used by people who for some reason are unable to use bitcoin directly. Even though this bitmessage "sidepool" doesn't have as strong censorship resistance, through the use of blind signatures, a high level of anonymity is achieved, allowing for censorship resistance to be maintained indirectly. Also, this is only unidirectional, used for sending new objects. For recipients, the miners would provide backwards compatibility and no change is necessary.

Blind signatures

Blind signatures are a mechanism for certifier to authenticate data without knowing its content. A third party can then use the certifiers public key to verify that a particular piece of data was authenticated by them. An implementation based on pre-existing research, was created for pyelliptic for a bounty: https://bountify.co/blind-signature-library-in-python-or-c

New object structure

Instead of the "nonce" at the beginning, the object would contain an array of signatures+pubkeys (with a leading varint indicating the depth). Here an example with 2 levels. The lowest level is always a signed inventory vector, and the highest is always the top-level certifier (CA). Mid-level certifiers are possible if they are needed for some reason. This part will probably be updated regarding pubkey structure (e.g. what curve is used etc).

  1. depth - varint
  2. lvl1sig - signature of the inventory vector
  3. lvl1F - F (blinding factor)
  4. lvl1pubkey - public key for the signature
  5. lvl2sig - signature of the lvl1pubkey
  6. lvl2F - F (blinding factor)
  7. lvl2pubkey - pubkey of the certifier

Routing

An object with signatures would use Dandelion-style routing to reach a miner. The miner would replace the signatures with a nonce, and inject the object into the normal inventory. Support for routing of signed objects would be indicated through a bit in the service bitfield.

Usage

Initialisation

The CA pubkey is distributed to all participants (e.g. in the code)

Client preparation

Client sends a bunch of blinded pubkeys to the CA, who will sign them if certain criteria are fulfilled (e..g payment received) and the client unblinds them. This can happen over any protocol, e.g. through a PoW-ed object or through a new command in the protocol, with the client connecting directly to the CA node.

Client sending a signed object

Client will pick a random pubkey, and blind-sign the object's inventory vector with it, attaching all the needed signatures and pubkeys to the signature block. Then it will use dandelion-type routing to send the object to the network.

Validation

Unlike with e-cash, where double-spending is a problem, the client is motivated not to reuse pubkeys as that reduces their anonymity. So it isn't necessary for the validators (dandelion stem nodes and miners) to check if the pubkey is already used. The pubkeys could also contain some sort of expiration (e.g. a mid-level CA would be only valid for a particular month), so that the nodes don't need to keep track of old pubkeys forever. This partially reduces anonymity, but not much (one month should provide adequate granularity).

Mining

The object will eventually hit a miner, who will replace the signature block with a nonce and inject it into the "normal" network. The nodes in the dandelion stem can compare new mined objects with the signed routed ones to see if it's still necessary to switch to the bloom phase, to prevent waste.

Problems

Onion routing (ACKs) to a recipient who doesn't support the protocol will break in the current proposal (isn't backwards compatible). Therefore pubkey objects of addresses should indicate with a bitfield if they support blind signatures.

stman commented 5 years ago

Before agreeing on solutions, like for the other issue of duplicate nodes, we should agree on the problems at hand, we must take 30 minutes to talk on a mumble server, this will save everybody a lot of time I think.

Le 15 déc. 2018 à 11:10, Peter Šurda notifications@github.com a écrit :

Rationale

Underpowered devices (e.g. on ARM architecture) take very long to calculate the PoW. As time progresses, the difference in hashing capacity may diverge even further, some people unable to communicate with each other. This proposal provides an alternative method for proving a message is not spam, using blind signatures added to the protocol. The exact details will be updated as the proposal evolves.

The purpose of the blind signatures isn't to replace the PoW mechanism, but to augment it, and to allow alternative method for accessing the network, for example by paying for the blind signatures. The payments can be used to finance the infrastructure and development.

TLDR;

The protocol will contain a parallel inventory of objects which are signed using blind signatures, instead of having a nonce for a PoW. A miner would be able to replace the blind signature with a nonce, allowing the object to be transferred to the "normal" inventory, providing backwards compatibility. If the blind signature was obtained against a pament, the miner can participate in the revenue.

If you're familiar with bitcoin, an analogy would be a permissioned unidirectioinal sidechain, which can be used by people who for some reason are unable to use bitcoin directly. Even though this bitmessage "sidechain" doesn't have as strong censorship resistance, through the use of blind signatures, a high level of anonymity is achieved, allowing for censorship resistance to be maintained indirectly. Also, this is only unidirectional, used for sending new objects. For recipients, the miners would provide backwards compatibility and no change is necessary.

Blind signatures

Blind signatures are a mechanism for certifier to authenticate data without knowing its content. A third party can then use the certifiers public key to verify that a particular piece of data was authenticated by them. An implementation based on pre-existing research, was created for pyelliptic for a bounty: https://bountify.co/blind-signature-library-in-python-or-c

New object structure

Instead of the "nonce" at the beginning, the object would contain an array of signatures+pubkeys (with a leading varint indicating the depth). Here an example with 2 levels. The lowest level is always a signed inventory vector, and the highest is always the top-level certifier (CA). Mid-level certifiers are possible if they are needed for some reason. This part will probably be updated regarding pubkey structure (e.g. what curve is used etc).

depth - varint lvl1sig - signature of the inventory vector lvl1F - F (blinding factor) lvl1pubkey - public key for the signature lvl2sig - signature of the lvl1pubkey lvl2F - F (blinding factor) lvl2pubkey - pubkey of the certifier Routing

An object with signatures would use Dandelion-style routing to reach a miner. The miner would replace the signatures with a nonce, and inject the object into the normal inventory. Support for routing of signed objects would be indicated through a bitfield.

Usage

Initialisation

The CA pubkey is distributed to all participants (e.g. in the code)

Client preparation

Client sends a bunch of blinded pubkeys to the CA, who will sign them if certain criteria are fulfilled (e..g payment received) and the client unblinds them. This can happen over any protocol, e.g. through a PoW-ed object or through a new command in the protocol, with the client connecting directly to the CA node.

Client sending a signed object

Client will pick a random pubkey, and blind-sign the object's inventory vector with it, attaching all the needed signatures and pubkeys to the signature block. Then it will use dandelion-type routing to send the object to the network.

Validation

Unlike with e-cash, where double-spending is a problem, the client is motivated not to reuse pubkeys as that reduces their anonymity. So it isn't necessary for the validators (dandelion stem nodes and miners) to check if the pubkey is already used. The pubkeys could also contain some sort of expiration (e.g. a mid-level CA would be only valid for a particular month), so that the nodes don't need to keep track of old pubkeys forever. This partially reduces anonymity, but not much (one month should provide adequate granularity).

Mining

The object will eventually hit a miner, who will replace the signature block with a nonce and inject it into the "normal" network. The nodes in the dandelion stem can compare new mined objects with the signed routed ones to see if it's still necessary to switch to the bloom phase, to prevent waste.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.