o1js-email-verify
Version:
Implemented using [o1js](https://github.com/o1-labs/o1js), this project is a reimplementation of [zk-email](https://github.com/zkemail/zk-email-verify), leveraging the Mina proving system [Kimchi](https://o1-labs.github.io/proof-systems/specs/kimchi.html#
48 lines • 2.92 kB
JavaScript
import { Bytes, Provable, Poseidon } from 'o1js';
import { rsaVerify65537 } from 'o1js-rsa';
import { pkcs1v15Pad, bodyHashRegex, selectSubarray } from './utils.js';
import { dynamicSHA256, partialSHA256 } from 'dynamic-sha256';
export { emailVerify };
/**
* Verifies a DKIM signature using the provided message, signature, and public key.
*
* This function hashes the headers, encodes the hash using PKCS#1 v1.5, and verifies the RSA signature.
* If required, it also checks the body hash against the one provided in the email headers.
*
* @param paddedHeader - The padded header as Bytes to be verified.
* @param headerHashIndex - The index of the header hash within the padded header as Field.
* @param signature - The signature to be verified as Bigint2048.
* @param publicKey - The public key used for verification as Bigint2048.
* @param modulusLength - The length of the RSA modulus.
* @param bodyHashCheck - Boolean indicating whether to check the body hash.
* @param paddedBodyRemainingBytes - The remaining padded body bytes as Bytes.
* @param precomputedHash - The precomputed hash as Bytes.
* @param bodyHashIndex - The index of the body hash within the headers as Field.
* @param headerBodyHashIndex - The index of the body hash within the header hash as Field.
* @returns - The public key hash.
*/
function emailVerify(paddedHeader, headerHashIndex, signature, publicKey, modulusLength, bodyHashCheck, paddedBodyRemainingBytes, precomputedHash, bodyHashIndex, headerBodyHashIndex) {
// Hash the email headers // 92675 rows for a 1024-byte input
const headerHash = dynamicSHA256(paddedHeader, headerHashIndex);
// PKCS#1 v1.5 encode the hash
const message = pkcs1v15Pad(headerHash, Math.ceil(modulusLength / 8));
// Verify RSA65537 signature // 12401 rows
rsaVerify65537(message, signature, publicKey);
// 2. Check body hash
if (bodyHashCheck) {
// Compute the partial hash of the body // 139074 rows for a 1536-byte input
const computedBodyHash = partialSHA256(precomputedHash, paddedBodyRemainingBytes, bodyHashIndex);
// Base64 encode the computed body hash // 1697 rows for a 32-byte input
const encodedBodyHash = computedBodyHash.base64Encode();
// Reveal the body hash from the email headers using regex // 86453 rows for a 1024-byte input
const { out, reveal } = bodyHashRegex(paddedHeader.bytes);
out.assertEquals(1);
// Select the body hash bytes subarray // 59133 rows for a 1024-byte input
const headerBodyHash = Bytes.from(selectSubarray(reveal[0], headerBodyHashIndex, 44));
// Assert that the computed body hash matches the regex-fetched body hash from the header
Provable.assertEqual(encodedBodyHash, headerBodyHash);
}
const publickeyhash = Poseidon.hash(publicKey.fields);
return publickeyhash;
}
//# sourceMappingURL=email-verify.js.map