From 1ca6d84301b37b720bcc91eeaca340be83108339 Mon Sep 17 00:00:00 2001 From: Prad N Date: Mon, 2 Jun 2025 14:08:04 -0700 Subject: [PATCH] feat: introduce enclave signing and verification WASM modules --- .goreleaser.yaml | 2 +- cmd/enclave/Makefile | 13 ++++ cmd/enclave/main.go | 31 +++++++++ cmd/radar/Taskfile.yml | 23 ------- cmd/signer/.gitignore | 3 + cmd/signer/Makefile | 17 +++++ cmd/signer/go.sum | 44 +++++++++++++ cmd/signer/main.go | 45 +++++++++++++ cmd/verifier/Makefile | 17 +++++ cmd/verifier/go.sum | 44 +++++++++++++ cmd/verifier/main.go | 40 ++++++++++++ cmd/worker/Taskfile.yml | 23 ------- go.mod | 31 +++++++++ go.sum | 78 ++++++++++++++++++++-- pkg/authz/jwt.go | 83 ++++++++++++++++++++++++ pkg/authz/source.go | 126 ++++++++++++++++++++++++++++++++++++ pkg/authz/ucan.go | 92 ++++++++++++++++++++++++++ pkg/cflare/d1_bindings.go | 4 -- pkg/cflare/d1_connection.go | 4 -- pkg/cflare/kv_bindings.go | 4 -- pkg/cflare/kv_connection.go | 4 -- pkg/wasm/log.go | 1 + 22 files changed, 662 insertions(+), 67 deletions(-) create mode 100644 cmd/enclave/Makefile create mode 100644 cmd/enclave/main.go delete mode 100644 cmd/radar/Taskfile.yml create mode 100644 cmd/signer/.gitignore create mode 100644 cmd/signer/Makefile create mode 100644 cmd/signer/go.sum create mode 100644 cmd/signer/main.go create mode 100644 cmd/verifier/Makefile create mode 100644 cmd/verifier/go.sum create mode 100644 cmd/verifier/main.go delete mode 100644 cmd/worker/Taskfile.yml create mode 100644 pkg/authz/jwt.go create mode 100644 pkg/authz/source.go create mode 100644 pkg/authz/ucan.go delete mode 100644 pkg/cflare/d1_bindings.go delete mode 100644 pkg/cflare/d1_connection.go delete mode 100644 pkg/cflare/kv_bindings.go delete mode 100644 pkg/cflare/kv_connection.go create mode 100644 pkg/wasm/log.go diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 6ac05f4..3a31f7f 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,7 +1,6 @@ # yaml-language-server: $schema=https://goreleaser.com/static/schema.json # vim: set ts=2 sw=2 tw=0 fo=cnqoj version: 2 - before: hooks: - go mod tidy @@ -25,6 +24,7 @@ archives: {{- else if eq .Arch "386" }}i386 {{- else }}{{ .Arch }}{{ end }} {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives format_overrides: - goos: windows formats: [zip] diff --git a/cmd/enclave/Makefile b/cmd/enclave/Makefile new file mode 100644 index 0000000..d37e2a0 --- /dev/null +++ b/cmd/enclave/Makefile @@ -0,0 +1,13 @@ +.PHONY: build test + +all: build publish + +build: tidy + @gum spin --show-error --title "[ENCLAVE] Running go build..." -- sh -c "GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o enclave.wasm" + @gum log --level info --time kitchen "[ENCLAVE] Completed go build successfully." + +publish: build + @gum spin --show-error --title "[ENCLAVE] Uploading enclave.wasm to r2" -- sh -c "rclone copy ./enclave.wasm r2:cdn/bin/" + @gum log --level info --time kitchen "[ENCLAVE] Completed rclone upload successfully." + + diff --git a/cmd/enclave/main.go b/cmd/enclave/main.go new file mode 100644 index 0000000..465ea69 --- /dev/null +++ b/cmd/enclave/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/extism/go-pdk" + "github.com/sonr-io/crypto/mpc" +) + +type GenerateResponse struct { + PubKeyHex string `json:"pub_key_hex"` + Enclave *mpc.EnclaveData `json:"enclave"` +} + +func main() { + generate() +} + +//go:wasmexport generate +func generate() int32 { + e, err := mpc.NewEnclave() + if err != nil { + pdk.SetError(err) + return 1 + } + pdk.Log(pdk.LogInfo, "Generated enclave successfully") + resp := &GenerateResponse{ + PubKeyHex: e.PubKeyHex(), + Enclave: e.GetData(), + } + pdk.OutputJSON(resp) + return 0 +} diff --git a/cmd/radar/Taskfile.yml b/cmd/radar/Taskfile.yml deleted file mode 100644 index ddfd51f..0000000 --- a/cmd/radar/Taskfile.yml +++ /dev/null @@ -1,23 +0,0 @@ -# yaml-language-server: $schema=https://taskfile.dev/schema.json -version: "3" -vars: - GIT_ROOT: - sh: git rev-parse --show-toplevel - -tasks: - worker: - dir: "{{.GIT_ROOT}}/cmd/worker" - cmd: make build - sources: - - "main.go" - generates: - - build/app.wasm - - radar: - dir: "{{.GIT_ROOT}}/cmd/radar" - cmd: make build - sources: - - "main.go" - generates: - - build/app.wasm - diff --git a/cmd/signer/.gitignore b/cmd/signer/.gitignore new file mode 100644 index 0000000..d01d19b --- /dev/null +++ b/cmd/signer/.gitignore @@ -0,0 +1,3 @@ +*.wasm +dist +.tmp diff --git a/cmd/signer/Makefile b/cmd/signer/Makefile new file mode 100644 index 0000000..49afef7 --- /dev/null +++ b/cmd/signer/Makefile @@ -0,0 +1,17 @@ +.PHONY: build + +all: build publish + +tidy: + @gum spin --show-error --title "[SIGNER] Running go mod tidy..." -- sh -c "go mod tidy" + @gum log --level info --time kitchen "[SIGNER] Completed go mod tidy successfully." + +build: tidy + @gum spin --show-error --title "[SIGNER] Running tinygo build..." -- sh -c "tinygo build -o signer.wasm -target wasip1 -buildmode=c-shared main.go" + @gum log --level info --time kitchen "[SIGNER] Completed tinygo build successfully." + +publish: build + @gum spin --show-error --title "[SIGNER] Uploading signer.wasm to r2" -- sh -c "rclone copy ./signer.wasm r2:cdn/bin/" + @gum log --level info --time kitchen "[SIGNER] Completed rclone upload successfully." + + diff --git a/cmd/signer/go.sum b/cmd/signer/go.sum new file mode 100644 index 0000000..f1b5e9d --- /dev/null +++ b/cmd/signer/go.sum @@ -0,0 +1,44 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/consensys/bavard v0.1.27 h1:j6hKUrGAy/H+gpNrpLU3I26n1yc+VMGmd6ID5+gAhOs= +github.com/consensys/bavard v0.1.27/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.16.0 h1:8Dl4eYmUWK9WmlP1Bj6je688gBRJCJbT8Mw4KoTAawo= +github.com/consensys/gnark-crypto v0.16.0/go.mod h1:Ke3j06ndtPTVvo++PhGNgvm+lgpLvzbcE2MqljY7diU= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 h1:I6KUy4CI6hHjqnyJLNCEi7YHVMkwwtfSr2k9splgdSM= +github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564/go.mod h1:yekO+3ZShy19S+bsmnERmznGy9Rfg6dWWWpiGJjNAz8= +github.com/extism/go-pdk v1.1.3 h1:hfViMPWrqjN6u67cIYRALZTZLk/enSPpNKa+rZ9X2SQ= +github.com/extism/go-pdk v1.1.3/go.mod h1:Gz+LIU/YCKnKXhgge8yo5Yu1F/lbv7KtKFkiCSzW/P4= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/cmd/signer/main.go b/cmd/signer/main.go new file mode 100644 index 0000000..45bc423 --- /dev/null +++ b/cmd/signer/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "github.com/extism/go-pdk" + "github.com/sonr-io/crypto/mpc" +) + +type SignRequest struct { + Message []byte `json:"message"` + Enclave []byte `json:"enclave"` +} + +type SignResponse struct { + Signature []byte `json:"signature"` +} + +func main() { + sign() +} + +//go:wasmexport sign +func sign() int32 { + req := SignRequest{} + err := pdk.InputJSON(req) + if err != nil { + pdk.SetError(err) + return 1 + } + pdk.Log(pdk.LogInfo, "Deserialized request successfully") + e, err := mpc.ImportEnclave(mpc.WithEnclaveJSON(req.Enclave)) + if err != nil { + pdk.SetError(err) + return 1 + } + pdk.Log(pdk.LogInfo, "Imported enclave successfully") + sig, err := e.Sign(req.Message) + if err != nil { + pdk.SetError(err) + return 1 + } + pdk.Log(pdk.LogInfo, "Signature successful") + sigJSON := SignResponse{Signature: sig} + pdk.OutputJSON(sigJSON) + return 0 +} diff --git a/cmd/verifier/Makefile b/cmd/verifier/Makefile new file mode 100644 index 0000000..41cd9f3 --- /dev/null +++ b/cmd/verifier/Makefile @@ -0,0 +1,17 @@ +.PHONY: build + +all: build publish + +tidy: + @gum spin --show-error --title "[VERIFIER] Running go mod tidy..." -- sh -c "go mod tidy" + @gum log --level info --time kitchen "[VERIFIER] Completed go mod tidy successfully." + +build: tidy + @gum spin --show-error --title "[VERIFIER] Running tinygo build..." -- sh -c "tinygo build -o verifier.wasm -target wasip1 -buildmode=c-shared main.go" + @gum log --level info --time kitchen "[VERIFIER] Completed tinygo build successfully." + +publish: build + @gum spin --show-error --title "[VERIFIER] Uploading verifier.wasm to r2" -- sh -c "rclone copy ./verifier.wasm r2:cdn/bin/" + @gum log --level info --time kitchen "[VERIFIER] Completed rclone upload successfully." + + diff --git a/cmd/verifier/go.sum b/cmd/verifier/go.sum new file mode 100644 index 0000000..f1b5e9d --- /dev/null +++ b/cmd/verifier/go.sum @@ -0,0 +1,44 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/consensys/bavard v0.1.27 h1:j6hKUrGAy/H+gpNrpLU3I26n1yc+VMGmd6ID5+gAhOs= +github.com/consensys/bavard v0.1.27/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.16.0 h1:8Dl4eYmUWK9WmlP1Bj6je688gBRJCJbT8Mw4KoTAawo= +github.com/consensys/gnark-crypto v0.16.0/go.mod h1:Ke3j06ndtPTVvo++PhGNgvm+lgpLvzbcE2MqljY7diU= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 h1:I6KUy4CI6hHjqnyJLNCEi7YHVMkwwtfSr2k9splgdSM= +github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564/go.mod h1:yekO+3ZShy19S+bsmnERmznGy9Rfg6dWWWpiGJjNAz8= +github.com/extism/go-pdk v1.1.3 h1:hfViMPWrqjN6u67cIYRALZTZLk/enSPpNKa+rZ9X2SQ= +github.com/extism/go-pdk v1.1.3/go.mod h1:Gz+LIU/YCKnKXhgge8yo5Yu1F/lbv7KtKFkiCSzW/P4= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/cmd/verifier/main.go b/cmd/verifier/main.go new file mode 100644 index 0000000..bf18323 --- /dev/null +++ b/cmd/verifier/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "github.com/extism/go-pdk" + "github.com/sonr-io/crypto/mpc" +) + +type VerifyRequest struct { + PubKey []byte `json:"pub_key"` + Message []byte `json:"message"` + Sig []byte `json:"sig"` +} + +type VerifyResponse struct { + Valid bool `json:"valid"` +} + +func main() { + verify() +} + +//go:wasmexport verify +func verify() int32 { + req := VerifyRequest{} + err := pdk.InputJSON(req) + if err != nil { + pdk.Log(pdk.LogError, err.Error()) + return 1 + } + pdk.Log(pdk.LogInfo, "Deserialized request successfully") + res := VerifyResponse{Valid: false} + valid, err := mpc.VerifyWithPubKey(req.PubKey, req.Message, req.Sig) + if err != nil { + pdk.SetError(err) + return 1 + } + res.Valid = valid + pdk.OutputJSON(res) + return 0 +} diff --git a/cmd/worker/Taskfile.yml b/cmd/worker/Taskfile.yml deleted file mode 100644 index ddfd51f..0000000 --- a/cmd/worker/Taskfile.yml +++ /dev/null @@ -1,23 +0,0 @@ -# yaml-language-server: $schema=https://taskfile.dev/schema.json -version: "3" -vars: - GIT_ROOT: - sh: git rev-parse --show-toplevel - -tasks: - worker: - dir: "{{.GIT_ROOT}}/cmd/worker" - cmd: make build - sources: - - "main.go" - generates: - - build/app.wasm - - radar: - dir: "{{.GIT_ROOT}}/cmd/radar" - cmd: make build - sources: - - "main.go" - generates: - - build/app.wasm - diff --git a/go.mod b/go.mod index be1f3f3..e712f23 100644 --- a/go.mod +++ b/go.mod @@ -4,19 +4,50 @@ go 1.24.2 require ( github.com/a-h/templ v0.3.857 + github.com/extism/go-pdk v1.1.3 + github.com/golang-jwt/jwt v3.2.2+incompatible github.com/labstack/echo/v4 v4.13.3 github.com/segmentio/ksuid v1.0.4 + github.com/sonr-io/crypto v0.0.0-00010101000000-000000000000 github.com/syumai/workers v0.30.2 + lukechampine.com/blake3 v1.4.1 ) +replace github.com/sonr-io/crypto => ../crypto/ + require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/bwesterb/go-ristretto v1.2.3 // indirect + github.com/consensys/bavard v0.1.27 // indirect + github.com/consensys/gnark-crypto v0.16.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/ipfs/go-cid v0.5.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/labstack/gommon v0.4.2 // indirect + github.com/libp2p/go-libp2p v0.41.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect golang.org/x/crypto v0.36.0 // indirect golang.org/x/net v0.37.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index a336ee3..957fda7 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,84 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/a-h/templ v0.3.857 h1:6EqcJuGZW4OL+2iZ3MD+NnIcG7nGkaQeF2Zq5kf9ZGg= github.com/a-h/templ v0.3.857/go.mod h1:qhrhAkRFubE7khxLZHsBFHfX+gWwVNKbzKeF9GlPV4M= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/consensys/bavard v0.1.27 h1:j6hKUrGAy/H+gpNrpLU3I26n1yc+VMGmd6ID5+gAhOs= +github.com/consensys/bavard v0.1.27/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.16.0 h1:8Dl4eYmUWK9WmlP1Bj6je688gBRJCJbT8Mw4KoTAawo= +github.com/consensys/gnark-crypto v0.16.0/go.mod h1:Ke3j06ndtPTVvo++PhGNgvm+lgpLvzbcE2MqljY7diU= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= +github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 h1:I6KUy4CI6hHjqnyJLNCEi7YHVMkwwtfSr2k9splgdSM= +github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564/go.mod h1:yekO+3ZShy19S+bsmnERmznGy9Rfg6dWWWpiGJjNAz8= +github.com/extism/go-pdk v1.1.3 h1:hfViMPWrqjN6u67cIYRALZTZLk/enSPpNKa+rZ9X2SQ= +github.com/extism/go-pdk v1.1.3/go.mod h1:Gz+LIU/YCKnKXhgge8yo5Yu1F/lbv7KtKFkiCSzW/P4= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg= +github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p v0.41.0 h1:JRaD39dqf/tBBGapJ0T38N73vOaDCsWgcx3mE6HgXWk= +github.com/libp2p/go-libp2p v0.41.0/go.mod h1:Be8QYqC4JW6Xq8buukNeoZJjyT1XUDcGoIooCHm1ye4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.15.0 h1:zB/HeaI/apcZiTDwhY5YqMvNVl/oQYvs3XySU+qeAVo= +github.com/multiformats/go-multiaddr v0.15.0/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syumai/workers v0.30.2 h1:ZefPdAoXBsw87Bxy1LTAR6Pm9Gbxw/iM7DNraPSput0= @@ -27,6 +89,8 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -35,5 +99,11 @@ golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= +lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/pkg/authz/jwt.go b/pkg/authz/jwt.go new file mode 100644 index 0000000..7216e61 --- /dev/null +++ b/pkg/authz/jwt.go @@ -0,0 +1,83 @@ +package authz + +import ( + "crypto/sha256" + + "github.com/golang-jwt/jwt" +) + +// MPCSigningMethod implements the SigningMethod interface for MPC-based signing +type MPCSigningMethod struct { + Name string + ks ucanKeyshare +} + +// NewJWTSigningMethod creates a new MPC signing method with the given keyshare source +func NewJWTSigningMethod(name string, ks ucanKeyshare) *MPCSigningMethod { + return &MPCSigningMethod{ + Name: name, + ks: ks, + } +} + +// Alg returns the signing method's name +func (m *MPCSigningMethod) Alg() string { + return m.Name +} + +// Verify verifies the signature using the MPC public key +func (m *MPCSigningMethod) Verify(signingString, signature string, key any) error { + // // Decode the signature + // sig, err := base64.RawURLEncoding.DecodeString(signature) + // if err != nil { + // return err + // } + // + // // Hash the signing string + // hasher := sha256.New() + // hasher.Write([]byte(signingString)) + // digest := hasher.Sum(nil) + // valid, err := m.ks.valShare.PublicKey().Verify(digest, sig) + // if !valid || err != nil { + // return fmt.Errorf("invalid signature") + // } + return nil +} + +// Sign signs the data using MPC +func (m *MPCSigningMethod) Sign(signingString string, key any) (string, error) { + // Hash the signing string + hasher := sha256.New() + hasher.Write([]byte(signingString)) + // digest := hasher.Sum(nil) + // + // // Create signing functions + // signFunc, err := m.ks.userShare.SignFunc(digest) + // if err != nil { + // return "", fmt.Errorf("failed to create sign function: %w", err) + // } + // + // valSignFunc, err := m.ks.valShare.SignFunc(digest) + // if err != nil { + // return "", fmt.Errorf("failed to create validator sign function: %w", err) + // } + + // // Run the signing protocol + // sig, err := mpc.ExecuteSigning(valSignFunc, signFunc) + // if err != nil { + // return "", fmt.Errorf("failed to run sign protocol: %w", err) + // } + + // Encode the signature + // encoded := base64.RawURLEncoding.EncodeToString(sig) + return "", nil +} + +func init() { + // Register the MPC signing method + jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod { + return &MPCSigningMethod{ + Name: "MPC256", + } + }) +} diff --git a/pkg/authz/source.go b/pkg/authz/source.go new file mode 100644 index 0000000..74fe717 --- /dev/null +++ b/pkg/authz/source.go @@ -0,0 +1,126 @@ +package authz + +import ( + "context" + "fmt" + "time" + + "github.com/sonr-io/crypto/keys" + "github.com/sonr-io/crypto/ucan" + "lukechampine.com/blake3" +) + +type KeyshareSource interface { + ucan.Source + + Address() string + Issuer() string + ChainCode() ([]byte, error) + OriginToken() (*Token, error) + SignData(data []byte) ([]byte, error) + VerifyData(data []byte, sig []byte) (bool, error) + UCANParser() *ucan.TokenParser +} + +// func NewSource(ks mpc.KeyEnclave) (KeyshareSource, error) { +// iss, addr, err := getIssuerDID(val.PublicKey()) +// if err != nil { +// return nil, err +// } +// +// return ucanKeyshare{ +// issuerDID: iss, +// addr: addr, +// }, nil +// } +// +// Address returns the address of the keyshare +func (k ucanKeyshare) Address() string { + return k.addr +} + +// Issuer returns the DID of the issuer of the keyshare +func (k ucanKeyshare) Issuer() string { + return k.issuerDID +} + +// ChainCode returns the chain code of the keyshare +func (k ucanKeyshare) ChainCode() ([]byte, error) { + sig, err := k.SignData([]byte(k.addr)) + if err != nil { + return nil, err + } + hash := blake3.Sum256(sig) + // Return the first 32 bytes of the hash + return hash[:32], nil +} + +// DefaultOriginToken returns a default token with the keyshare's issuer as the audience +func (k ucanKeyshare) OriginToken() (*Token, error) { + // att := ucan.NewSmartAccount(k.addr) + zero := time.Time{} + // return k.NewOriginToken(k.issuerDID, att, nil, zero, zero) + return k.newToken(k.issuerDID, nil, nil, nil, zero, zero) +} + +func (k ucanKeyshare) SignData(data []byte) ([]byte, error) { + // // Create signing functions + // signFunc, err := k.userShare.SignFunc(data) + // if err != nil { + // return nil, fmt.Errorf("failed to create sign function: %w", err) + // } + // + // valSignFunc, err := k.valShare.SignFunc(data) + // if err != nil { + // return nil, fmt.Errorf("failed to create validator sign function: %w", err) + // } + + // Run the signing protocol + // return mpc.ExecuteSigning(valSignFunc, signFunc) + return nil, nil +} + +func (k ucanKeyshare) VerifyData(data []byte, sig []byte) (bool, error) { + return false, nil + // return k.valShare.PublicKey().Verify(data, sig) +} + +// TokenParser returns a token parser that can be used to parse tokens +func (k ucanKeyshare) UCANParser() *ucan.TokenParser { + caps := ucan.AccountPermissions.GetCapabilities() + ac := func(m map[string]any) (ucan.Attenuation, error) { + var ( + cap string + rsc ucan.Resource + ) + for key, vali := range m { + val, ok := vali.(string) + if !ok { + return ucan.Attenuation{}, fmt.Errorf(`expected attenuation value to be a string`) + } + + if key == ucan.CapKey { + cap = val + } else { + } + } + + return ucan.Attenuation{ + Rsc: rsc, + Cap: caps.Cap(cap), + }, nil + } + + store := ucan.NewMemTokenStore() + return ucan.NewTokenParser(ac, customDIDPubKeyResolver{}, store.(ucan.CIDBytesResolver)) +} + +// customDIDPubKeyResolver implements the DIDPubKeyResolver interface without +// any network backing. Works if the key string given contains the public key +// itself +type customDIDPubKeyResolver struct{} + +// ResolveDIDKey extracts a public key from a did:key string +func (customDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (keys.DID, error) { + return keys.Parse(didStr) +} diff --git a/pkg/authz/ucan.go b/pkg/authz/ucan.go new file mode 100644 index 0000000..56493e7 --- /dev/null +++ b/pkg/authz/ucan.go @@ -0,0 +1,92 @@ +package authz + +import ( + "fmt" + "time" + + "github.com/golang-jwt/jwt" + "github.com/sonr-io/crypto/ucan" +) + +type ( + Token = ucan.Token + Claims = ucan.Claims + Proof = ucan.Proof + + Attenuations = ucan.Attenuations + Fact = ucan.Fact +) + +var ( + UCANVersion = ucan.UCANVersion + UCANVersionKey = ucan.UCANVersionKey + PrfKey = ucan.PrfKey + FctKey = ucan.FctKey + AttKey = ucan.AttKey + CapKey = ucan.CapKey +) + +type ucanKeyshare struct { + addr string + issuerDID string +} + +func (k ucanKeyshare) NewOriginToken(audienceDID string, att Attenuations, fct []Fact, notBefore, expires time.Time) (*ucan.Token, error) { + return k.newToken(audienceDID, nil, att, fct, notBefore, expires) +} + +func (k ucanKeyshare) NewAttenuatedToken(parent *Token, audienceDID string, att ucan.Attenuations, fct []ucan.Fact, nbf, exp time.Time) (*Token, error) { + if !parent.Attenuations.Contains(att) { + return nil, fmt.Errorf("scope of ucan attenuations must be less than it's parent") + } + return k.newToken(audienceDID, append(parent.Proofs, Proof(parent.Raw)), att, fct, nbf, exp) +} + +func (k ucanKeyshare) newToken(audienceDID string, prf []Proof, att Attenuations, fct []Fact, nbf, exp time.Time) (*ucan.Token, error) { + t := jwt.New(NewJWTSigningMethod("MPC256", k)) + + // if _, err := did.Parse(audienceDID); err != nil { + // return nil, fmt.Errorf("invalid audience DID: %w", err) + // } + + t.Header[UCANVersionKey] = UCANVersion + + var ( + nbfUnix int64 + expUnix int64 + ) + + if !nbf.IsZero() { + nbfUnix = nbf.Unix() + } + if !exp.IsZero() { + expUnix = exp.Unix() + } + + // set our claims + t.Claims = &Claims{ + StandardClaims: &jwt.StandardClaims{ + Issuer: k.issuerDID, + Audience: audienceDID, + NotBefore: nbfUnix, + // set the expire time + // see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4 + ExpiresAt: expUnix, + }, + Attenuations: att, + Facts: fct, + Proofs: prf, + } + + raw, err := t.SignedString(nil) + if err != nil { + return nil, err + } + + return &Token{ + Raw: raw, + Attenuations: att, + Facts: fct, + Proofs: prf, + }, nil +} diff --git a/pkg/cflare/d1_bindings.go b/pkg/cflare/d1_bindings.go deleted file mode 100644 index 2c4e472..0000000 --- a/pkg/cflare/d1_bindings.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:build js && wasm -// +build js,wasm - -package cflare diff --git a/pkg/cflare/d1_connection.go b/pkg/cflare/d1_connection.go deleted file mode 100644 index 2c4e472..0000000 --- a/pkg/cflare/d1_connection.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:build js && wasm -// +build js,wasm - -package cflare diff --git a/pkg/cflare/kv_bindings.go b/pkg/cflare/kv_bindings.go deleted file mode 100644 index 2c4e472..0000000 --- a/pkg/cflare/kv_bindings.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:build js && wasm -// +build js,wasm - -package cflare diff --git a/pkg/cflare/kv_connection.go b/pkg/cflare/kv_connection.go deleted file mode 100644 index 2c4e472..0000000 --- a/pkg/cflare/kv_connection.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:build js && wasm -// +build js,wasm - -package cflare diff --git a/pkg/wasm/log.go b/pkg/wasm/log.go new file mode 100644 index 0000000..955e5a9 --- /dev/null +++ b/pkg/wasm/log.go @@ -0,0 +1 @@ +package wasm