> For the complete documentation index, see [llms.txt](https://debitllama.gitbook.io/debitllama/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://debitllama.gitbook.io/debitllama/payment-intents/zkp-implementation-details.md).

# ZKP Implementation details

The Circom Circuit powering the application

```javascript
pragma circom 2.0.0;
include "../../node_modules/circomlib/circuits/poseidon.circom";

template CommitmentHasher(){
    signal input nullifier;
    signal input secret;
    signal input nonce;
    signal output commitment;
    signal output paymentIntent;

    component commitmentHasher  = Poseidon(2);

    component nullifierHasher = Poseidon(2);

    commitmentHasher.inputs[0] <== nullifier;
    commitmentHasher.inputs[1] <== secret;

    commitment <==commitmentHasher.out;

    nullifierHasher.inputs[0] <== nullifier;
    nullifierHasher.inputs[1] <== nonce;

    paymentIntent <== nullifierHasher.out;
}

template DirectDebit(){
    signal input paymentIntent;
    signal input commitmentHash;

    signal input payee;

    // The max amount that can be debited with the proof
    signal input maxDebitAmount;
    
    // The amount of times this proof can be used ti withdraw max amount
    signal input debitTimes;

    // The time that needs to pass before the proof can be used to debit an account again
    signal input debitInterval;

   // Private inputs!
    signal input secret;
    // A nonce for the nullifier so the note is reusable!
    signal input nonce;
    // The nullifier is used to calculate the secret with the commitment
    // And also the payment intent with the nonce!
    signal input nullifier;
    
    //Hidden signals to verify inputs
    signal payeeSquare;
    signal maxDebitAmountSquare;
    signal debitTimesSquare;
    signal debitIntervalSquare;

    // Hashing the commitment and the nullifier
    component commitmentHasher = CommitmentHasher();
    commitmentHasher.nullifier <== nullifier;
    commitmentHasher.secret <== secret;
    commitmentHasher.nonce <== nonce;

    commitmentHasher.paymentIntent === paymentIntent;
    commitmentHasher.commitment === commitmentHash;

    payeeSquare <== payee * payee;
    maxDebitAmountSquare <== maxDebitAmount * maxDebitAmount;
    debitTimesSquare <== debitTimes * debitTimes;
    debitIntervalSquare <==debitInterval * debitInterval;
}

component main {public [paymentIntent,commitmentHash, payee, maxDebitAmount, debitTimes,debitInterval]} = DirectDebit();
```

The direct debit implementation is powered by this zkp circuit.

Let me explain what is going on, 🤔

### Commitment Hasher

The hasher takes a nullifier, a secret and a nonce which are BigIntegers and outputs Poseidon Hashes Commitment and PaymentIntent

* Nullifier is a random generated number created when the Debit Account is created
* Secret is a random generated number created when the Debit Account is created
* Nonce is a random generated number created when a payment intent is created to allow reusing the Nullifier!
* The Commitment hash is the identifier of the Account. It is the poseidon hash of the nullifier and the secret
* The PaymentIntent hash is the identifier of the PaymentIntent that is used to nullify it and it's created by hashing the nullifier with the nonce!

### Direct Debit Template

The template contains public, private and hidden signals. The public signals need to be available when the proof is verified in the smart contract, the private signals are kept secret and the hidden signals are used to verify parameters of the subscription so they can't be altered!\
\
Private Inputs, These are provided only when the ZKP is created

* Secret, nonce, nullifier&#x20;

Public Inputs:

* paymentIntent - Used to verify the creator knows the nullifier and the nonce without revealing it
* commitment - Used to verify the creator knows the secret and the nullifier that created the commitment hash
* payee, maxDebitAmount,debitTimes, debitInterval - These are arguments to the smart contract function and they are used to verify they were not tampared with, this is done using hidden signals!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://debitllama.gitbook.io/debitllama/payment-intents/zkp-implementation-details.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
