Skip to content

Commit ed6b43d

Browse files
committed
Implement online ceremony
Provide implementation of client and server for online contributions. The server waits for contributions from the clients and orchestrates the ceremony. Clients connect to the server, contribute and disconnect. Signed-off-by: Wojciech Zmuda <[email protected]>
1 parent 2efe28c commit ed6b43d

File tree

31 files changed

+2116
-18
lines changed

31 files changed

+2116
-18
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444
uses: actions/setup-go@v5
4545
with:
4646
go-version: '1.24'
47+
- name: Generate code from gRPC protocol definition
48+
run: go generate ./...
4749
- name: Build
4850
run: go build ./...
4951
- name: Test

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
.idea/
22

3-
*.ph1
4-
*.ph2
3+
# Generated protobuf code
4+
**/ceremony.pb.go
5+
**/ceremony_grpc.pb.go
56

67
trusted-setup
8+
.DS_Store

README.md

Lines changed: 122 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,42 @@
11
# ZKP Trusted Setup Ceremony Coordinator
22

3+
**Warning**
4+
Please note that this tool is under development. Please consider it unusable before the first release.
5+
36
## Overview
47
This utility program allows for performing a Trusted Setup Ceremony in a Multi-Party Computation fashion. It is meant
58
to be used by the Coordinator of the ceremony, as well as by the Contributors. In the end, the Coordinator will obtain
69
Proving and Verifying Keys, which can be used to generate proofs for the circuit the ceremony was conducted for.
710

11+
### Online mode
12+
13+
The primary mode of the program. In this mode, the Coordinator runs the ceremony server, which is responsible for
14+
accepting contributions from the Contributors. The Contributors connect to the Coordinator and contribute to the
15+
ceremony.
16+
17+
See help for `server` and `client` commands for details.
18+
19+
### Offline mode
20+
21+
In this mode, the Coordinator and the Contributors run the ceremony locally. The Coordinator initializes the ceremony
22+
and generates the initial Phase 2 file. The Coordinator sends the file to the first Contributor. The Contributor
23+
generates their contribution and sends them to the Coordinator in the form of a Phase 2 file. The Coordinator verifies
24+
the contributions and, if the verification is positive, sends it to the next Contributor.
25+
26+
In this mode, sending Phase 2 files must be performed manually by the Coordinator and Contributors.
27+
28+
At the end of the ceremony, the Coordinator will have a list of accepted contributions. The Coordinator can then
29+
perform the final verification and extract the Proving and the Verifying Keys.
30+
31+
See help for `init`, `contrib`, `verify` and `extract` commands for details.
32+
33+
### Snarkjs powers of tau (ptau) -> Phase 1 conversion
34+
35+
The tool can convert a Snarkjs powers of tau file to a Phase 1 file. This step is performed by the Coordinator before
36+
the initialization of the offline mode ceremony, if the Coordinator has a ptau file that they wish to use in the ceremony.
37+
38+
This step is not necessary if the Coordinator already has a Phase 1 file.
39+
840
## Constraints
941

1042
Gnark version used for implementing the circuit the ceremony will be conducted for must match the Gnark version used
@@ -14,20 +46,57 @@ Your Gnark project must satisfy the following constraints:
1446
- Supported curve: BN254
1547
- Supported backend: Groth16
1648

