Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
88 changes: 87 additions & 1 deletion post-quantum-server-testing/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,87 @@
This is a WIP
# Post-Quantum Signature Generation Performance Test
Comment thread
alexcottner marked this conversation as resolved.

Benchmark signature generation performance for post-quantum algorithms ML-DSA-65, Falcon-512 and current algorithms RSA-4096, ECDSA-384.

This is to help us investigate and understand performance issues we might run into while doing code-signing and content-signing.

The test will execute 100 signature generations for 4 different algorithms each with 2 different payload sizes. Then return the signing time per operation of each algorithm.

## Running the Testing Program

### Requirements

This program is meant to be a server-side test and can only be tested by authenticated GCP users, otherwise KMS signing will not work.

**Note:** The ML-DSA-65 and ECDSA-384 test functions use KMS key names `mldsa` and `ecdsa`. If your KMS keys have different names, you'll need to update the key names in the `SignData()` function calls in `main.go`.

### Linux (Ubuntu/Debian)

#### 1. Install Dependencies

```bash
sudo apt update
sudo apt install -y \
git \
cmake \
build-essential \
pkg-config \
libssl-dev \
golang-go
```

#### 2. Configure Environment Variables

Create a `.env` file in the `src` directory with your own Google KMS details:

```bash
LOCATION=global
KEYRING=your-keyring
PROJECT_ID=your-gcp-project-id
```

#### 3. Build and Install liboqs

```bash
# Clone and install the liboqs using cmake
git clone --depth=1 https://github.com/open-quantum-safe/liboqs
cmake -S liboqs -B liboqs/build -DBUILD_SHARED_LIBS=ON
cmake --build liboqs/build --parallel 4
sudo cmake --build liboqs/build --target install
```
**Note:** Change `--parallel 4` to the amount of available cores on your system.

#### 4. Set Up liboqs-go Wrapper

```bash
# Clone the liboqs-go
git clone --depth=1 https://github.com/open-quantum-safe/liboqs-go

# Next, you must modify the following lines in $HOME/liboqs-go/.config/liboqs-go.pc
LIBOQS_INCLUDE_DIR=/usr/local/include
LIBOQS_LIB_DIR=/usr/local/lib

# Add these environment variables
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$PWD/liboqs-go/.config
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
```

**Note:** The `liboqs-go.pc` might already have the lines added

#### 5. Authenticate with GCP

```bash
gcloud auth application-default login
```

#### 6. Install Go Dependencies

```bash
cd post-quantum-server-testing/src
go mod download
```

#### 7. Run the Program

```bash
Comment thread
alexcottner marked this conversation as resolved.
go run main.go
```
22 changes: 22 additions & 0 deletions post-quantum-server-testing/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Code coverage profiles and other test artifacts
*.out
coverage.*
*.coverprofile
profile.cov

# Go workspace file
go.work
go.work.sum

# env file
.env
81 changes: 81 additions & 0 deletions post-quantum-server-testing/src/ecdsa_local/ecdsa_local.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package ecdsa_local

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha512"
"crypto/x509"
"encoding/base64"
"fmt"
"log"
"sync"
)

// Public key struct
type PublicKey struct {
Pk *ecdsa.PublicKey
}

// Private key struct
type PrivateKey struct {
PublicKey
Sk *ecdsa.PrivateKey
}

// Response struct
type response struct {
Signature string `json:"signature"`
PublicKey string `json:"publicKey"`
}

// GenerateKey generates a new ECDSA P-384 key pair
func GenerateKey() (*PrivateKey, error) {
sk, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
return nil, err
}
pk := &sk.PublicKey

privateKey := &PrivateKey{
PublicKey: PublicKey{Pk: pk},
Sk: sk,
}
return privateKey, nil
}

// signPQC signs a message using the private key
func (priv *PrivateKey) signPQC(msg []byte) ([]byte, error) {
hash := sha512.Sum384(msg)
sign, err := ecdsa.SignASN1(rand.Reader, priv.Sk, hash[:])
if err != nil {
return nil, fmt.Errorf("signing failed: %v", err)
}
return sign, nil
}

