-
Notifications
You must be signed in to change notification settings - Fork 14
Feature/longfellow zk/verification #327
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
base: main
Are you sure you want to change the base?
Changes from all commits
422b235
8019260
36d5fac
37998b8
c7967a7
c5eb177
95e2be9
4041f67
42779fc
abb019d
5651f6c
b614344
75da835
74e68c7
4e57281
e2a218c
74e7645
898d8a0
01e67fc
f1d21de
10c9c6e
3a94fa2
36bb5e4
ccbfbc2
ac05e7c
94078d9
f0cd17e
d7bf66a
972a024
4062431
3c4cac1
6880adc
cb2b8a0
aedc326
a8c5c94
82ec860
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -36,10 +36,14 @@ RESERVED_TAGS := latest testing demo dev | |||||
| # PKCS#11 requires CGO for hardware security module support. | ||||||
| PKCS11_TAG := pkcs11 | ||||||
|
|
||||||
| VC20_TAG := vc20 | ||||||
| ALL_TAGS := $(SAML_TAG),$(OIDCRP_TAG) | ||||||
| ZK_TAG := zk | ||||||
|
|
||||||
| # Service Build Configuration (service -> static/dynamic, tags) | ||||||
| # Format: service_name:cgo_mode:build_tags | ||||||
| BUILD_CONFIGS := \ | ||||||
| verifier:static: \ | ||||||
| verifier:dynamic:${ZK_TAG} \ | ||||||
|
||||||
| verifier:dynamic:${ZK_TAG} \ | |
| verifier:dynamic: \ |
Copilot
AI
Mar 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an extra space before $(ZK_TAG) in the -tags list. Go's -tags flag expects a clean comma-separated list; the space can lead to an invalid/ignored tag depending on parsing. Remove the space to ensure zk is actually enabled when running this target.
| go test -tags "$(SAML_TAG),$(OIDCRP_TAG),$(VC20_TAG),$(PKCS11_TAG), $(ZK_TAG)" -v ./... | |
| go test -tags "$(SAML_TAG),$(OIDCRP_TAG),$(VC20_TAG),$(PKCS11_TAG),$(ZK_TAG)" -v ./... |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| //go:build !zk | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| "vc/pkg/model" | ||
| ) | ||
|
|
||
| func setupZK(cfg *model.Cfg) error { | ||
| return nil | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,26 @@ | ||||||||||||||||||||||||||||||||
| //go:build zk | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| package main | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||
| "proofs/server/v2/zk" | ||||||||||||||||||||||||||||||||
| "vc/pkg/model" | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| func setupZK(cfg *model.Cfg) error { | ||||||||||||||||||||||||||||||||
| if cfg.Verifier == nil || cfg.Verifier.ZK.CircuitsPath == "" || cfg.Verifier.ZK.CACertsPath == "" { | ||||||||||||||||||||||||||||||||
| return fmt.Errorf("ZK build requires circuits_path and cacerts_path in config") | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| zk.LoadCircuits(cfg.Verifier.ZK.CircuitsPath) | ||||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+16
|
||||||||||||||||||||||||||||||||
| if cfg.Verifier == nil || cfg.Verifier.ZK.CircuitsPath == "" || cfg.Verifier.ZK.CACertsPath == "" { | |
| return fmt.Errorf("ZK build requires circuits_path and cacerts_path in config") | |
| } | |
| zk.LoadCircuits(cfg.Verifier.ZK.CircuitsPath) | |
| if cfg.Verifier == nil || cfg.Verifier.ZK.CircuitsPath == "" || cfg.Verifier.ZK.CACertsPath == "" || cfg.Verifier.ZK.LibPath == "" { | |
| return fmt.Errorf("ZK build requires circuits_path, cacerts_path, and lib_path in config") | |
| } | |
| if err := os.Setenv("LD_LIBRARY_PATH", cfg.Verifier.ZK.LibPath); err != nil { | |
| return fmt.Errorf("could not set ZK library path: %w", err) | |
| } | |
| if err := zk.LoadCircuits(cfg.Verifier.ZK.CircuitsPath); err != nil { | |
| return fmt.Errorf("could not load ZK circuits: %w", err) | |
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -88,6 +88,11 @@ common: | |||||
| auth_scopes: ["pid_1_5", "pid_1_8", "eduid"] | ||||||
| auth_claims: ["given_name", "birthdate", "family_name"] | ||||||
| format: "dc+sd-jwt" | ||||||
| mdl_pid: | ||||||
| vct: "urn:eudi:pid:1" | ||||||
| vctm_file_path: "/metadata/vctm_pid_arf_1_5.json" # Or your mdoc metadata | ||||||
| auth_method: "basic" | ||||||
| format: "mso_mdoc" | ||||||
|
|
||||||
| kafka: | ||||||
| enable: false | ||||||
|
|
@@ -96,16 +101,18 @@ kafka: | |||||
| - "kafka1:9092" | ||||||
|
|
||||||
| issuer: | ||||||
| issuer_url: "http://apigw.vc.docker:8080" | ||||||
| identifier: "https://issuer.sunet.se" | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. identifier is not used anymore. |
||||||
| wallet_url: "" | ||||||
| issuer_url: "http://apigw.vc.docker:8080" | ||||||
| signing_key_path: "/pki/signing_ec_private.pem" | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use key_config, it has capability to use pkcs11 as well as crypto material on disk. |
||||||
| api_server: | ||||||
| addr: :8080 | ||||||
| grpc_server: | ||||||
| addr: issuer.vc.docker:8090 | ||||||
| registry_client: | ||||||
| addr: registry.vc.docker:8090 | ||||||
| audit_log: | ||||||
| enable: false | ||||||
| enabled: false | ||||||
|
||||||
| enabled: false | |
| enable: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use key_config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what rust code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is circuits_path the same as a path to a lib?
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,7 +69,7 @@ services: | |
| verifier: | ||
| container_name: "vc_dev_verifier" | ||
| hostname: "verifier.vc.docker" | ||
| image: docker.sunet.se/iam_vc/verifier:local | ||
| image: verifier | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use the complete path please |
||
| restart: always | ||
| volumes: | ||
| - ./config_minimal.yaml:/config.yaml:ro | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # --- Stage 1: Build C++ ZK Libraries and Go Binary --- | ||
| FROM golang:latest AS builder | ||
|
Check warning on line 2 in dockerfiles/verifier.Dockerfile
|
||
|
|
||
| RUN apt update -y && apt install -y \ | ||
| clang cmake libssl-dev libzstd-dev libgtest-dev \ | ||
| libbenchmark-dev zlib1g-dev build-essential git | ||
|
|
||
| # 1. Clone the external dependency | ||
| RUN git clone https://github.com/google/longfellow-zk.git /tmp/longfellow-zk && \ | ||
| cd /tmp/longfellow-zk && \ | ||
| git checkout 66fab34ac83bdb669be35ca380e16191468e96d4 | ||
|
|
||
| WORKDIR /tmp/longfellow-zk | ||
|
|
||
| RUN CXX=clang++ cmake -D CMAKE_BUILD_TYPE=Release -S lib -B build \ | ||
| --install-prefix /usr/local/zk-install && \ | ||
| cd build && make -j$(nproc) install | ||
|
|
||
| WORKDIR /app | ||
| COPY . . | ||
| ARG GO_BUILD_TAGS | ||
| RUN --mount=type=cache,target=/root/.cache/go-build \ | ||
| CGO_ENABLED=1 \ | ||
| CGO_CFLAGS="-I/usr/local/zk-install/include" \ | ||
| CGO_LDFLAGS="-L/usr/local/zk-install/lib -lmdoc_static -lcrypto -lzstd -lstdc++" \ | ||
| go build -mod=vendor -v \ | ||
| -tags "${GO_BUILD_TAGS}" \ | ||
| -o /app/bin/vc_verifier ./cmd/verifier/ | ||
|
|
||
| # --- Stage 2: Final Runtime Image --- | ||
| FROM docker.sunet.se/iam_vc/verifier:latest | ||
|
Check warning on line 31 in dockerfiles/verifier.Dockerfile
|
||
|
|
||
| RUN apt update -y && apt install -y libssl3 libzstd1 zlib1g && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Copy the binary | ||
| COPY --from=builder /app/bin/vc_verifier /usr/local/bin/verifier | ||
| COPY --from=builder /tmp/longfellow-zk/lib/circuits /app/vc/internal/verifier/zk/circuits/ | ||
| COPY --from=builder /tmp/longfellow-zk/reference/verifier-service/server/certs.pem /app/vc/internal/verifier/zk/certs.pem | ||
|
|
||
| # Copy compiled libraries | ||
| COPY --from=builder /usr/local/zk-install/lib /usr/local/lib/ | ||
| RUN ldconfig | ||
|
|
||
| WORKDIR / | ||
| ENTRYPOINT ["/usr/local/bin/verifier"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,9 +8,8 @@ ARG GO_BUILD_TAGS | |
| # Copy only dependency files first for better caching | ||
| COPY go.mod go.sum ./ | ||
| RUN --mount=type=cache,target=/root/.cache/go-build \ | ||
| --mount=type=cache,target=/go/pkg/mod \ | ||
| go mod download | ||
|
|
||
| --mount=type=cache,target=/go/pkg/mod | ||
| COPY vendor/ ./vendor/ | ||
|
Comment on lines
10
to
+12
|
||
| # Copy source code | ||
| COPY . . | ||
|
|
||
|
|
@@ -22,7 +21,7 @@ RUN make proto | |
| # GO_BUILD_TAGS is optional - if set, adds -tags flag | ||
| RUN --mount=type=cache,target=/root/.cache/go-build \ | ||
| --mount=type=cache,target=/go/pkg/mod \ | ||
| GOOS=linux GOARCH=amd64 go build -v ${GO_BUILD_TAGS:+-tags "$GO_BUILD_TAGS"} -o bin/vc_$SERVICE_NAME -ldflags \ | ||
| GOOS=linux GOARCH=amd64 go build -mod=vendor -v ${GO_BUILD_TAGS:+-tags "$GO_BUILD_TAGS"} -o bin/vc_$SERVICE_NAME -ldflags \ | ||
| "-X vc/pkg/model.BuildVariableGitCommit=$(git rev-list -1 HEAD) \ | ||
| -X vc/pkg/model.BuildVariableGitBranch=$(git rev-parse --abbrev-ref HEAD) \ | ||
| -X vc/pkg/model.BuildVariableTimestamp=$(date +'%F:T%TZ') \ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,6 +64,7 @@ require ( | |
| gopkg.in/yaml.v2 v2.4.0 | ||
| gorm.io/gorm v1.31.1 | ||
| gotest.tools/v3 v3.5.2 | ||
| proofs/server/v2 v2.0.0 | ||
| ) | ||
|
|
||
| require ( | ||
|
|
@@ -213,3 +214,5 @@ require ( | |
| google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5 // indirect | ||
| gopkg.in/yaml.v3 v3.0.1 // indirect | ||
| ) | ||
|
|
||
| replace proofs/server/v2 => /tmp/longfellow-zk/reference/verifier-service/server | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this necessary? |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,11 @@ | |
| "vc/internal/gen/issuer/apiv1_issuer" | ||
| "vc/pkg/logger" | ||
|
|
||
| "context" | ||
| "encoding/hex" | ||
|
|
||
| "vc/pkg/mdoc" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
@@ -602,3 +607,32 @@ | |
| }) | ||
| } | ||
| } | ||
|
|
||
| func TestMakeMDoc_Only(t *testing.T) { | ||
|
Check warning on line 611 in internal/issuer/apiv1/handlers_test.go
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only what? |
||
| ctx := context.Background() | ||
| log := logger.NewSimple("test") | ||
| client := mockNewClient(ctx, t, "ecdsa", log) | ||
|
|
||
| realIssuer := &mdoc.Issuer{} | ||
|
|
||
| client.mdocIssuer = realIssuer | ||
|
|
||
| deviceKeyHex := "a501020326200121582065eda5bd2d497ef0d35502f5846014e4a66a17ef65476a029587428f6426466322582042f4c664323c932a393086603a1f81d894e77227ed9097e38317769539257609" | ||
| deviceKeyBytes, _ := hex.DecodeString(deviceKeyHex) | ||
|
|
||
| req := &CreateMDocRequest{ | ||
| Scope: "mdl", | ||
| DocType: "org.iso.18013.5.1.mDL", | ||
| DocumentData: []byte(`{"given_name": "John"}`), | ||
| DevicePublicKey: deviceKeyBytes, | ||
| DeviceKeyFormat: "cose", | ||
| } | ||
|
|
||
| got, err := client.MakeMDoc(ctx, req) | ||
| if err != nil { | ||
| t.Logf("Note: Real issuer failed (likely missing keys): %v", err) | ||
| } else { | ||
| require.NoError(t, err) | ||
| assert.NotNil(t, got) | ||
| } | ||
|
Comment on lines
+611
to
+637
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,8 @@ import ( | |
| "go.opentelemetry.io/otel/codes" | ||
|
|
||
| "github.com/gin-gonic/gin" | ||
|
|
||
| "vc/internal/issuer/apiv1" | ||
| ) | ||
|
|
||
| func (s *Service) endpointHealth(ctx context.Context, c *gin.Context) (any, error) { | ||
|
|
@@ -21,3 +23,11 @@ func (s *Service) endpointHealth(ctx context.Context, c *gin.Context) (any, erro | |
| } | ||
| return reply, nil | ||
| } | ||
|
|
||
| func (s *Service) endpointMakeMDoc(ctx context.Context, c *gin.Context) (any, error) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should not be exposed via http, only grpc |
||
| req := &apiv1.CreateMDocRequest{} | ||
| if err := c.ShouldBindJSON(req); err != nil { | ||
| return nil, err | ||
| } | ||
| return s.apiv1.MakeMDoc(ctx, req) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,7 @@ type Service struct { | |
| cfg *model.Cfg | ||
| log *logger.Log | ||
| server *http.Server | ||
| apiv1 Apiv1 | ||
| apiv1 *apiv1.Client | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use interface, not struct. |
||
| gin *gin.Engine | ||
| tracer *trace.Tracer | ||
| httpHelpers *httphelpers.Client | ||
|
Comment on lines
22
to
28
|
||
|
|
@@ -51,6 +51,7 @@ func New(ctx context.Context, cfg *model.Cfg, apiv1 *apiv1.Client, tracer *trace | |
| } | ||
|
|
||
| s.httpHelpers.Server.RegEndpoint(ctx, rgRoot, http.MethodGet, "health", http.StatusOK, s.endpointHealth) | ||
| s.httpHelpers.Server.RegEndpoint(ctx, rgRoot, http.MethodPost, "mdoc", http.StatusOK, s.endpointMakeMDoc) | ||
|
|
||
| rgDocs := rgRoot.Group("/swagger") | ||
| rgDocs.GET("/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running
go mod tidy+go mod vendorinside CI mutatesgo.mod/go.sum/vendorduring the workflow, which makes the build non-deterministic and can mask the fact that the repo isn't kept tidy/vendor'd in git. It also works around the/tmp-based replace rather than fixing it. Prefer committing the correct module dependency (or removing the local replace) and have CI verifygo mod tidy/go mod vendorare already clean (or run tests with-mod=vendorwithout rewriting files).