authenticity-zkapp
v0.3.1
Published
Zero-knowledge proof system for verifying image authenticity on Mina blockchain
Maintainers
Readme
Mina zkApp: Authenticity Zkapp
A zero-knowledge proof system for verifying image authenticity on the Mina blockchain.
Installation
npm install authenticity-zkappDeployment
Prerequisites
Install dependencies:
npm installCreate a
.envfile with your private keys (see.env.example):# Devnet keys DEVNET_PAYER_PRIVATE_KEY=EKE... # Account that pays transaction fees DEVNET_ZKAPP_PRIVATE_KEY=EKE... # Deterministic zkApp deployment address # Mainnet keys MAINNET_PAYER_PRIVATE_KEY=EKE... MAINNET_ZKAPP_PRIVATE_KEY=EKE... # Zeko keys ZEKO_PAYER_PRIVATE_KEY=EKE... ZEKO_ZKAPP_PRIVATE_KEY=EKE...
Deploy to a Network
Deploy the AuthenticityZkApp contract:
# Deploy to devnet
npm run deploy:devnet
# Deploy to mainnet
npm run deploy:mainnet
# Deploy to zeko
npm run deploy:zekoThe deployment script will:
- Compile the AuthenticityProgram (dependency)
- Compile the AuthenticityZkApp contract
- Deploy to the specified network
- Save deployment info to
deployments/[network]-deployment.json
Deployment Output
After successful deployment, you'll receive:
- Transaction hash for tracking
- zkApp address for contract interaction
- Explorer link to view the deployment
Example deployment info:
{
"network": "devnet",
"zkAppAddress": "B62qj2zKtjxv1oaY4S9f5Noy3BKj7V3SWHX91u4vwuCDwyQVbsTeNF5",
"payerAddress": "B62qkifieqVmoequ7HrKisEPyFno14MP2fpAUnDYZ2krdMt7PbhtgG6",
"deployedAt": "2025-08-13T19:10:01.180Z",
"explorerUrl": "https://minascan.io/devnet/account/B62qj2zKtjxv1oaY4S9f5Noy3BKj7V3SWHX91u4vwuCDwyQVbsTeNF5",
"txHash": "5JvGN4pCvZDJpykvKHXzAkrbfe3q55GkZamN8qmYSgsnwtv8MSjD"
}Usage
Run the Example Script
npm run exampleBasic Image Verification
import {
AuthenticityProgram,
AuthenticityInputs,
FinalRoundInputs,
prepareImageVerification,
Bytes32
} from 'authenticity-zkapp';
import { PrivateKey, PublicKey, Signature } from 'o1js';
// 1. Compile the zkProgram
await AuthenticityProgram.compile();
// 2. Prepare image for verification
const verificationInputs = prepareImageVerification('path/to/image.jpg');
// 3. Create a signature to prove ownership
const privateKey = PrivateKey.random();
const publicKey = PublicKey.fromPrivateKey(privateKey);
const signature = Signature.create(
privateKey,
verificationInputs.expectedHash.toFields()
);
// 4. Create public and private inputs
const publicInputs = new AuthenticityInputs({
commitment: verificationInputs.expectedHash,
signature,
publicKey
});
const privateInputs = new FinalRoundInputs({
state: verificationInputs.penultimateState,
initialState: verificationInputs.initialState,
messageWord: verificationInputs.messageWord,
roundConstant: verificationInputs.roundConstant
});
// 5. Generate the proof
const { proof } = await AuthenticityProgram.verifyAuthenticity(
publicInputs,
privateInputs
);
// 6. Verify the proof
const isValid = await AuthenticityProgram.verify(proof);
console.log('Proof is valid:', isValid);Computing On-Chain Commitment
To compute the exact commitment value that will be stored on-chain:
import { computeOnChainCommitment } from 'authenticity-zkapp';
import fs from 'fs';
const imageData = fs.readFileSync('path/to/image.jpg');
const commitment = computeOnChainCommitment(imageData);
console.log('On-chain commitment:', commitment.toString());API Reference
Core Classes
AuthenticityProgram: The main zkProgram for generating and verifying proofsAuthenticityProof: The proof type returned by the programAuthenticityInputs: Public inputs (commitment, signature, publicKey)FinalRoundInputs: Private inputs for SHA-256 final round verificationBytes32: 32-byte type for SHA-256 hashesAuthenticityZkApp: Smart contract for on-chain verification (stores Poseidon hash of commitment)
Helper Functions
prepareImageVerification(imagePath): Prepares all inputs needed for proof generationhashImageOffCircuit(imageData): Computes complete SHA-256 hashhashUntilFinalRound(imageData): Computes SHA-256 up to the final roundperformFinalSHA256Round(...): Executes final SHA-256 round in-circuitcomputeOnChainCommitment(imageData): Computes the exact commitment value stored on-chain (SHA-256 → Poseidon)
How It Works
This zkApp optimizes proof generation by splitting SHA-256 computation:
- Off-circuit: Computes rounds 0-62 of SHA-256 in JavaScript
- In-circuit: Only verifies the final round (63) using zkSNARKs
Circuit Analysis
The AuthenticityProgram method verifyAuthenticity has the following summary:
{
'Total rows': 908,
Generic: 169,
EndoMulScalar: 218,
Rot64: 6,
RangeCheck0: 18,
Xor16: 36,
Zero: 147,
RangeCheck1: 6,
ForeignFieldAdd: 3,
Poseidon: 198,
CompleteAdd: 5,
VarBaseMul: 102
}Development
Build
npm run buildRun Tests
npm run testLint & Format
npm run lint
npm run formatRequirements
- Node.js >= 18.14.0
- o1js >= 2.0.0
