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

Adding support for multiple signatures #31

Open
bodymindarts opened this issue Jun 12, 2018 · 4 comments
Open

Adding support for multiple signatures #31

bodymindarts opened this issue Jun 12, 2018 · 4 comments

Comments

@bodymindarts
Copy link

bodymindarts commented Jun 12, 2018

I would like to document the required steps for making this library support multiple signatures as per the JWS standard

Support General JWS JSON Serialization Syntax

the schema is:

     {
      "payload":"<payload contents>",
      "signatures":[
       {"protected":"<integrity-protected header 1 contents>",
        "header":<non-integrity-protected header 1 contents>,
        "signature":"<signature 1 contents>"},
       ...
       {"protected":"<integrity-protected header N contents>",
        "header":<non-integrity-protected header N contents>,
        "signature":"<signature N contents>"}]
     }

Additional code

the current structure of the code is very much relying on the assumption of there being 1 signature. Instead of trying to add code to the existing classes I would add use-case specific classes and potentially if deemed useful extract / generalize the code to work for 1 or N sigs.

this would mean adding the following files:

src/multi-signer.js
src/multi-verifier.js

Payload structure

  • public_keys this is already an array in the current structure so no problems here.
  • iss this holds the address of the bucket which is the bitcoin address connected to the exposed public key(eg. did:btc-addr:1Bjw4R9q38f8NR6TPy64YDsHLqYgR5BvNa). There are multiple ways of deriving a multi sig address from a set of public keys. When represented as a P2SH address bip-0067 describes how to create a deterministic address. Potentially we may also want to support p2sh-p2wsh.
    How would we identify which address generation scheme should be used? ['p2pkh', 'p2sh', 'p2sh-p2swsh'] or since ps2h could mean a lot of other things than a multi-sig address perhaps: ['p2pkh', 'multi-sig', 'segwit-multi-sig']
    And under what key should this information be stored in the payload?
@kantai
Copy link
Member

kantai commented Jun 12, 2018

Good notes @bodymindarts -- but I think we'd want to continue to use the JWT standard rather than JWS. JWTs use three Base64-URL strings concatenated together with .s to convey the header, payload, signature respectively (see https://jwt.io/introduction/) -- so we'd need to convey all the signatures in the signature object -- which we can certainly do, we'd just need to use a different verification scheme (e.g., ES256K-P2SH or ES256K-MULTI).

The signature object, which is now just a single signature, would have to contain all the signatures (we would need some way to encode those, but that's easy enough). The verifier, however, would need to be passed the redeem script (or something of the like).

@bodymindarts
Copy link
Author

bodymindarts commented Jun 12, 2018

Good notes @bodymindarts -- but I think we'd want to continue to use the JWT standard rather than JWS. JWTs use three Base64-URL strings concatenated together with .s to convey the header, payload, signature respectively (see https://jwt.io/introduction/) -- so we'd need to convey all the signatures in the signature object -- which we can certainly do, we'd just need to use a different verification scheme (e.g., ES256K-P2SH or ES256K-MULTI).

Yeah I thought JWT was a superset of JWS / JWE but now I see that a JWS is only considered a JWT when serialized in its compact form. In that case the JWS standard for serializing multiple signatures won't help.
So instead you are suggesting to encode all signatures into the signature section of the JWT. How would this work? A base 64 encoded JSON array perhaps?

The signature object, which is now just a single signature, would have to contain all the signatures (we would need some way to encode those, but that's easy enough). The verifier, however, would need to be passed the redeem script (or something of the like).

As to the verifier needing the redeem script. If the verification scheme sufficiently identifies the type of signature (1 sig, multi-sig, segwit-multi-sig) then the verifier would be able to reconstruct the redeem script (with the help of bitcoinjs-lib) without it needing to be passed in. Alternatively where do you think the code that constructs the redeem script should live?

@kantai
Copy link
Member

kantai commented Jun 12, 2018

The redeem script cannot be constructed from the address alone. In bitcoin, the last part of the scriptSig reveals that redeem script. We could use the same encoding as bitcoin (and encode a scriptSig and a witness for p2shwh), and then the verifier would just be instantiated with a bitcoin scriptPubKey (or address) -- though in this case, the signers would be responsible for providing the redeemScript.

@bodymindarts
Copy link
Author

bodymindarts commented Jun 12, 2018

It can be constructed from the public keys (which obviously need to be provided, ie part of the payload)

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

No branches or pull requests

2 participants