// SignData signs input and returns a response with signature and public key
func SignData(input string, privKey *PrivateKey, wg *sync.WaitGroup) response {
defer wg.Done()

message, err := base64.StdEncoding.DecodeString(input)
if err != nil {
log.Fatalf("error decoding base64 input %v", err)
}

signature, err := privKey.signPQC(message)
if err != nil {
log.Fatalf("error signing message: %v", err)
}

pubKey, err := x509.MarshalPKIXPublicKey(privKey.PublicKey.Pk)
if err != nil {
log.Fatalf("error marshaling public key: %v", err)
}
resp := response{
Signature: base64.StdEncoding.EncodeToString(signature),
PublicKey: base64.StdEncoding.EncodeToString(pubKey),
}

return resp
}
103 changes: 103 additions & 0 deletions post-quantum-server-testing/src/falcon/falcon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package falcon

import (
"crypto/sha256"
"encoding/base64"
"fmt"
"log"
"sync"

"github.com/open-quantum-safe/liboqs-go/oqs"
)

const (
SIGNAME = "Falcon-512"
PUBLICKEYSIZE = 897
PRIVATEKEYSIZE = 1281
)

// Public key struct
type PublicKey struct {
Pk []byte
}

// Private key struct
type PrivateKey struct {
PublicKey
Sk []byte
}

// This is a struct for the response
type response struct {
Signature string `json:"signature"`
PublicKey string `json:"publicKey"`
}

// This function generates a pivate/public key pair
func GenerateKey() (*PrivateKey, error) {
signer := oqs.Signature{}

if err := signer.Init(SIGNAME, nil); err != nil {
log.Fatal(err)
}

pk, err := signer.GenerateKeyPair()
if err != nil {
return nil, err
}

privateKey := new(PrivateKey)
sk := signer.ExportSecretKey()

privateKey.PublicKey.Pk = pk
privateKey.Sk = sk

return privateKey, err
}

// This function takes a private key, signs a message and returns a signature
func (priv *PrivateKey) SignPQC(msg []byte) (sig []byte, err error) {
signer := oqs.Signature{}

if err := signer.Init(SIGNAME, priv.Sk); err != nil {
return nil, fmt.Errorf("failed to init signer: %w", err)
}

// hash with sha256
h := sha256.New()
h.Write(msg)
hash := h.Sum(nil)

sign, err := signer.Sign(hash)
if err != nil {
return nil, fmt.Errorf("signing failed: %w", err)
}
return sign, nil
}

func SignData(input string, privKey *PrivateKey, wg *sync.WaitGroup) response {
defer wg.Done()

// Decode the base64 input
message, err := base64.StdEncoding.DecodeString(input)
if err != nil {
log.Fatalf("error decoding base64 input %v", err)
}

// Generate signature with Falcon signer
signature, err := privKey.SignPQC(message)
if err != nil {
log.Fatalf("error signing message: %v", err)
}

// Get the public key
pubKey := privKey.PublicKey.Pk

resp := response{
Signature: base64.StdEncoding.EncodeToString(signature),
PublicKey: base64.StdEncoding.EncodeToString(pubKey[:]),
}

return resp

}
40 changes: 40 additions & 0 deletions post-quantum-server-testing/src/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module server-testing

go 1.24.0

require (
cloud.google.com/go v0.120.0 // indirect
cloud.google.com/go/auth v0.16.4 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.8.0 // indirect
cloud.google.com/go/iam v1.5.2 // indirect
cloud.google.com/go/kms v1.23.2 // indirect
cloud.google.com/go/longrunning v0.6.7 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/open-quantum-safe/liboqs-go v0.0.0-20250119172907-28b5301df438 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
golang.org/x/crypto v0.41.0 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
golang.org/x/time v0.12.0 // indirect
google.golang.org/api v0.247.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a // indirect
google.golang.org/grpc v1.74.2 // indirect
google.golang.org/protobuf v1.36.10 // indirect
)
Loading
Loading