# ZKML on Mina: Building Machine Learning Models with Privacy in Mind
The need for privacy-preserving technologies has led to innovations in combining machine learning (ML) with zero-knowledge proofs (ZKPs). Mina Protocol, a lightweight blockchain, is uniquely positioned to offer a powerful infrastructure for implementing ZKML (Zero-Knowledge Machine Learning). This guide explores how Mina can enable privacy-focused ML predictions, with detailed code examples and creative insights.
## Why ZKML and Mina?
Traditional ML systems often require sharing sensitive data to generate predictions, raising privacy concerns. ZKML bridges this gap by ensuring:
- **Privacy**: Data remains confidential while still generating predictions.
- **Verification**: Predictions are accompanied by proofs of correctness.
- **Scalability**: Mina's swift blockchain ensures minimal computational overhead.
Mina's zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge) enable developers to integrate lightweight, privacy-preserving proofs into their ML workflows.
## Building a Privacy-Preserving Model
We'll build a ZKML system on Mina that:
- Processes inputs (e.g., user data) without exposing them.
- Outputs predictions alongside verifiable proofs.
- Utilizes Mina's zk-SNARKs for efficiency.
### Prerequisites
- Basic understanding of Mina Protocol and zk-SNARKs.
- Python and JavaScript (Node.js) installed locally.
- Mina zkApp CLI and SnarkyJS library.
## Step 1: Set Up Mina zkApp
### Install Mina zkApp CLI:
```bash
npm install -g zkapp-clizkapp-cli create zkml-app
cd zkml-appnpm install snarkyjsLet's consider a simple linear regression model predicting y = mx + c. We'll train the model in Python and save its parameters.
import numpy as np
from sklearn.linear_model import LinearRegression
import json
# Training data
X = np.array([[1], [2], [3]])
y = np.array([3, 5, 7])
# Train model
model = LinearRegression().fit(X, y)
# Extract parameters
params = {"m": model.coef_[0], "c": model.intercept_}
with open("model.json", "w") as f:
json.dump(params, f)Now, let's load the model parameters into your zkApp. SnarkyJS helps define computations verified on Mina.
import { Field, SmartContract, state, State, method } from "snarkyjs";
class ZKMLApp extends SmartContract {
@state(Field) m = State<Field>();
@state(Field) c = State<Field>();
deploy() {
super.deploy();
this.m.set(Field(0)); // Initialize m
this.c.set(Field(0)); // Initialize c
}
@method setModelParams(m: Field, c: Field) {
this.m.set(m);
this.c.set(c);
}
@method predict(x: Field) {
const m = this.m.get();
const c = this.c.get();
const y = m.mul(x).add(c);
return y;
}
}
export default ZKMLApp;npm run deploy
npm run setModelParams -- --m 2 --c 1Integrate user input and generate a zk-SNARK proof of prediction.
import { Field } from "snarkyjs";
import ZKMLApp from "./ZKMLApp.js";
async function main() {
const zkml = new ZKMLApp();
const x = Field(4); // User input
const y = zkml.predict(x);
console.log(`Prediction for x=${x.toString()}: y=${y.toString()}`);
// Generate zk-SNARK proof (abstracted by Mina tools)
const proof = await zkml.prove();
console.log(`Proof of correctness: ${proof}`);
}
main();The proof can be verified independently without revealing the user's input.
import { verifyProof } from "snarkyjs";
async function verify(proof, publicInput) {
const isValid = await verifyProof(proof, publicInput);
console.log(`Proof valid: ${isValid}`);
}
verify(proof, x);- Train the model locally and deploy the zkApp on Mina's testnet.
- Accept user inputs (e.g., via a web form).
- Generate predictions with zk-SNARK proofs.
- Verify predictions publicly while keeping the input private.
Expand from linear regression to a neural network for digit classification using the MNIST dataset.
import tensorflow as tf
import numpy as np
import json
# Load MNIST dataset
(x_train, y_train), _ = tf.keras.datasets.mnist.load_data()
x_train = x_train / 255.0 # Normalize
y_train = tf.keras.utils.to_categorical(y_train, num_classes=10)
# Define and train the model
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)
# Export weights
weights = {layer.name: layer.get_weights() for layer in model.layers}
with open("mnist_model.json", "w") as f:
json.dump(weights, f)For a simplified version of the neural network in Mina:
import { Field, Circuit } from "snarkyjs";
class NeuralNetwork extends Circuit {
static predict(input) {
const weights = [Field(0.2), Field(0.4), Field(0.6)];
const bias = Field(0.1);
let result = Field(0);
for (let i = 0; i < input.length; i++) {
result = result.add(input[i].mul(weights[i]));
}
return result.add(bias);
}
}
export default NeuralNetwork;mina client import-key --privkey-path <path-to-private-key>npm run buildnpm run deployconst zkAppInstance = new ZKMLApp();
zkAppInstance.deploy();
zkAppInstance.setModelParams(Field(2), Field(3));- Create User Input:
const input = [Field(1), Field(2), Field(3)];- Run Prediction:
const prediction = NeuralNetwork.predict(input);
console.log(`Prediction: ${prediction.toString()}`);- Generate Proof:
const proof = await zkAppInstance.prove();
console.log(`Proof: ${proof}`);- Verify Proof:
const isValid = await zkAppInstance.verify(proof);
console.log(`Proof Valid: ${isValid}`);Example using React.js for seamless web interface:
import React, { useState } from "react";
import ZKMLApp from "./ZKMLApp.js";
function App() {
const [input, setInput] = useState("");
const [result, setResult] = useState(null);
const handlePredict = async () => {
const zkml = new ZKMLApp();
const prediction = zkml.predict([Field(input)]);
const proof = await zkml.prove();
setResult({ prediction: prediction.toString(), proof });
};
return (
<div>
<h1>Privacy-Preserving ML</h1>
<input type="text" value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={handlePredict}>Predict</button>
{result && (
<div>
<p>Prediction: {result.prediction}</p>
<p>Proof: {result.proof}</p>
</div>
)}
</div>
);
}
export default App;- Train an ML model for disease risk prediction.
- Encode the model in a Mina zkApp.
- Patients submit encrypted medical data to generate predictions.
- The zkApp provides predictions with verifiable proofs, ensuring the provider never accesses raw data.
- Model Compression: Techniques like quantization and pruning reduce model size.
import tensorflow_model_optimization as tfmot
prune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude
model = prune_low_magnitude(model)- Batch Proof Generation: Generate proofs for multiple inputs simultaneously.
const batchProof = await zkAppInstance.batchProve(inputs);- Leverage Mina's Snarketplace: Use Mina's ecosystem to outsource heavy computation while keeping proofs lightweight.
ZKML on Mina opens doors to secure, private, and scalable ML applications. By combining advanced cryptographic proofs with efficient blockchain design, developers can revolutionize industries like healthcare, finance, and beyond. Whether handling simple models or scaling to real-world applications, Mina ensures privacy without compromise.