Skip to content
Open
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
12 changes: 6 additions & 6 deletions .github/workflows/node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ jobs:
node-version: [20]
steps:
- name: Checking out
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Setup Node v${{ matrix.node-version }}
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
Expand All @@ -38,12 +38,12 @@ jobs:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checking out
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Use Node.js v20
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: 20
# registry-url is required to correctly setup authentication per https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages#publishing-packages-to-the-npm-registry
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/semgrep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
if: github.repository == 'cloudflare/zkp-ecdsa'
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
SEMGREP_URL: https://cloudflare.semgrep.dev
Expand All @@ -20,5 +21,5 @@ jobs:
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- run: semgrep ci --verbose
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
cff-version: 1.2.0
version: 0.2.5
version: 0.2.6
title: "zkp-ecdsa: A Typescript Implementation of ZKAttest"
license: Apache-2.0
abstract: >
Expand Down Expand Up @@ -57,4 +57,4 @@ preferred-citation:
isbn: "978-3-030-99277-4"
notes: >
Available at https://github.com/cloudflare/zkp-ecdsa.
v0.2.5 Accessed Nov 2022
v0.2.6 Accessed Jan 2026
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
Ready to use ZKAttest proofs, follow this short guideline.

#### Step 1

Suppose you already have a signature of a message using ECDSA (P-256). Otherwise, create signature as follows:

```ts
Expand Down Expand Up @@ -52,6 +53,7 @@ listKeys.unshift(await keyToInt(keyPair.publicKey));
#### Step 3

Now, create a **ZKAttest proof of knowledge** showing that

- the signature was generated using the private key, AND
- the public key is in the ring.

Expand Down Expand Up @@ -98,7 +100,7 @@ To cite this library, use one of the following formats and update the version an

**APA Style**

Faz-Hernández, A., Ladd, W., Maram, D. (2021). ZKAttest: Ring and Group Signatures for Existing ECDSA Keys. In: AlTawy, R., Hülsing, A. (eds) Selected Areas in Cryptography. SAC 2021. Available at https://github.com/cloudflare/zkp-ecdsa. v0.2.5 Accessed Nov 2022.
Faz-Hernández, A., Ladd, W., Maram, D. (2021). ZKAttest: Ring and Group Signatures for Existing ECDSA Keys. In: AlTawy, R., Hülsing, A. (eds) Selected Areas in Cryptography. SAC 2021. Available at https://github.com/cloudflare/zkp-ecdsa. v0.2.6 Accessed Jan 2026.

**BibTex Source**

Expand All @@ -116,7 +118,7 @@ Faz-Hernández, A., Ladd, W., Maram, D. (2021). ZKAttest: Ring and Group Signatu
month = {oct},
year = {2021},
note = {Available at \url{https://github.com/cloudflare/zkp-ecdsa}.
v0.2.5 Accessed Nov 2022},
v0.2.6 Accessed Jan 2026},
}
```

Expand Down
11 changes: 11 additions & 0 deletions example/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../tsconfig.json",
"include": [
"."
],
"references": [
{
"path": ".."
}
]
}
62 changes: 62 additions & 0 deletions example/usage.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a great addition!

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright 2026 Cloudflare Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {
verifySignatureList,
generateParamsList,
proveSignatureList,
keyToInt,
writeJson,
SignatureProofList,
} from '../src/index.js'

async function example() {
// Message to be signed.
const plain_msg = 'kilroy was here',
msg = new TextEncoder().encode(plain_msg)
console.log(`Message: ${plain_msg}`)

const // Generate a keypair for signing.
keyPair = await crypto.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign', 'verify']),
// Sign a message as usual.
signature = new Uint8Array(
await crypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, keyPair.privateKey, msg)
),
// Add the public key to an existing ring of keys,
listKeys = [BigInt(4), BigInt(5), BigInt(6), BigInt(7), BigInt(8)]
listKeys.unshift(await keyToInt(keyPair.publicKey))

// Create a zero-knowledge proof about the signature.
const params = generateParamsList(),
msgHash = new Uint8Array(await crypto.subtle.digest('SHA-256', msg)),
zkAttestProof = await proveSignatureList(
params,
msgHash,
signature,
keyPair.publicKey,
0, // position of the public key in the list.
listKeys
),
proofJSON = writeJson(SignatureProofList, zkAttestProof)
console.log(`Proof JSON size: ${proofJSON.length} bytes.`)

// Verify that zero-knowledge proof is valid.
const valid = await verifySignatureList(params, msgHash, listKeys, zkAttestProof)
console.assert(valid == true)
console.log(`Valid signature: ${valid}`)
}

await example()
Loading