Skip to content

Commit

Permalink
chore(wip): add sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
martonmoro committed Sep 24, 2024
1 parent 5f10962 commit df2952b
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 48 deletions.
1 change: 0 additions & 1 deletion browser-extension/mockSig.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const publicKey = privateKey.toPublicKey();
const age = Field(25);
const message = [age];

// Create the signature
const signature = Signature.create(privateKey, message);

console.log('Private Key:', privateKey.toBase58());
Expand Down
3 changes: 3 additions & 0 deletions browser-extension/public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
"permissions": ["storage"],
"background": {
"service_worker": "background.js"
},
"sandbox": {
"pages": ["sandbox.html"]
}
}
3 changes: 0 additions & 3 deletions browser-extension/src/popup/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('attestationForm');
const generateProofButton = document.getElementById('generateProof');

// Load saved values
chrome.storage.sync.get(['age', 'signature', 'issuerPublicKey'], (result) => {
document.getElementById('age').value = result.age || '';
document.getElementById('signature').value = result.signature || '';
document.getElementById('issuerPublicKey').value =
result.issuerPublicKey || '';
});

// Save form data
form.addEventListener('submit', (e) => {
e.preventDefault();
const age = document.getElementById('age').value;
Expand All @@ -22,7 +20,6 @@ document.addEventListener('DOMContentLoaded', () => {
});
});

// Open proof generation page
generateProofButton.addEventListener('click', () => {
chrome.tabs.create({ url: 'proof/proof.html' });
});
Expand Down
17 changes: 10 additions & 7 deletions browser-extension/src/proof/proof.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Generate Proof</title>
<script type="module" src="proof.js"></script>
</head>
<body>
<h1>Generate Proof</h1>
<div>
<label for="minAge">Minimum Age:</label>
<input type="number" id="minAge" name="minAge" required />
<input type="number" id="minAge" min="0" />
</div>
<br />
<button id="generateProofBtn">Generate Proof</button>
<div id="proofResult"></div>
<script type="module" src="proof.js"></script>

<iframe
id="sandboxFrame"
sandbox="allow-scripts"
src="sandbox.html"
style="display: none"
></iframe>
</body>
</html>
87 changes: 50 additions & 37 deletions browser-extension/src/proof/proof.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import { Field, PublicKey, Signature, ZkProgram } from 'o1js';
import { zkProgram } from '../../src/program.js';

let compiledZkProgram;

document.addEventListener('DOMContentLoaded', async () => {
console.log('DOMContentLoaded event fired');

const minAgeInput = document.getElementById('minAge');
const generateProofBtn = document.getElementById('generateProofBtn');
const proofResultDiv = document.getElementById('proofResult');
const sandboxFrame = document.getElementById('sandboxFrame');

console.log('DOM elements retrieved:', {
minAgeInput,
generateProofBtn,
proofResultDiv,
sandboxFrame,
});

proofResultDiv.textContent = 'Compiling ZK program...';
try {
compiledZkProgram = await zkProgram.compile();
proofResultDiv.textContent =
'ZK program compiled successfully. Ready to generate proofs.';
} catch (error) {
console.error('Error compiling ZK program:', error);
proofResultDiv.textContent =
'Error compiling ZK program. Please check the console for details.';
return;
}
proofResultDiv.textContent = 'Waiting for sandbox to load...';

sandboxFrame.addEventListener('load', () => {
console.log('Sandbox iframe loaded, sending compile message');
proofResultDiv.textContent = 'Compiling ZK program...';

sandboxFrame.contentWindow.postMessage({ type: 'compile' }, '*');
});

generateProofBtn.addEventListener('click', async () => {
console.log('Generate Proof button clicked');
const minAge = parseInt(minAgeInput.value, 10);

if (isNaN(minAge) || minAge < 0) {
proofResultDiv.textContent = 'Please enter a valid minimum age.';
return;
}

try {
// Retrieve stored data
console.log('Retrieving stored data from chrome.storage.sync');
const storedData = await new Promise((resolve) => {
chrome.storage.sync.get(
['age', 'signature', 'issuerPublicKey'],
Expand All @@ -46,30 +50,39 @@ document.addEventListener('DOMContentLoaded', async () => {
return;
}

// Convert stored data to appropriate types
const age = Field(storedData.age);
const minAgeField = Field(minAge);
const signature = Signature.fromJSON(storedData.signature);
const issuerPublicKey = PublicKey.fromJSON(storedData.issuerPublicKey);
const data = {
age: Field(storedData.age),
minAgeField: Field(minAge),
signature: Signature.fromBase58(storedData.signature),
issuerPublicKey: PublicKey.fromJSON(storedData.issuerPublicKey),
};

proofResultDiv.textContent = 'Generating proof...';

// Generate the proof
const proof = await zkProgram.verifyAge(
minAgeField,
age,
issuerPublicKey,
signature
console.log('Sending generateProof message to sandbox');
sandboxFrame.contentWindow.postMessage(
{
type: 'generateProof',
data: data,
},
'*'
);

proofResultDiv.textContent = `Proof generated successfully. The stored age (${storedData.age}) is at least ${minAge}.`;

// You can do something with the proof here, like sending it to a server or displaying it
console.log('Generated proof:', proof.toJSON());
} catch (error) {
console.error('Error generating proof:', error);
console.error('Error retrieving or processing data:', error);
proofResultDiv.textContent =
'An error occurred while generating the proof. Please check the console for details.';
'An error occurred while retrieving the data. Please check the console for details.';
}
});

window.addEventListener('message', (event) => {
if (event.data.type === 'compilationResult') {
if (event.data.success) {
proofResultDiv.textContent =
'ZK program compiled successfully. Ready to generate proofs.';
} else {
proofResultDiv.textContent =
'Error compiling ZK program. Please check the console for details.';
}
} else if (event.data.type === 'proofResult') {
proofResultDiv.textContent = event.data.result;
}
});
});
11 changes: 11 additions & 0 deletions browser-extension/src/proof/sandbox.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self' 'wasm-eval';"
/>
<script type="module" src="sandbox.js"></script>
</head>
<body></body>
</html>
110 changes: 110 additions & 0 deletions browser-extension/src/proof/sandbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Field, PublicKey, Signature, ZkProgram } from 'o1js';

console.log('sandbox.js loaded');

let compiledZkProgram;

console.log('Defining ZkProgram');
const zkProgram = ZkProgram({
name: 'AgeCheck',
publicInput: Field,
publicOutput: PublicKey,
methods: {
verifyAge: {
privateInputs: [Field, PublicKey, Signature],
async method(minAge, age, issuerPubKey, signature) {
console.log('verifyAge method called with:', {
minAge,
age,
issuerPubKey,
signature,
});
const validSignature = signature.verify(issuerPubKey, [age]);
console.log('Signature verification result:', validSignature);
validSignature.assertTrue();
console.log('Asserting age >= minAge');
age.assertGreaterThanOrEqual(minAge);
return issuerPubKey;
},
},
},
});

async function compileProgram() {
console.log('Compiling ZkProgram');
try {
compiledZkProgram = await zkProgram.compile();
console.log('ZkProgram compiled successfully');
window.parent.postMessage(
{
type: 'compilationResult',
success: true,
},
'*'
);
} catch (error) {
console.error('Error compiling ZK program:', error);
window.parent.postMessage(
{
type: 'compilationResult',
success: false,
},
'*'
);
}
}

window.addEventListener('message', async (event) => {
console.log('Received message in sandbox:', event.data);

if (event.data.type === 'compile') {
console.log('Compile message received, starting compilation');
await compileProgram();
} else if (event.data.type === 'generateProof') {
console.log('Generate proof message received');
const { age, minAgeField, signature, issuerPublicKey } = event.data.data;
console.log('Proof generation data:', {
age,
minAgeField,
signature,
issuerPublicKey,
});

try {
if (!compiledZkProgram) {
throw new Error('ZkProgram not compiled yet');
}

console.log('Generating proof');
const proof = await zkProgram.verifyAge(
minAgeField,
age,
issuerPublicKey,
signature
);

console.log('Proof generated successfully');
window.parent.postMessage(
{
type: 'proofResult',
result: `Proof generated successfully. The stored age (${age.toString()}) is at least ${minAgeField.toString()}.`,
},
'*'
);

console.log('Generated proof:', proof.toJSON());
} catch (error) {
console.error('Error generating proof:', error);
window.parent.postMessage(
{
type: 'proofResult',
result:
'An error occurred while generating the proof. Please check the console for details.',
},
'*'
);
}
}
});

console.log('sandbox.js event listener set up');
1 change: 1 addition & 0 deletions browser-extension/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default defineConfig({
popup: resolve(root, 'popup', 'popup.html'),
background: resolve(root, 'background.js'),
proof: resolve(root, 'proof', 'proof.html'),
sandbox: resolve(root, 'proof', 'sandbox.html'),
},
output: {
entryFileNames: '[name].js',
Expand Down

0 comments on commit df2952b

Please sign in to comment.