TBD54566975 / web5-go

Apache License 2.0
10 stars 6 forks source link

[WIP] DID Signer #35

Closed mistermoe closed 6 months ago

mistermoe commented 6 months ago

[!WARNING] 🚧 WIP 🚧

Goals

[!IMPORTANT] the changes in this PR provide quite a bit more optionality and defensive checks (specifically wrt verification method selection) than what's currently on main

Current Usage

No Options (aka default signer)

func main() {
    bearerDID, err := didjwk.Create()
    if err != nil {
        panic(err)
    }

    sign, verificationMethod, err := bearerDID.GetSigner(nil)
    if err != nil {
        panic(err)
    }

    payload := []byte("hi")
    signature, err := sign(payload)
    if err != nil {
        panic(err)
    }

    fmt.Printf("signature: %s\n", hex.EncodeToString(signature))

    legit, err := dsa.Verify(payload, signature, *verificationMethod.PublicKeyJwk)
    if err != nil {
        panic(err)
    }

    if !legit {
        panic("expected signature to be valid")
    }
}

With Options (signer using a key with a specific purpose)

func main() {
    bearerDID, err := didjwk.Create()
    if err != nil {
        panic(err)
    }

    sign, _, err := bearerDID.GetSigner(didcore.Purpose("authentication"))
    if err != nil {
        panic(err)
    }

    payload := []byte("hi")
    signature, err := sign(payload)
    if err != nil {
        panic(err)
    }

    fmt.Printf("signature: %s\n", hex.EncodeToString(signature))
}

BearerDID.GetSigner() Explanation

GetSigner returns a sign method that can be used to sign a payload using a key associated to the BearerDID. This function also returns the verification method needed to verify the signature.

Returning the verification method allows the caller to provide the signature's recipient with a reference to the verification method needed to verify the payload. This is often done by including the verification method id either alongside the signature or as part of the header in the case of JSON Web Signatures.

The verifier can dereference the verification method id to obtain the public key needed to verify the signature. This function optionally takes a Verification Method selector that can be used to select a specific verification method from the DID Document if desired. If no selector is provided, the payload will be signed with the key associated to the first verification method in the DID Document.

The selector can either be a Verification Method ID or a Purpose. If a Purpose is provided, the first verification method in the DID Document that has the provided purpose will be used to sign the payload.

The returned signer is a function that takes a byte payload and returns a byte signature.

Concerns

The potential complexity introduced may outweigh the cognitive overhead required to maintain the code added in this PR.

Benefits

mistermoe commented 6 months ago

Incase anyone needs a brain reset after looking through all of this:

What made me laugh is "FART" in full caps on the sign in the back

alecthomas commented 6 months ago

IMO the VMSelector actually reads quite well.