Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .docker/frost-ci.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
FROM ubuntu:22.04

# Avoid interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive

# Install system dependencies
# curl - Download tools and Rust installer
# build-essential - GCC compiler and build tools for Rust
# pkg-config - Helps find system libraries during compilation
# libssl-dev - SSL/TLS support required by Rust networking crates
# ca-certificates - Trusted certificate authorities for HTTPS
# git - Version control needed by cargo for git dependencies
RUN apt-get update && apt-get install -y \
curl \
build-essential \
pkg-config \
libssl-dev \
ca-certificates \
git \
&& rm -rf /var/lib/apt/lists/*

# Install Rust programming language and toolchain
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
ENV PATH="/root/.cargo/bin:${PATH}"

# Install mkcert for generating local TLS certificates (required by frostd server)
RUN curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64" \
&& chmod +x mkcert-v*-linux-amd64 \
&& mv mkcert-v*-linux-amd64 /usr/local/bin/mkcert

# Setup mkcert CA (this needs to be done at runtime for the examples)
RUN mkcert -install

# Pre-install frostd server
RUN cargo install --git https://github.com/ZcashFoundation/frost-zcash-demo.git --locked frostd

# Create workspace directory
WORKDIR /workspace

# Set environment variables
ENV CARGO_TERM_COLOR=always
ENV RUST_LOG=warn

# Default command
CMD ["/bin/bash"]
33 changes: 33 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Git files

.git
.gitignore

# Documentation

README.md
\*.md

# CI files (except the docker directory)

.github
!.docker

# Build outputs

target/
frost-client/target/

# Generated examples

frost-client/examples/\*/generated/

# IDE files

.vscode/
.idea/

# Temporary files

_.tmp
_.log
67 changes: 67 additions & 0 deletions .github/workflows/build-ci-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This workflow builds a Docker image with pre-installed dependencies for FROST examples.
#
# This workflow runs:
# - Weekly (to get latest security updates)
# - You manually trigger it on GH actions (with latest label from main and pr specific label if made from branch)
# - You push changes to the image to main

name: Build CI Image

on:
workflow_dispatch: # Allow for manual dispatch
schedule:
- cron: "0 2 * * 0" # Weekly rebuild on Sundays at 2 AM to get latest deps
push:
branches: ["main"]
paths: [".docker/frost-ci.Dockerfile"] # Also trigger when this workflow changes

env:
REGISTRY: ghcr.io
IMAGE_NAME: raspberry-devs/mina-multi-sig/frost-ci

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
# Get the source code including the Dockerfile
- name: Checkout code
uses: actions/checkout@v4

# Authenticate with GitHub Container Registry using the built-in token
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Generate appropriate tags and labels for the Docker image
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=raw,value=latest,enable={{is_default_branch}}

# Set up Docker Buildx for advanced building features (caching, multi-platform)
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Build the Docker image with FROST dependencies and push to registry
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: .docker/frost-ci.Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
82 changes: 82 additions & 0 deletions .github/workflows/client-commands.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Client Commands

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
paths:
- "frost-client/**"

env:
CARGO_TERM_COLOR: always

jobs:
test-frost-examples:
runs-on: ubuntu-latest
container:
# @TODO: Once PR 76 is merged change the image to frost-ci:latest
# (it will only be created after merge to main)
image: ghcr.io/raspberry-devs/mina-multi-sig/frost-ci:pr-76
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

steps:
- name: Checkout code
uses: actions/checkout@v4

# Add Cargo caching for speed boost
- name: Cache Cargo build artifacts
uses: actions/cache@v3
with:
path: |
/root/.cargo/registry/index/
/root/.cargo/registry/cache/
/root/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-container-${{ hashFiles('frost-client/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-container-

# Pre-build once instead of building for each example
- name: Build frost-client (release mode)
run: |
cd frost-client
cargo build --release --bin frost-client

# Run all examples that test if the basic usecases of the client don't break
- name: Run Trusted Dealer Example
run: |
cd frost-client/examples/trusted_dealer_example
timeout 300 ./trusted_dealer_example.sh

- name: Run DKG Example
run: |
cd frost-client/examples/dkg_example
timeout 300 ./dkg_example.sh

- name: Run Signing Example
run: |
cd frost-client/examples/signing_example
timeout 300 ./signing_example.sh

- name: Verify generated artifacts
run: |
test -f frost-client/examples/trusted_dealer_example/generated/alice.toml
test -f frost-client/examples/trusted_dealer_example/generated/bob.toml
test -f frost-client/examples/trusted_dealer_example/generated/eve.toml
test -f frost-client/examples/dkg_example/generated/alice.toml
test -f frost-client/examples/dkg_example/generated/bob.toml
test -f frost-client/examples/dkg_example/generated/eve.toml
test -f frost-client/examples/signing_example/generated/signature.json
test -f frost-client/examples/signing_example/generated/message.json

- name: Upload artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: frost-example-outputs
path: |
frost-client/examples/*/generated/
retention-days: 7
46 changes: 46 additions & 0 deletions frost-client/examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# FROST Client Examples

Three examples demonstrating FROST threshold signatures for the Mina protocol.

## Examples

### 1. Trusted Dealer (`trusted_dealer_example/`)

Single party generates and distributes key shares to 3 participants (threshold t=2).

```bash
cd trusted_dealer_example/
./trusted_dealer_example.sh
```

### 2. Distributed Key Generation (`dkg_example/`)

Participants collaboratively generate keys without any single party knowing the complete private key.

```bash
cd dkg_example/
./dkg_example.sh
```

### 3. Signing (`signing_example/`)

Create threshold signatures using keys from previous examples.

```bash
# Then run signing example
cd ../signing_example/
./signing_example.sh
```

## Development

Remember to add executable permisions for each example before running:

```bash
chmod +x trusted_dealer_example/trusted_dealer_example.sh
chmod +x dkg_example/dkg_example.sh
chmod +x signing_example/signing_example.sh
```

Examples use `cargo run` to run the client (always uses your latest code changes).

Empty file.
Loading