diff --git a/packages/app/src/lib/code-gen/templates/zkemail_example/circuit/<%- name %>.circom.ejs b/packages/app/src/lib/code-gen/templates/zkemail_example/circuit/<%- name %>.circom.ejs index 4e03c9b..423c84b 100644 --- a/packages/app/src/lib/code-gen/templates/zkemail_example/circuit/<%- name %>.circom.ejs +++ b/packages/app/src/lib/code-gen/templates/zkemail_example/circuit/<%- name %>.circom.ejs @@ -49,18 +49,30 @@ template <%- name %>(maxHeaderLength, maxBodyLength, n, k, packSize) { <% values.forEach(function(value){ %> // <%- value.name.toUpperCase() %> Extraction - signal input <%- value.name %>RegexIdx; var <%- value.name %>MaxLength = <%- value.maxLength %>; - signal <%- value.name %>RegexOut, <%- value.name %>RegexReveal[<%- (value.location === 'body') ? 'maxBodyLength' : 'maxHeaderLength' %>]; <% if (["from", "to"].includes(value.location)) { %> + <% // Custom regex circuit to extract from and to%> + signal <%- value.name %>RegexOut, <%- value.name %>RegexReveal[<%- (value.location === 'body') ? 'maxBodyLength' : 'maxHeaderLength' %>]; (<%- value.name %>RegexOut, <%- value.name %>RegexReveal) <== <%- value.location === 'to' ? 'ToAddrRegex' : 'FromAddrRegex' %>(maxHeaderLength)(emailHeader); + <%- value.name %>RegexOut === 1; + signal output <%- value.name %>PackedOut[computeIntChunkLength(<%- value.name %>MaxLength)]; + <%- value.name %>PackedOut <== PackRegexReveal(<%- (value.location === 'body') ? 'maxBodyLength' : 'maxHeaderLength' %>, <%- value.name %>MaxLength)(<%- value.name %>RegexReveal, <%- value.name %>RegexIdx); <% } else { %> + <% if (value.parts.find(a => a.is_public)) { %> + <% // Handle case when regex have a public reveal%> + signal <%- value.name %>RegexOut, <%- value.name %>RegexReveal[<%- (value.location === 'body') ? 'maxBodyLength' : 'maxHeaderLength' %>]; + signal input <%- value.name %>RegexIdx; (<%- value.name %>RegexOut, <%- value.name %>RegexReveal) <== <%- value.name %>Regex(<%- (value.location === 'body') ? 'maxBodyLength' : 'maxHeaderLength' %>)(<%- (value.location === 'body') ? 'emailBody' : 'emailHeader' %>); -<% } %> <%- value.name %>RegexOut === 1; - signal output <%- value.name %>PackedOut[computeIntChunkLength(<%- value.name %>MaxLength)]; <%- value.name %>PackedOut <== PackRegexReveal(<%- (value.location === 'body') ? 'maxBodyLength' : 'maxHeaderLength' %>, <%- value.name %>MaxLength)(<%- value.name %>RegexReveal, <%- value.name %>RegexIdx); + <% } else { %> + <% // Handle case when regex have no public reveal%> + signal <%- value.name %>RegexOut; + <%- value.name %>RegexOut <== <%- value.name %>Regex(<%- (value.location === 'body') ? 'maxBodyLength' : 'maxHeaderLength' %>)(<%- (value.location === 'body') ? 'emailBody' : 'emailHeader' %>); + <%- value.name %>RegexOut === 1; + <% } %> +<% } %> <% }); %> } diff --git a/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/contract.sol.ejs b/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/contract.sol.ejs index 2c9fbde..0cebf01 100644 --- a/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/contract.sol.ejs +++ b/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/contract.sol.ejs @@ -18,7 +18,7 @@ contract Contract is Ownable { uint16 public constant pack_size = 31; uint16 public constant pubkey_hash_len = 1; string public constant domain = "<%- senderDomain %>"; -<% let signal_size = 1; values.forEach(function(value) { const packSize = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0) %> +<% let signal_size = 1; values.filter(v => v.parts.find(a => a.is_public)).forEach(function(value) { const packSize = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0) %> uint16 public constant <%- value.name %>_len = <%- packSize %>;<% signal_size += packSize;}) %> <% externalInputs.forEach(function(value) { const packSize = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0) %> @@ -38,7 +38,7 @@ contract Contract is Ownable { // verify RSA bytes32 ph = bytes32(signals[0]); require(dkimRegistry.isDKIMPublicKeyHashValid(domain, ph), "RSA public key incorrect"); -<% let cur_idx = 1; values.forEach(function(value) { %> +<% let cur_idx = 1; values.filter(v => v.parts.find(a => a.is_public)).forEach(function(value) { %> // unpack <%- value.name %> uint[] memory packed_<%- value.name %> = new uint[](<%- value.name %>_len); for (uint i = 0; i < <%- value.name %>_len; i++) { diff --git a/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/verifier.sol.ejs b/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/verifier.sol.ejs index 5f99c9d..4d7c6f6 100644 --- a/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/verifier.sol.ejs +++ b/packages/app/src/lib/code-gen/templates/zkemail_example/contract/src/verifier.sol.ejs @@ -22,7 +22,7 @@ pragma solidity >=0.7.0 <0.9.0; contract Groth16Verifier { - <% let cur_idx = 1; values.forEach(function(value) { const packSize = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0); cur_idx += packSize; });%> + <% let cur_idx = 1; values.filter(v => v.parts.find(a => a.is_public)).forEach(function(value) { const packSize = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0); cur_idx += packSize; });%> <% externalInputs.forEach(function(value) { const packSize = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0); cur_idx += packSize; });%> function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[<%-cur_idx%>] calldata _pubSignals) public view returns (bool) { // verification code will only be filled after the circuit proving keys are generated diff --git a/packages/app/src/lib/code-gen/templates/zkemail_example/index.ts.ejs b/packages/app/src/lib/code-gen/templates/zkemail_example/index.ts.ejs index c2a8cb1..3596279 100644 --- a/packages/app/src/lib/code-gen/templates/zkemail_example/index.ts.ejs +++ b/packages/app/src/lib/code-gen/templates/zkemail_example/index.ts.ejs @@ -39,6 +39,7 @@ try { let currentIndex = 2; <% values.forEach(function(value) { %> + <% if (value.parts.find(a => a.is_public)) { // skip output unpacking when there isn't going to be an output%> { const packedLength = <%- Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0) %> const packedValue = witness.slice(currentIndex, currentIndex + packedLength); @@ -46,7 +47,7 @@ try { console.log("<%- value.name %>: ", unpackedValue); currentIndex += packedLength; } - <% }) %> + <% }}) %> <% externalInputs.forEach(function(input) { %> { diff --git a/packages/app/src/lib/contract/index.ts b/packages/app/src/lib/contract/index.ts index 90687e5..ec5b0a7 100644 --- a/packages/app/src/lib/contract/index.ts +++ b/packages/app/src/lib/contract/index.ts @@ -60,13 +60,15 @@ export const parseOutput = (entry: Entry, output: string[]) => { return result; } for (const value of (entry.parameters as any).values || []) { - const packLength = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0); - const data = output.slice(i, i+packLength); - const unpackedValue = packedNBytesToString(data.map(BigInt)).replaceAll('\u0000', ''); - i += packLength; - result = { - ...result, - [value.name]: unpackedValue + if (value.parts.find((a: {is_public: boolean}) => a.is_public)) { + const packLength = Math.floor(value.maxLength / 31) + (value.maxLength % 31 ? 1 : 0); + const data = output.slice(i, i+packLength); + const unpackedValue = packedNBytesToString(data.map(BigInt)).replaceAll('\u0000', ''); + i += packLength; + result = { + ...result, + [value.name]: unpackedValue + } } } for (const value of (entry.parameters as any).externalInputs || []) {