49+
## Prerequisites
50+
51+
These are one-time steps that must be done in order to build the program.
52+
53+
Install [Go](https://go.dev/dl/). Any recent version will do. Look into `go.mod` to see the minimum required version.
54+
55+
Install [Protocol Buffer Compiler](https://protobuf.dev/installation/).
56+
57+
Install gRPC for Go:
58+
59+
```shell
60+
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
61+
```
62+
63+
## Build
64+
65+
To build the project, run:
66+
```shell
67+
$ go generate ./...
68+
$ go build .
69+
````
70+
71+
in the project's root directory.
72+
73+
The test suite can be executed with:
74+
```shell
75+
$ go test -v ./...
76+
```
77+
1778
## Usage
1879
19-
Run the program with `go run .` or `go run <command> <options>`.
80+
Run the program with:
81+
```shell
82+
$ go run . <command> <options>
83+
84+
# or, after the program was built
85+
./trusted-setup <command> <options>
86+
```
2087
2188
Running the program with no arguments lists the available commands. Running the program with the command but without
2289
options will display the command's help.
2390

2491
## Commands
2592

26-
### `help`
93+
### General purpose commands
94+
95+
#### `help`
2796

2897
Print help.
2998

30-
### `ptau`
99+
#### `ptau`
31100

32101
Convert a Snarkjs powers of tau file to a Phase 1 file. This step is performed by the Coordinator.
33102

@@ -38,9 +107,54 @@ tau file to a Phase 1 file, which can be used to initialize the Phase 2 of the c
38107
- `--ptau` - A Snarkjs powers of tau file,
39108
- `--phase1` - The output Phase 1 file.
40109

41-
### `init`
110+
### Online mode commands
111+
112+
#### `server`
113+
114+
Start a Ceremony server. This step is performed by the Coordinator.
115+
116+
The server is responsible for orchestrating the ceremony, receiving contributions from the participants and, in the end,
117+
generating Proving and Verifying Keys.
118+
119+
The server is configured with a JSON file. An example configuration is shown below:
120+
```json5
121+
{
122+
// A human-readable name for the ceremony that will be sent to contributors.
123+
// Used for identification purposes; can be any reasonably sized string.
124+
"ceremonyName": "test ceremony",
125+
// The IP address on which the server will listen on.
126+
"host": "127.0.0.1",
127+
// The TCP port on which the server will listen on.
128+
"port": 7312,
129+
// The path to the R1CS file generated from a Gnark circuit.
130+
"r1cs": "resources/server.r1cs",
131+
// The path to the Phase 1 file (possibly generated from a ptau file - see the `ptau` command for details).
132+
"phase1": "resources/server.ph1",
133+
}
134+
```
135+
136+
Coordination of the ceremony is automatic. No action from the Coordinator is required besides starting the server
137+
and stopping it with CTRL+C at any arbitrary moment. At CTRL+C, the server stops accepting new contributions and starts
138+
key extraction from the existing contributions.
139+
140+
- `--config` - Path to a JSON file containing the server configuration.
141+
142+
#### `client`
143+
144+
Connect to a Ceremony server and provide contributions. This step is performed by the Contributors.
145+
146+
The client is responsible for connecting to the server and providing contributions. The client is configured with
147+
a host and port of the server. Participation in the ceremony is automatic. No action from the Contributor is required
148+
besides starting the client.
149+
150+
- `--host` - The IP address of the server,
151+
- `--port` - The port of the server.
152+
153+
### Offline mode commands
154+
155+
#### `init`
42156

43-
Initialize Phase 2 of the ceremony for the given R1CS with a Phase 1 file. This step is performed by the Coordinator.
157+
Initialize Phase 2 of the ceremony for the given R1CS with a Phase 1 file. This step is performed by the Coordinator.
44158

45159
This step outputs a Phase 2 file based on the provided R1CS and Phase 1 file. The Coordinator must provide the R1CS file
46160
generated from a Gnark circuit and the Phase 1 file either generated in the previous step or from another
@@ -58,7 +172,7 @@ The command outputs a beacon value, which must then be passed as an argument to
58172
- `--phase2` - The output path for the Phase 2 file,
59173
- `--srscommons` - The output path for circuit-independent components of the Groth16 SRS.
60174

61-
### `contribute`
175+
#### `contribute`
62176

63177
Contribute randomness to Phase 2. This step is performed by all the participants of the ceremony.
64178

@@ -70,7 +184,7 @@ appended to the name.
70184

71185
- `--phase2` - The existing Phase 2 file created in the `init` step or in the previous run of the `contribute` step.
72186

73-
### `verify`
187+
#### `verify`
74188

75189
Verify the last randomness contributed to Phase 2. This step is performed by the Coordinator.
76190

@@ -85,7 +199,7 @@ If the verification is successful, the Coordinator can either:
85199
- `--phase2prev` - A Phase 2 file being an input to the contribution
86200
- `--phase2next` - A Phase 2 file that was contributed to.
87201

88-
### `extract-keys`
202+
#### `extract-keys`
89203

90204
Extract the Proving and Verifying Keys. This step is performed by the Coordinator.
91205

go.mod

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ require (
66
github.com/consensys/gnark v0.13.0
77
github.com/consensys/gnark-crypto v0.18.0
88
github.com/drand/go-clients v0.2.3
9+
github.com/golang/protobuf v1.5.4
910
github.com/stretchr/testify v1.10.0
1011
github.com/urfave/cli/v3 v3.3.8
1112
github.com/worldcoin/ptau-deserializer v0.2.0
13+
google.golang.org/grpc v1.73.0
14+
google.golang.org/protobuf v1.36.6
1215
)
1316

1417
replace github.com/worldcoin/ptau-deserializer => github.com/reilabs/ptau-deserializer v0.0.0-20250630133456-6f3242b72b0a
@@ -41,6 +44,7 @@ require (
4144
github.com/prometheus/procfs v0.17.0 // indirect
4245
github.com/ronanh/intcomp v1.1.1 // indirect
4346
github.com/rs/zerolog v1.34.0 // indirect
47+
github.com/stretchr/objx v0.5.2 // indirect
4448
github.com/x448/float16 v0.8.4 // indirect
4549
go.dedis.ch/fixbuf v1.0.3 // indirect
4650
go.uber.org/multierr v1.11.0 // indirect
@@ -51,7 +55,5 @@ require (
5155
golang.org/x/sys v0.33.0 // indirect
5256
golang.org/x/text v0.26.0 // indirect
5357
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect
54-
google.golang.org/grpc v1.71.1 // indirect
55-
google.golang.org/protobuf v1.36.6 // indirect
5658
gopkg.in/yaml.v3 v3.0.1 // indirect
5759
)

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ github.com/ronanh/intcomp v1.1.1/go.mod h1:7FOLy3P3Zj3er/kVrU/pl+Ql7JFZj7bwliMGk
113113
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
114114
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
115115
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
116+
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
117+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
116118
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
117119
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
118120
github.com/urfave/cli/v3 v3.3.8 h1:BzolUExliMdet9NlJ/u4m5vHSotJ3PzEqSAZ1oPMa/E=
@@ -141,8 +143,8 @@ go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/
141143
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
142144
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
143145
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
144-
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
145-
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
146+
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
147+
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
146148
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
147149
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
148150
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
@@ -173,8 +175,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e h1:
173175
google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e/go.mod h1:085qFyf2+XaZlRdCgKNCIZ3afY2p4HHZdoIRpId8F4A=
174176
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e h1:ztQaXfzEXTmCBvbtWYRhJxW+0iJcz2qXfd38/e9l7bA=
175177
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
176-
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
177-
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
178+
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
179+
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
178180
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
179181
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
180182
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

main.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ import (
99
"github.com/urfave/cli/v3"
1010

1111
"github.com/reilabs/trusted-setup/offline"
12+
"github.com/reilabs/trusted-setup/online"
1213
)
1314

1415
func main() {
1516
app := &cli.Command{
1617
Name: filepath.Base(os.Args[0]),
1718
Usage: "a ZKP Trusted Setup Ceremony Coordinator",
18-
Description: "This program allows for initializing a trusted setup ceremony and contributing to it.\n" +
19+
Description: "This program allows for initializing a trusted setup ceremony and contributing to it.\n\n" +
20+
"The program has two modes:\n" +
21+
"- the online mode: run an automated ceremony server and let clients connect and contribute\n" +
22+
"- the offline mode: orchestrate the ceremony yourself, manually managing contributions\n\n" +
1923
"Phase 2 of the ceremony can be initialized from a previously generated Phase 1 file\n" +
2024
"or from a Snarkjs powers of tau file. New contributions can be added to Phase 2.\n" +
2125
"The contributions can be verified. Proving and verifying keys can be exported from the\n" +
@@ -31,9 +35,12 @@ func main() {
3135
},
3236
DefaultCommand: "help",
3337
Suggest: true,
34-
Commands: offline.Commands,
38+
Commands: []*cli.Command{},
3539
}
3640

41+
app.Commands = append(app.Commands, offline.Commands...)
42+
app.Commands = append(app.Commands, online.Commands...)
43+
3744
if err := app.Run(context.Background(), os.Args); err != nil {
3845
log.Fatal(err)
3946
}

online/actions/client.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package actions
2+
3+
import (
4+
"context"
5+
6+
"github.com/urfave/cli/v3"
7+
8+
"github.com/reilabs/trusted-setup/online/client"
9+
)
10+
11+
func Client(_ context.Context, cmd *cli.Command) error {
12+
host := cmd.String("host")
13+
port := cmd.String("port")
14+
15+
return client.ConnectAndContribute(host, port)
16+
}

0 commit comments

Comments
 (0)