Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signature Aggregation #210

Closed
wants to merge 14 commits into from
Closed

Signature Aggregation #210

wants to merge 14 commits into from

Conversation

bvohaska
Copy link
Contributor

@bvohaska bvohaska commented Mar 22, 2019

Initial changes to Signature spec

  • Updated Sign, Verify, Recover
  • Added aggregate
  • Added a section for Recovery
  • Added a subsection for BLS signature public key recovery

signatures.md Outdated Show resolved Hide resolved
signatures.md Outdated Show resolved Hide resolved
…n Sign and Aggregate. Added BLS12-381 parameters.
@whyrusleeping
Copy link
Member

@bvohaska what sort of review are you looking for right now?

@bvohaska
Copy link
Contributor Author

@bvohaska what sort of review are you looking for right now?

@whyrusleeping: I’m looking for any feedback to make sure this spec is heading in the right direction. No deep review needed yet. Should have most or all of this spec ready for deep review by 28 March.

Sent with GitHawk

@bvohaska bvohaska changed the title init changes to signature spec to comply with Issue #123 (Draft Spec) Signature Aggregation Mar 27, 2019
@bvohaska bvohaska changed the title (Draft Spec) Signature Aggregation Signature Aggregation Mar 27, 2019
…nged Signature interface methods. Removed redundant references to Address since address is contained in SignedMessage. Reworked the references section. REmoved libsecp256k1 wire format b/c it is too complicated; added a reference to the authoritative code. :-(
@bvohaska
Copy link
Contributor Author

bvohaska commented Mar 27, 2019

@whyrusleeping added a very rough description for BLS public key recovery based on this. Please update with corrections.

This update should represent the last update for signature.md. All reviewers should feel free to commence a deep review on that file.

…nature must implement the Signature interface.
signatures.md Outdated
//
Verify(m Messgage, pk PublicKey, sig SignatureBytes) (valid bool, err error)
VerifyAggregate(smsgs SignedMessgage, pks []PublicKeys) (valid bool, err error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there multiple signed messages here? also does the signature get passed in? or how does this work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating name "smgs" --> "smsg" to reduce confusion. Any SignedMessage containing a signature aggregate will contain the signature aggregate as well as all messages contained therein. So we only need the one SignedMessage as input.

Setting aside golang syntax, suppose there is X = SignedMessage. To verify a signature aggregate, VerifyAggregate will perform something like:

  • For all messages m_i in X.Msgs, h_i = hash2curve(m_i)
  • Compute S = deserialize(X.SignatureBytes)
  • Compute T = e(h_1, pk_i)*...*e(h_n, pk_n)
  • If T = e(S, P2) => valid

signatures.md Outdated Show resolved Hide resolved
signatures.md Outdated

Currently, Filecoin uses secp256k1 signatures to fulfill the above interface. All signatures on messages, blocks, and tickets currently use the same scheme and format.
```go
Type SignedMessage Struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where does this type actually get used? This is not the signed message that gets sent over the network for message propogation, its something else, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be only one SignedMessage --> https://github.com/filecoin-project/go-filecoin/blob/master/types/signed_message.go#L22-L28

If there are more than one, then we should do some disambiguation.

signatures.md Outdated Show resolved Hide resolved
@whyrusleeping
Copy link
Member

good detail on the base cryptographic primitives (are there RFCs for some of that? seems like stuff that should go in the standard)

A bit more still needed before completion:

  • Spec for how message signatures are aggregated by the miner when putting together the block
  • spec for how a block with aggregated signatures gets verified
    • Where do the public keys come from here? (they come from the chain somehow, but that needs to be detailed)
    • The account actor needs to be upgraded to hold public keys for bls based accounts
  • What does the array of signed messages in the block look like now that some of the messages have had their signatures aggregated?
  • How exactly do we disambiguate signatures?
  • add the signature type to the data-structures doc, along with pointers to how things are serialized.

probably more questions, but once the above is done, let's get dev to review. A sign-off from them is what we're after.

@whyrusleeping whyrusleeping requested a review from frrist March 29, 2019 21:00
… 'smgs'--> 'smsg', commented out the Sign method for the Signature interface as it will need to be a method on a privateKey
Copy link
Contributor

@dignifiedquire dignifiedquire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall nice shape 👍

I haven't found any documentation about how hashing is done, and what exactly is hashed in terms of bytes. Maybe this is supposed to be defined somewhere else, but needs to be there eventually

signatures.md Outdated Show resolved Hide resolved
- Avg. processing power available to a CPU
- Affects ability to verify signature aggregates
- Each signature or collection of signatures should be validated with no impact to the consumption of the chain
- `Gas` cost - `Gas(ECDSA) > Gas(BLS)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please clarify which operations are more costly than others, eg Gas(ECDSA_Sign)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have this information. Ping @whyrusleeping : can you answer this?

signatures.md Outdated Show resolved Hide resolved
signatures.md Outdated Show resolved Hide resolved
signatures.md Outdated Show resolved Hide resolved
signatures.md Show resolved Hide resolved
signatures.md Outdated Show resolved Hide resolved
signatures.md Outdated Show resolved Hide resolved
Copy link
Member

@frrist frrist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really thorough, nice work!

I have a couple questions about the assumptions we are making wrt addresses using protocol 0.

signatures.md Outdated Show resolved Hide resolved
signatures.md Outdated
Input: Address
Output: "BLS", "ECDSA", or "INVALID"

1. If Address.protocol = 0 output "BLS" and stop
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this could be ECDSA, BLS or INVALID. Protocol 0 indicates the address represents an ID and ID's are issued to for all actors. Some discussion was had here about creating a mapping from ID to PublicKey, I think we will want to consider this here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you have covered this case here: #123 (comment)

Does Address.protocol specify 0? If so, fetch actor with ID = Address.payload, return BLS or ECDSA. <--this method needs to be specified in actors.md and should distinguish between BLS and ECDSA signatures.

signatures.md Outdated
Output: "Aggregate" or "INVALID"

1. If SignedMessage.Address[i].protocol != {0 OR 3} for all i output "INVALID" and stop
2. If len(SignedMessage.Msgs) > 1 output "Aggregate" else output "INVALID"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the case len(SignedMessage.Msgs) == 1 indicate the the SignedMessage contains a ECDSA signature?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the case of no addresses and one message? Is an aggregate of one explicitly invalid? While that's what the pseudocode implied, explicit clarification would help.

What about the case of multiple addresses and multiple messages? I'm guessing this means an aggregate (but should it check the lengths are equal)? An enumeration of all possible cases of {1, many}-messages ⨯ {0, many}-addresses would help (perhaps in the prose above).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frrist: yes. ECDSA signatures can't be aggregated in this scheme so if we encounter them we should error. Maybe "INVALID" is not the right wording. We should probably specify input validation. Alex alludes to this below.

@anorth: Good point. Request someone from go-filecoin to work on this (input validation).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added note about ECDSA not being aggregatable in the "Aggregating Signed Messages" section

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love us to work on input validation, but we need you to specify what inputs should be valid. Please enumerate all combinations that are semantically valid and explicitly state that other combinations are meaningless.

signatures.md Outdated
}
```

### Signed Message

This is the container for a signature that combines a message with an address and signature.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by the plurality of addresses and messages in the structure given this description.

I understand the use case for multiple addresses, but what is the case for multiple different messages? This seems like redundant data in the case of multiple signers of an identical message.

A brief outline of use cases and capabilities at the top of this doc would help greatly if my understanding of the motivations and context is lacking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm note sure I quite understand but I've reworked the description. Agree it is very confusing. Will push. Let me know if that answers your questions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't understand why there are multiple messages in the container. The comment uses the singular "a message and an address" which disagrees with the code directly below. Please clarify the intended role of a SignedMessage. E.g. you could write:

A container for one or multiple messages and an aggregation of the signatures of those messages by corresponding addresses. In the case of a single message and address, the signature is a vanilla signature, not an aggregate. In the case of multiple messages, the signature is assumed to be an aggregate. See *Determining signature type* below for more detail.

But I don't know whether that is in fact correct or complete.


}
If there is more then one message in `SignedMessage.Msgs` then the `SignedMessage` is assumed to be a signature aggregate. If `Address` is empty then `Verify` will assume the `SignedMessage` is a signature aggregate. The procedure below uses `len()` to indicate a function that returns the number of elements in an array.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a practical matter, I recommend an explicit representation of the "type" of signed message rather than assuming from the number of messages and/or addresses. An explicit byte identifying the semantics will simplify future changes and make code easier to understand and more likely to be correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@whyrusleeping: ^ . It would make things easier to understand but would cost a bit or two on-chain. What do you think?

signatures.md Outdated
Output: "Aggregate" or "INVALID"

1. If SignedMessage.Address[i].protocol != {0 OR 3} for all i output "INVALID" and stop
2. If len(SignedMessage.Msgs) > 1 output "Aggregate" else output "INVALID"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the case of no addresses and one message? Is an aggregate of one explicitly invalid? While that's what the pseudocode implied, explicit clarification would help.

What about the case of multiple addresses and multiple messages? I'm guessing this means an aggregate (but should it check the lengths are equal)? An enumeration of all possible cases of {1, many}-messages ⨯ {0, many}-addresses would help (perhaps in the prose above).

bvohaska added 2 commits April 9, 2019 12:27
…hods for signature interface. Added note indicating ECDSA signatures are not aggregatable.
signatures.md Outdated Show resolved Hide resolved
@@ -107,7 +107,7 @@ Chain selection is a crucial component of how the Filecoin blockchain works. Eve

### Block Validation

The block structure and serialization is detailed in [the datastructures spec](data-structures.md#block). Check there for details on fields and types.
The block structure and serialization is detailed in [the datastructures spec](data-structures.md#block). Check there for details on fields and types. All references to `VaidateSignature` must implement the `Signature` interface found [here](https://github.com/filecoin-project/specs/blob/master/signatures.md).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addition is confusing. Why not just say that signature validation is covered in detail in the signature spec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point. I've been mulling over how to best represent that ValidateSignature must use the verification method in signatures.md. The current phrasing is confusing b/c it should read: "Block implements the Signature interface" and ValidateSignature --> Block.Verify(SignedMessage_Block, PublicKey). in this case, the internal block messages would be represented as a single value (hashed), SignatureBytes would be the actual signature of the message and Address would be the address of the block proposer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need a place that implements verification of the aggregated signatures, e.g. a method like VerfiyAggregates([]Message, SignatureBytes) bool for use inside the block validation.

@bvohaska
Copy link
Contributor Author

@anorth, @whyrusleeping: This PR is suffering a bit of scope creep. Let's close it out and push to master. I'd like to ship this so we can move a bit faster. We can create a new PR for other concerns captured in this PR. I believe most of the concerns are captured in this GH issue.

@whyrusleeping
Copy link
Member

@bvohaska I don't think its scope creeping. The scope of signature aggregation should be every change needed to the protocol to support it. I don't want to merge a partial spec change which would leave the spec in a weird place here.

Copy link
Member

@anorth anorth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have unresolved two questions about the specific semantics of the SignedMessage structure.

I would also like an explicit call, perhaps from @whyrusleeping, on an explicit type identifier to distinguish possible interpretations. If that call is "no", then the exhaustive enumeration of valid and invalid combinations is important to understanding the avenues open for change in the future.

Beyond that, this LGTM, but I expect my approval isn't sufficient to merge.

signatures.md Outdated
}
```

### Signed Message

This is the container for a signature that combines a message with an address and signature.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't understand why there are multiple messages in the container. The comment uses the singular "a message and an address" which disagrees with the code directly below. Please clarify the intended role of a SignedMessage. E.g. you could write:

A container for one or multiple messages and an aggregation of the signatures of those messages by corresponding addresses. In the case of a single message and address, the signature is a vanilla signature, not an aggregate. In the case of multiple messages, the signature is assumed to be an aggregate. See *Determining signature type* below for more detail.

But I don't know whether that is in fact correct or complete.

signatures.md Outdated
Output: "Aggregate" or "INVALID"

1. If SignedMessage.Address[i].protocol != {0 OR 3} for all i output "INVALID" and stop
2. If len(SignedMessage.Msgs) > 1 output "Aggregate" else output "INVALID"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love us to work on input validation, but we need you to specify what inputs should be valid. Please enumerate all combinations that are semantically valid and explicitly state that other combinations are meaningless.

@mhammersley
Copy link

suggestion: have a set of diagrams describing the constituent elements as well as the process flow with concise, precise definitions

…ge to better comply with current understanding. Moved SignedMessage to data-structures.md; updated Ticket definition to comply with SignedMessage.
@bvohaska
Copy link
Contributor Author

Moved content of this comment to the tracking issue here

GasPrice Integer
GasLimit Integer

GasPrice Integer
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@whyrusleeping, @dignifiedquire: is there a canonical description for Integer? In other words, what exactly do we mean by integer here? Is this a 32 byte binary quantity? Perhaps it's a bigInt in form LEB128?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know the size of these Integers?

type Ticket struct {

// The VDF Result is derived from the prior ticket in the ticket chain
VDFResult BigInteger
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sternhenri, @ZenGround0: Do we have a language-independent description of BigInteger here? What is the binary representation? Maybe we could point to a spec that defines this for us.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is what LEB128 is for

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a size for these bigInts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are variably length sized, to support arbitrary numbers. But if you have a max range you want to represent then I can tell you the size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Someone will have to update the spec comments to expound on this. As for the typing, we are using inconsistent type nomenclature for big integers. It would be nice to go through and standardize these. So far I've seen Integer, BigInteger, BigInt; they no doubt mean the same thing --> LEB128 encoded integers of arbitrary size but we should specifically call that out here.

If the spec owners acknowledge that this is what they mean when they write an element from the list above, I'll go ahead and change it. Don't want to misinterpret the authors intent.


// MessageReceipts is a set of receipts matching to the sending of the `Messages`.
// TODO: should be the same type of merkletree-list thing that the messages are
// TODO: should be the same type of merkletree-list thing that the messages are
MessageReceipts []MessageReceipt
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@whyrusleeping: what are MessageReceipts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are defined below and store the result of applying the message

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the struct definition. Do we have any exposition as to why we need them? Given that they are an on-chain quantity, I would claim that it's important to declare exactly why we have them. This would be the best place to put that explanation.


// ElectionProof is a signature over the final ticket that proves this miner
// is the leader at this round
ElectionProof SignatureBytes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it defined somewhere what kind of signature this is cc @sternhenri

Copy link
Contributor Author

@bvohaska bvohaska Apr 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ I took a guess at this. Previously, it read Signature. Will need @sternhenri to verify this is a BLS signature.

## Block

A block represents an individual point in time that the network may achieve consensus on. It contains (via merkle links) the full state of the system, references to the previous state, and some notion of a 'weight' for deciding which block is the 'best'.

```go
// Block is a block in the blockchain.
type Block struct {

// Miner is the address of the miner actor that mined this block.
Miner Address

// Tickets are the winning ticket that were submitted with this block.
Tickets []Ticket
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we aggregate the signatures on the tickets as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the EC spec can be updated to support it, I don't see why not. We'll need to make sure that the EC spec is using SignedMessages and the Signature interface.

^ thoughts @sternhenri?


// BLSMessages is the set of messages with associated BLS signatures contained
// in BLSSignatureAggregate.
BLSMessages []Message
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general I like this structure, but we are now unable to present an ordering of messages in the form of

- bls message
- ecdsa message
- bls message

In regards to execution order.

I would argue this is fine, and miners are simply asked to process these not together, but first one kind, then the other kind. But this is an explicit design decision that might have other implications.

@bvohaska
Copy link
Contributor Author

bvohaska commented Apr 22, 2019

@whyrusleeping: from mining.md (https://github.com/filecoin-project/specs/blob/master/mining.md#block-validation), it doesn't look like on-chain message signatures are validated during block validation. Maybe I'm missing something?

@pooja pooja mentioned this pull request Jul 3, 2019
19 tasks
@pooja pooja mentioned this pull request Jul 30, 2019
18 tasks
@pooja pooja mentioned this pull request Aug 27, 2019
22 tasks
@sternhenri
Copy link
Contributor

outdated

@sternhenri sternhenri closed this Nov 5, 2019
@nicola nicola deleted the feat/sig-aggregation branch November 29, 2019 02:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants