Skip to content

proofcarryingdata/example-issuer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PCD Issuer

This monorepo contains a client/server boilerplate to demonstrate the PCD SDK usage for issuing an EdDSA PCD in the PCD passport.

πŸ–Ό Context

Proof-Carrying Data (PCD) is a self-contained, independent entity of data carrying sufficient information to be verified and interpreted by a consumer without reliance on exchanges between the issuer and consumer. The two primary components are the claim, a straightforward statement (dubbed 'facts'), and the proof, proving the truth of the statement by mathematical or cryptographic means. No external information is necessary for validation; everything essential resides within, potentially revolutionizing data management: envisioning a world where data flows unrestricted, free from the confinement of silos, restoring data ownership to individuals, facilitating portability across platforms, and removing barriers. Think about your bank or Reddit as a PCD Issuer, offering data imbued with cryptography or math (as Merkle Trees and signatures). Then, you can blend it with your private data, creating your unique PCD. Any third-party PCD Consumer application, from social networks to lending services, can wield the PCD as an unobjectionable attestation to unlock their services.

πŸ§ͺ EdDSA PCD Demo

Now, let's embark on a step-by-step journey to harness the potential of Proof-Carrying Data (PCD). The purpose of this demonstration is to emphasize the way and extent of integration of PCD EdDSA via the PCD SDK. We are going to leverage two basic implementations of PCD Issuer (example-issuer) and PCD Consumer (example-consumer), both contained in a single monorepo (client and server applications). In this case, you can interact with the PCD Issuer to request a PCD on an EdDSA signature on a message (color of your choice) while the PCD Consumer can verify the PCDs (signature on the color of your choice) and subsequently change the background color of the client accordingly to the color in the PCD message. Summarizing, a PCD comprises a claim, in the form of a simple message (the name of your chosen color), and a proof (a signature) crafted through a confidential EdDSA key from the PCD Issuer on the message (color).

Step 1: Prepare Your PCD Passport

Before delving into PCDs, ensure you have the PCD Passport up and running. You must register using an email on PCD Passport to accommodate multiple PCDs. You can efficiently manage these identities using zupass as PCD Passport.

  1. Follow the Local Development section to run your own PCD Passport instance.

  2. Navigate to localhost:3000. You should be able the same page as represented below.

PCD Pass

  1. Enter an email (e.g., demo@pcd.com) and click on Generate Pass. At the end of the process, you should see the following screen.

PCD Pass Identity

Finally, you are now set up and ready to interact with the PCD Issuer client.

Step 2: Request a PCD from the PCD Issuer

Here's where the magic begins. You can now interact with the PCD Issuer (example-issuer) to get a PCD attesting to a signature on your message (chosen color). The process unfolds as follows:

  1. Follow the πŸ›  Install and πŸ“œ Usage instructions in this repository. You should have the client (localhost:1234) and server (localhost:3005) up and running at the end of the process.
  2. Navigate through the client. Select a color (e.g., Yellow) and press the button (Add a PCD Signature with your color). This will open a popup to interact with your PCD Pass as follows.

Issuer Client Popup

  1. The PCD Issuer takes your message and, like a digital wizard, applies its private EdDSA key to create a signature. By clicking the Add button, the PCD is going to be added to your Passport. In fact, by browsing the Passport you should see the following.

PCD Pass EdDSA PCD

Now, you've got your claim (the chosen color name) and proof (EdDSA signature) neatly stored on your PCD Passport and ready for the next step.

Step 3: Interact with the PCD Consumer

With your PCD secured in your Passport, it's time to interact with the PCD Consumer. You can find the implementation at the example-consumer repository. This step allows you to unlock the true potential of your PCD. Here's how it unfolds:

  1. Follow the πŸ›  Install and πŸ“œ Usage instructions in the example-consumer repository. You should have the client (localhost:34269) and server (localhost:3006) up and- unning at the end of the process.
  2. Navigate through the client. Click on Get PCD Signature and then select your PCD.

PCD Consumer Select

  1. The PCD Consumer client interacts with the server that checks if the proof matches with the claim.
  2. If the PCD proves its correctness, you should see an alert on the client and the background color of the page should change to your chosen color accordingly.

πŸ’» PCD Issuer Integration

Integrating a PCD is a straightforward process, and this template, along with the example-consumer, serves as an excellent starting point. We'll now take a closer look at the core code blocks necessary to integrate a PCD (we are considering zupass as Passport along with the PCD SDK). To learn more about how to integrate the PCD Consumer, visit the example-consumer README.

The PCD Issuer should generate a proof for a user claim bundled in a form of a PCD. Generally, the integration of a PCD Issuer consists of the following steps:

Server

  1. Install the desired PCD implementation (e.g., @pcd/eddsa-pcd) and types (@pcd/pcd-types) packages from the PCD SDK.

  2. Initialize the specific PCD package before the execution of its methods (e.g., initEdDSAPCD())

  3. Implementation of an endpoint (POST) to forward the PCD computation request (e.g., sign-message). The API will need to verify the correctness of the forwarded information related to the claim, construct the PCD (prove()), return the PCD in a serialized form back to the client (serialize()).

app.post("/sign-message", async (req: Request, res: Response) => {
try {
if (!req.body.color) {
console.error(`[ERROR] No color specified`)
res.status(400).send()
return
}
if (!/^0x[0-9A-F]{6}$/i.test(req.body.color)) {
console.error(`[ERROR] No valid color`)
res.status(400).send()
return
}
const pcd = await prove({
id: {
argumentType: ArgumentTypeName.String
},
message: {
argumentType: ArgumentTypeName.StringArray,
value: [req.body.color]
},
privateKey: {
argumentType: ArgumentTypeName.String,
value: process.env.PRIVATE_KEY
}
})
console.debug(`[OKAY] color ${req.body.color} has been successfully signed`)
const serializedPCD = await serialize(pcd)
res.json({ serializedPCD }).status(200)
} catch (error: any) {
console.error(`[ERROR] ${error}`)
res.send(500)
}
})

Client

  1. Install the @pcd/passport-interface package containing all the necessary methods and types to interact with the PCD Passport.

  2. Build an interface to receive the information about the claim and forward it to the server to calculate the PCD.

  3. Once the serialized PCD has been obtained, through the method constructPassportPcdAddRequestUrl(), it will be possible to construct a parameterized URL with the PCD information that will allow the interaction with the PCD Passport via popup (openPassportPopup()) from which the user can finalize the addition of the PCD.

const addEdDSAPCD = useCallback(async () => {
const response = await fetch(`http://localhost:${process.env.SERVER_PORT}/sign-message`, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
color: color
})
})
if (!response.ok) {
alert("Some error occurred")
return
}
const { serializedPCD } = await response.json()
// The EdDSA is added to the user's PCDPass.
const url = constructPassportPcdAddRequestUrl(
process.env.PCDPASS_URL as string,
window.location.origin + "/popup",
serializedPCD
)
openPassportPopup("/popup", url)
}, [color])

πŸ›  Install

Use this repository as a Github template.

Clone your repository:

git clone https://github.com/<your-username>/<your-repo>.git

and install the dependencies:

cd <your-repo> && yarn

πŸ“œ Usage

To run everything, you must have a local instance of the zupass PCD Passport on your machine. Follow this guide to get it running correctly.

Copy the .env.example file as .env and add your environment variables:

cp .env.example .env

Run the following command to build (client + server):

yarn build

Run the following command to start the application (client + server):

yarn start