Skip to content

Commit

Permalink
full tested to work with all cases
Browse files Browse the repository at this point in the history
  • Loading branch information
jp4g committed Oct 3, 2024
1 parent fce02ba commit 3196238
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 83 deletions.
6 changes: 2 additions & 4 deletions examples/partial_hash/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use dep::zkemail::{
KEY_LIMBS_2048, base64::bodyhash_base64_decode, dkim::verify_dkim_2048, body_hash::get_body_hash_by_index,
KEY_LIMBS_2048, dkim::verify_dkim_2048, get_body_hash_by_index, base64::body_hash_base64_decode,
partial_hash::partial_sha256_var_end, standard_outputs
};

Expand Down Expand Up @@ -42,12 +42,10 @@ fn main(

// manually extract the body hash from the header
let body_hash_encoded = get_body_hash_by_index(header, body_hash_index);
let signed_body_hash: [u8; 32] = bodyhash_base64_decode(body_hash_encoded);
let signed_body_hash: [u8; 32] = body_hash_base64_decode(body_hash_encoded);

// finish the partial hash
let computed_body_hash = partial_sha256_var_end(partial_body_hash, body, partial_body_length as u64, body_length as u64);
println(signed_body_hash);
println(computed_body_hash);

// check the body hashes match
assert(
Expand Down
17 changes: 13 additions & 4 deletions examples/verify_email_1024_bit_dkim/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use dep::zkemail::{
KEY_LIMBS_1024, dkim::verify_dkim_1024, body_hash::{get_body_hash_by_index, compare_body_hash},
KEY_LIMBS_1024, dkim::verify_dkim_1024, get_body_hash_by_index, base64::body_hash_base64_decode,
standard_outputs
};
use dep::std::hash::sha256_var;

global MAX_EMAIL_HEADER_LENGTH: u32 = 512;
global MAX_EMAIL_BODY_LENGTH: u32 = 1024;
Expand Down Expand Up @@ -38,11 +39,19 @@ fn main(
// verify the dkim signature over the header
verify_dkim_1024(header, header_length, pubkey, pubkey_redc, signature);

// manually extract the body hash from the header
// extract the body hash from the header
let body_hash_encoded = get_body_hash_by_index(header, body_hash_index);

// compare the retrieved body hash to the computed body hash
compare_body_hash(body_hash_encoded, body, body_length);
// base64 decode the body hash
let signed_body_hash: [u8; 32] = body_hash_base64_decode(body_hash_encoded);

// hash the asserted body
let computed_body_hash: [u8; 32] = sha256_var(body, body_length as u64);

// compare the body hashes
assert(
signed_body_hash == computed_body_hash, "SHA256 hash computed over body does not match body hash found in DKIM-signed header"
);

// hash the pubkey and signature for the standard outputs
standard_outputs(pubkey, signature)
Expand Down
17 changes: 13 additions & 4 deletions examples/verify_email_2048_bit_dkim/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use dep::zkemail::{
KEY_LIMBS_2048, dkim::verify_dkim_2048, body_hash::{get_body_hash_by_index, compare_body_hash},
KEY_LIMBS_2048, dkim::verify_dkim_2048, get_body_hash_by_index, base64::body_hash_base64_decode,
standard_outputs
};
use dep::std::hash::sha256_var;

global MAX_EMAIL_HEADER_LENGTH: u32 = 512;
global MAX_EMAIL_BODY_LENGTH: u32 = 1024;
Expand Down Expand Up @@ -38,11 +39,19 @@ fn main(
// verify the dkim signature over the header
verify_dkim_2048(header, header_length, pubkey, pubkey_redc, signature);

// manually extract the body hash from the header
// extract the body hash from the header
let body_hash_encoded = get_body_hash_by_index(header, body_hash_index);

// compare the retrieved body hash to the computed body hash
compare_body_hash(body_hash_encoded, body, body_length);
// base64 decode the body hash
let signed_body_hash: [u8; 32] = body_hash_base64_decode(body_hash_encoded);

// hash the asserted body
let computed_body_hash: [u8; 32] = sha256_var(body, body_length as u64);

// compare the body hashes
assert(
signed_body_hash == computed_body_hash, "SHA256 hash computed over body does not match body hash found in DKIM-signed header"
);

// hash the pubkey and signature for the standard outputs
standard_outputs(pubkey, signature)
Expand Down
2 changes: 1 addition & 1 deletion js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export function generateEmailVerifierInputsFromDKIMResult(
});

// idk why this gets out of sync, todo: fix
if (bodyRemaining.length != bodyRemainingLength) {
if (params.shaPrecomputeSelector && bodyRemaining.length != bodyRemainingLength) {
bodyRemaining = bodyRemaining.slice(0, bodyRemainingLength);
}

Expand Down
13 changes: 7 additions & 6 deletions js/tests/circuits.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ function makeProver(circuit: CompiledCircuit): Prover {
}

async function teardownProver(prover: Prover) {
await prover.barretenberg.destroy(), await prover.ultraHonk.destroy();
await prover.barretenberg.destroy();
await prover.ultraHonk.destroy();
}

describe("Fixed Size Circuit Input", () => {
Expand All @@ -57,8 +58,8 @@ describe("Fixed Size Circuit Input", () => {
teardownProver(prover2048);
teardownProver(proverPartialHash);
});
xdescribe("UltraHonk", () => {
xit("UltraHonk::SmallEmail", async () => {
describe("UltraHonk", () => {
it("UltraHonk::SmallEmail", async () => {
const inputs = await generateEmailVerifierInputs(
emails.small,
inputParams
Expand All @@ -81,7 +82,7 @@ describe("Fixed Size Circuit Input", () => {
});
});

xdescribe("UltraPlonk", () => {
describe("UltraPlonk", () => {
it("UltraPlonk::SmallEmail", async () => {
const inputs = await generateEmailVerifierInputs(
emails.small,
Expand Down Expand Up @@ -111,7 +112,7 @@ describe("Fixed Size Circuit Input", () => {
const inputs = await generateEmailVerifierInputs(emails.large, {
shaPrecomputeSelector: selectorText,
maxHeadersLength: 512,
maxBodyLength: 192
maxBodyLength: 192,
});
const { witness } = await proverPartialHash.noir.execute(inputs);
const proof = await proverPartialHash.barretenberg.generateProof(witness);
Expand All @@ -123,7 +124,7 @@ describe("Fixed Size Circuit Input", () => {
const inputs = await generateEmailVerifierInputs(emails.large, {
shaPrecomputeSelector: selectorText,
maxHeadersLength: 512,
maxBodyLength: 192
maxBodyLength: 192,
});
const { witness } = await proverPartialHash.noir.execute(inputs);
const proof = await proverPartialHash.ultraHonk.generateProof(witness);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/base64.nr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::BODY_HASH_BASE64_LENGTH;
* @param encoded - the base 64 encoded body hash
* @returns the decoded sha256 hash
*/
pub fn bodyhash_base64_decode(encoded: [u8; BODY_HASH_BASE64_LENGTH]) -> [u8; 32] {
pub fn body_hash_base64_decode(encoded: [u8; BODY_HASH_BASE64_LENGTH]) -> [u8; 32] {
let mut total_bits = [0 as u1; BODY_HASH_BASE64_LENGTH * 6];
for i in 0..BODY_HASH_BASE64_LENGTH {
let translate = base64_lookup(encoded[i] as u8);
Expand Down
62 changes: 0 additions & 62 deletions lib/src/body_hash.nr

This file was deleted.

33 changes: 32 additions & 1 deletion lib/src/lib.nr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use dep::std::hash::pedersen_hash;

mod dkim;
mod partial_hash;
mod body_hash;
mod base64;

global RSA_EXPONENT: u32 = 65537;
Expand All @@ -12,6 +11,38 @@ global KEY_LIMBS_1024: u32 = 9;
global KEY_LIMBS_2048: u32 = 18;
global BODY_HASH_BASE64_LENGTH: u32 = 44;

/**
* Get the body hash from the header by allowing circuit input to choose index
* @notice unsafe, can theoretically make a recipient display name = the bh
*
* @param HEADER_LENGTH - The length of the email header
* @param header - The email header as validated in the DKIM signature
* @param index - The asserted index to find the body hash at
* @returns The base 64 encoded body hash
*/
pub fn get_body_hash_by_index<let MAX_HEADER_LENGTH: u32>(
header: [u8; MAX_HEADER_LENGTH],
index: u32
) -> [u8; BODY_HASH_BASE64_LENGTH] {
// check index range
assert(index >= 3, "Index does not leave room for 'bh=' prefix");
assert(index + BODY_HASH_BASE64_LENGTH < MAX_HEADER_LENGTH, "Index does not leave room for body hash");
// check for 'bh=' prefix
let BH_PREFIX: [u8; 3] = [98, 104, 61]; // "bh="
for i in 0..3 {
assert(header[index - 3 + i] == BH_PREFIX[i], "No 'bh=' prefix found");
}
// check for base64 suffix
let BH_SUFFIX: u8 = 59; // ";"
assert(header[index + BODY_HASH_BASE64_LENGTH] == BH_SUFFIX, "No base64 suffix found");
// retrieve body hash
let mut body_hash = [0 as u8; BODY_HASH_BASE64_LENGTH];
for i in 0..BODY_HASH_BASE64_LENGTH {
body_hash[i] = header[index + i];
}
body_hash
}

/**
* Standard outputs that essentially every email circuit will need to export (alongside app-specific outputs)
* @notice if you only need the pubkey hash just import pedersen and hash away
Expand Down

0 comments on commit 3196238

Please sign in to comment.