stellar / stellar-protocol

Developer discussion about possible changes to the protocol.
516 stars 302 forks source link

Key Context #93

Open JeremyRubin opened 6 years ago

JeremyRubin commented 6 years ago

Currently in Stellar, if a Key K exists on an Account A and an Account B with full privilege, then a transaction sourced from A with an operation from B requires a single signature.

While this is not inherently insecure, it adds a number of edge cases that make it difficult to verify behavior in cases where a key is required for different reasons within a transaction. Some of these attacks result around selecting the same key as another participant (without their checking) and others of these are resultant from from cryptographic manipulations (e.g., choosing a PKb' such that PKb' = PKb - PKa which breaks certain types of aggregation).

For example, suppose we have a protocol with three participants, Alice, Bob, and Carol. There is an account R which has signers Alice, Bob, Carol, and then an account A, B, and C, which require Alice, Bob, and Carol singularly. Our goal is to distribute to A and B and C three operations which affect account R with A and B and C as the sources, such that they can all occur independently. We want the property that B and C cannot run the operation from A's account, and so on. In the naive protocol, the signer's of R sign all three transactions, and then Alice, Bob, and Carol only sign them when they intend to broadcast them. However, the naive version is broken -- after being signed by the signers of R, each of the transactions are usable. There are two fixes to make the protocol secure in the current model: either Alice and Bob sign the transaction from Carol's account, and then give it to Carol (so Carol never share's her signatrue) and so on for Alice and Bob; or Alice, Bob, and Carol use a distinct key for their account A and the account R.

We can add some new constraints to Accounts and Signers that generally add a context for the signature that prevents these kinds of mistakes. While generally there are mechanisms that fix these vulnerabilities through stronger preconditions or smarter protocols, adding a couple low-level features will make it easier to address.

I propose few different mechanisms to force signatures to have context. In some cases, this means a single key must sign different values multiple times. All of these can be opt-in at the transaction, account, or signer level. They are somewhat redundant, so not all are needed.

1) Require signers to specify which account they are signing on behalf of 2) Assign a random IV or Tweak to a key depending on when it was added (e.g., H(ledger hash when added || public key || operation # in ledger || account id)). Signatures must use that IV/tweak for it to count against that account 3) Require signatures to include an index of which # signer they were (first, second, third, etc). This is not too difficult to do, first sort on Account ID then sort on PK. 4) Only allow a unique signature to satisfy one threshold equation 5) Require signatures to specify how many obligations they should be satisfying. Default is one

I'm not wild about any of these measures, so I'm opening it up for general discussion before making a more concrete proposal.

theaeolianmachine commented 5 years ago

Feel free to surface this on the mailing list @JeremyRubin if you're still interested in pushing this conversation further.

JeremyRubin commented 5 years ago

I'm not interested in pushing any further on this -- it's an issue with the way that we do signatures, but it's not something we can easily fix.

Similar to #92:

I think @jonjove should take a look at this one as he'll have a handle on the least annoying way to implement.

It is something we want to fix in general -- so we should just leave issue open for now.