mirror of
https://github.com/zkemail/zk-email-verify.git
synced 2026-01-10 05:58:08 -05:00
moved files, fixing vercel errors
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -40,3 +40,4 @@ circuits/inputs/*test.json
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
out/
|
||||
|
||||
@@ -1,473 +0,0 @@
|
||||
// SHA-256 (+ HMAC and PBKDF2) for JavaScript.
|
||||
//
|
||||
// Written in 2014-2016 by Dmitry Chestnykh.
|
||||
// Public domain, no warranty.
|
||||
//
|
||||
// Functions (accept and return Uint8Arrays):
|
||||
//
|
||||
// sha256(message) -> hash
|
||||
// sha256.hmac(key, message) -> mac
|
||||
// sha256.pbkdf2(password, salt, rounds, dkLen) -> dk
|
||||
//
|
||||
// Classes:
|
||||
//
|
||||
// new sha256.Hash()
|
||||
// new sha256.HMAC(key)
|
||||
//
|
||||
export const digestLength: number = 32;
|
||||
export const blockSize: number = 64;
|
||||
|
||||
// SHA-256 constants
|
||||
const K = new Uint32Array([
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
|
||||
0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
|
||||
0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
|
||||
0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
|
||||
0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
||||
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
|
||||
0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
|
||||
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
|
||||
0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
|
||||
0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
]);
|
||||
|
||||
function hashBlocks(w: Int32Array, v: Int32Array, p: Uint8Array, pos: number, len: number): number {
|
||||
let a: number, b: number, c: number, d: number, e: number,
|
||||
f: number, g: number, h: number, u: number, i: number,
|
||||
j: number, t1: number, t2: number;
|
||||
while (len >= 64) {
|
||||
a = v[0];
|
||||
b = v[1];
|
||||
c = v[2];
|
||||
d = v[3];
|
||||
e = v[4];
|
||||
f = v[5];
|
||||
g = v[6];
|
||||
h = v[7];
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
j = pos + i * 4;
|
||||
w[i] = (((p[j] & 0xff) << 24) | ((p[j + 1] & 0xff) << 16) |
|
||||
((p[j + 2] & 0xff) << 8) | (p[j + 3] & 0xff));
|
||||
}
|
||||
|
||||
for (i = 16; i < 64; i++) {
|
||||
u = w[i - 2];
|
||||
t1 = (u >>> 17 | u << (32 - 17)) ^ (u >>> 19 | u << (32 - 19)) ^ (u >>> 10);
|
||||
|
||||
u = w[i - 15];
|
||||
t2 = (u >>> 7 | u << (32 - 7)) ^ (u >>> 18 | u << (32 - 18)) ^ (u >>> 3);
|
||||
|
||||
w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
t1 = (((((e >>> 6 | e << (32 - 6)) ^ (e >>> 11 | e << (32 - 11)) ^
|
||||
(e >>> 25 | e << (32 - 25))) + ((e & f) ^ (~e & g))) | 0) +
|
||||
((h + ((K[i] + w[i]) | 0)) | 0)) | 0;
|
||||
|
||||
t2 = (((a >>> 2 | a << (32 - 2)) ^ (a >>> 13 | a << (32 - 13)) ^
|
||||
(a >>> 22 | a << (32 - 22))) + ((a & b) ^ (a & c) ^ (b & c))) | 0;
|
||||
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = (d + t1) | 0;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = (t1 + t2) | 0;
|
||||
}
|
||||
|
||||
v[0] += a;
|
||||
v[1] += b;
|
||||
v[2] += c;
|
||||
v[3] += d;
|
||||
v[4] += e;
|
||||
v[5] += f;
|
||||
v[6] += g;
|
||||
v[7] += h;
|
||||
|
||||
pos += 64;
|
||||
len -= 64;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Hash implements SHA256 hash algorithm.
|
||||
export class Hash {
|
||||
digestLength: number = digestLength;
|
||||
blockSize: number = blockSize;
|
||||
|
||||
// Note: Int32Array is used instead of Uint32Array for performance reasons.
|
||||
private state: Int32Array = new Int32Array(8); // hash state
|
||||
private temp: Int32Array = new Int32Array(64); // temporary state
|
||||
private buffer: Uint8Array = new Uint8Array(128); // buffer for data to hash
|
||||
private bufferLength: number = 0; // number of bytes in buffer
|
||||
private bytesHashed: number = 0; // number of total bytes hashed
|
||||
|
||||
finished: boolean = false; // indicates whether the hash was finalized
|
||||
|
||||
constructor() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
// Resets hash state making it possible
|
||||
// to re-use this instance to hash other data.
|
||||
reset(): this {
|
||||
this.state[0] = 0x6a09e667;
|
||||
this.state[1] = 0xbb67ae85;
|
||||
this.state[2] = 0x3c6ef372;
|
||||
this.state[3] = 0xa54ff53a;
|
||||
this.state[4] = 0x510e527f;
|
||||
this.state[5] = 0x9b05688c;
|
||||
this.state[6] = 0x1f83d9ab;
|
||||
this.state[7] = 0x5be0cd19;
|
||||
this.bufferLength = 0;
|
||||
this.bytesHashed = 0;
|
||||
this.finished = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Cleans internal buffers and re-initializes hash state.
|
||||
clean() {
|
||||
for (let i = 0; i < this.buffer.length; i++) {
|
||||
this.buffer[i] = 0;
|
||||
}
|
||||
for (let i = 0; i < this.temp.length; i++) {
|
||||
this.temp[i] = 0;
|
||||
}
|
||||
this.reset();
|
||||
}
|
||||
|
||||
// Updates hash state with the given data.
|
||||
//
|
||||
// Optionally, length of the data can be specified to hash
|
||||
// fewer bytes than data.length.
|
||||
//
|
||||
// Throws error when trying to update already finalized hash:
|
||||
// instance must be reset to use it again.
|
||||
update(data: Uint8Array, dataLength: number = data.length): this {
|
||||
if (this.finished) {
|
||||
throw new Error("SHA256: can't update because hash was finished.");
|
||||
}
|
||||
let dataPos = 0;
|
||||
this.bytesHashed += dataLength;
|
||||
if (this.bufferLength > 0) {
|
||||
while (this.bufferLength < 64 && dataLength > 0) {
|
||||
this.buffer[this.bufferLength++] = data[dataPos++];
|
||||
dataLength--;
|
||||
}
|
||||
if (this.bufferLength === 64) {
|
||||
hashBlocks(this.temp, this.state, this.buffer, 0, 64);
|
||||
this.bufferLength = 0;
|
||||
}
|
||||
}
|
||||
if (dataLength >= 64) {
|
||||
dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength);
|
||||
dataLength %= 64;
|
||||
}
|
||||
while (dataLength > 0) {
|
||||
this.buffer[this.bufferLength++] = data[dataPos++];
|
||||
dataLength--;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Finalizes hash state and puts hash into out.
|
||||
//
|
||||
// If hash was already finalized, puts the same value.
|
||||
finish(out: Uint8Array): this {
|
||||
if (!this.finished) {
|
||||
const bytesHashed = this.bytesHashed;
|
||||
const left = this.bufferLength;
|
||||
const bitLenHi = (bytesHashed / 0x20000000) | 0;
|
||||
const bitLenLo = bytesHashed << 3;
|
||||
const padLength = (bytesHashed % 64 < 56) ? 64 : 128;
|
||||
|
||||
this.buffer[left] = 0x80;
|
||||
for (let i = left + 1; i < padLength - 8; i++) {
|
||||
this.buffer[i] = 0;
|
||||
}
|
||||
this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;
|
||||
this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;
|
||||
this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;
|
||||
this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;
|
||||
this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;
|
||||
this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;
|
||||
this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;
|
||||
this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;
|
||||
|
||||
hashBlocks(this.temp, this.state, this.buffer, 0, padLength);
|
||||
|
||||
this.finished = true;
|
||||
}
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff;
|
||||
out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;
|
||||
out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;
|
||||
out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Returns the final hash digest.
|
||||
digest(): Uint8Array {
|
||||
const out = new Uint8Array(this.digestLength);
|
||||
this.finish(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Returns the current hash state.
|
||||
cacheState(): Uint8Array {
|
||||
const out32 = new Uint32Array(this.state.length);
|
||||
this._saveState(out32);
|
||||
const out = new Uint8Array(this.state.length * 4);
|
||||
for (let i = 0; i < 8; i++) {
|
||||
out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff;
|
||||
out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;
|
||||
out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;
|
||||
out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Internal function for use in HMAC for optimization.
|
||||
_saveState(out: Uint32Array) {
|
||||
for (let i = 0; i < this.state.length; i++) {
|
||||
out[i] = this.state[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Internal function for use in HMAC for optimization.
|
||||
_restoreState(from: Uint32Array, bytesHashed: number) {
|
||||
for (let i = 0; i < this.state.length; i++) {
|
||||
this.state[i] = from[i];
|
||||
}
|
||||
this.bytesHashed = bytesHashed;
|
||||
this.finished = false;
|
||||
this.bufferLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// HMAC implements HMAC-SHA256 message authentication algorithm.
|
||||
export class HMAC {
|
||||
private inner: Hash = new Hash();
|
||||
private outer: Hash = new Hash();
|
||||
|
||||
blockSize: number = this.inner.blockSize;
|
||||
digestLength: number = this.inner.digestLength;
|
||||
|
||||
// Copies of hash states after keying.
|
||||
// Need for quick reset without hashing they key again.
|
||||
private istate: Uint32Array;
|
||||
private ostate: Uint32Array;
|
||||
|
||||
constructor(key: Uint8Array) {
|
||||
const pad = new Uint8Array(this.blockSize);
|
||||
if (key.length > this.blockSize) {
|
||||
(new Hash()).update(key).finish(pad).clean();
|
||||
} else {
|
||||
for (let i = 0; i < key.length; i++) {
|
||||
pad[i] = key[i];
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < pad.length; i++) {
|
||||
pad[i] ^= 0x36;
|
||||
}
|
||||
this.inner.update(pad);
|
||||
|
||||
for (let i = 0; i < pad.length; i++) {
|
||||
pad[i] ^= 0x36 ^ 0x5c;
|
||||
}
|
||||
this.outer.update(pad);
|
||||
|
||||
this.istate = new Uint32Array(8);
|
||||
this.ostate = new Uint32Array(8);
|
||||
|
||||
this.inner._saveState(this.istate);
|
||||
this.outer._saveState(this.ostate);
|
||||
|
||||
for (let i = 0; i < pad.length; i++) {
|
||||
pad[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns HMAC state to the state initialized with key
|
||||
// to make it possible to run HMAC over the other data with the same
|
||||
// key without creating a new instance.
|
||||
reset(): this {
|
||||
this.inner._restoreState(this.istate, this.inner.blockSize);
|
||||
this.outer._restoreState(this.ostate, this.outer.blockSize);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Cleans HMAC state.
|
||||
clean() {
|
||||
for (let i = 0; i < this.istate.length; i++) {
|
||||
this.ostate[i] = this.istate[i] = 0;
|
||||
}
|
||||
this.inner.clean();
|
||||
this.outer.clean();
|
||||
}
|
||||
|
||||
// Updates state with provided data.
|
||||
update(data: Uint8Array): this {
|
||||
this.inner.update(data);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Finalizes HMAC and puts the result in out.
|
||||
finish(out: Uint8Array): this {
|
||||
if (this.outer.finished) {
|
||||
this.outer.finish(out);
|
||||
} else {
|
||||
this.inner.finish(out);
|
||||
this.outer.update(out, this.digestLength).finish(out);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Returns message authentication code.
|
||||
digest(): Uint8Array {
|
||||
const out = new Uint8Array(this.digestLength);
|
||||
this.finish(out);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns SHA256 hash of data.
|
||||
export function hash(data: Uint8Array): Uint8Array {
|
||||
const h = (new Hash()).update(data);
|
||||
const digest = h.digest();
|
||||
h.clean();
|
||||
return digest;
|
||||
}
|
||||
|
||||
// Function hash is both available as module.hash and as default export.
|
||||
export default hash;
|
||||
|
||||
// Returns HMAC-SHA256 of data under the key.
|
||||
export function hmac(key: Uint8Array, data: Uint8Array) {
|
||||
const h = (new HMAC(key)).update(data);
|
||||
const digest = h.digest();
|
||||
h.clean();
|
||||
return digest;
|
||||
}
|
||||
|
||||
// Fills hkdf buffer like this:
|
||||
// T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
|
||||
function fillBuffer(buffer: Uint8Array, hmac: HMAC, info: Uint8Array | undefined, counter: Uint8Array) {
|
||||
// Counter is a byte value: check if it overflowed.
|
||||
const num = counter[0];
|
||||
|
||||
if (num === 0) {
|
||||
throw new Error("hkdf: cannot expand more");
|
||||
}
|
||||
|
||||
// Prepare HMAC instance for new data with old key.
|
||||
hmac.reset();
|
||||
|
||||
// Hash in previous output if it was generated
|
||||
// (i.e. counter is greater than 1).
|
||||
if (num > 1) {
|
||||
hmac.update(buffer);
|
||||
}
|
||||
|
||||
// Hash in info if it exists.
|
||||
if (info) {
|
||||
hmac.update(info);
|
||||
}
|
||||
|
||||
// Hash in the counter.
|
||||
hmac.update(counter);
|
||||
|
||||
// Output result to buffer and clean HMAC instance.
|
||||
hmac.finish(buffer);
|
||||
|
||||
// Increment counter inside typed array, this works properly.
|
||||
counter[0]++;
|
||||
}
|
||||
|
||||
const hkdfSalt = new Uint8Array(digestLength); // Filled with zeroes.
|
||||
export function hkdf(key: Uint8Array, salt: Uint8Array = hkdfSalt, info?: Uint8Array, length: number = 32) {
|
||||
const counter = new Uint8Array([1]);
|
||||
|
||||
// HKDF-Extract uses salt as HMAC key, and key as data.
|
||||
const okm = hmac(salt, key);
|
||||
|
||||
// Initialize HMAC for expanding with extracted key.
|
||||
// Ensure no collisions with `hmac` function.
|
||||
const hmac_ = new HMAC(okm);
|
||||
|
||||
// Allocate buffer.
|
||||
const buffer = new Uint8Array(hmac_.digestLength);
|
||||
let bufpos = buffer.length;
|
||||
|
||||
const out = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (bufpos === buffer.length) {
|
||||
fillBuffer(buffer, hmac_, info, counter);
|
||||
bufpos = 0;
|
||||
}
|
||||
out[i] = buffer[bufpos++];
|
||||
}
|
||||
|
||||
hmac_.clean();
|
||||
buffer.fill(0);
|
||||
counter.fill(0);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Derives a key from password and salt using PBKDF2-HMAC-SHA256
|
||||
// with the given number of iterations.
|
||||
//
|
||||
// The number of bytes returned is equal to dkLen.
|
||||
//
|
||||
// (For better security, avoid dkLen greater than hash length - 32 bytes).
|
||||
export function pbkdf2(password: Uint8Array, salt: Uint8Array, iterations: number, dkLen: number) {
|
||||
const prf = new HMAC(password);
|
||||
const len = prf.digestLength;
|
||||
const ctr = new Uint8Array(4);
|
||||
const t = new Uint8Array(len);
|
||||
const u = new Uint8Array(len);
|
||||
const dk = new Uint8Array(dkLen);
|
||||
|
||||
for (let i = 0; i * len < dkLen; i++) {
|
||||
let c = i + 1;
|
||||
ctr[0] = (c >>> 24) & 0xff;
|
||||
ctr[1] = (c >>> 16) & 0xff;
|
||||
ctr[2] = (c >>> 8) & 0xff;
|
||||
ctr[3] = (c >>> 0) & 0xff;
|
||||
prf.reset();
|
||||
prf.update(salt);
|
||||
prf.update(ctr);
|
||||
prf.finish(u);
|
||||
for (let j = 0; j < len; j++) {
|
||||
t[j] = u[j];
|
||||
}
|
||||
for (let j = 2; j <= iterations; j++) {
|
||||
prf.reset();
|
||||
prf.update(u).finish(u);
|
||||
for (let k = 0; k < len; k++) {
|
||||
t[k] ^= u[k];
|
||||
}
|
||||
}
|
||||
for (let j = 0; j < len && i * len + j < dkLen; j++) {
|
||||
dk[i * len + j] = t[j];
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < len; i++) {
|
||||
t[i] = u[i] = 0;
|
||||
}
|
||||
for (let i = 0; i < 4; i++) {
|
||||
ctr[i] = 0;
|
||||
}
|
||||
prf.clean();
|
||||
return dk;
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
import { bytesToBigInt, stringToBytes, toCircomBigIntBytes } from "../../src/helpers/binaryFormat";
|
||||
import {
|
||||
AAYUSH_EMAIL_SIG,
|
||||
AAYUSH_EMAIL_MODULUS,
|
||||
AAYUSH_POSTHASH_MESSAGE_PADDED_INT,
|
||||
AAYUSH_PREHASH_MESSAGE_INT,
|
||||
AAYUSH_PREHASH_MESSAGE_STRING,
|
||||
CIRCOM_FIELD_MODULUS,
|
||||
MAX_HEADER_PADDED_BYTES,
|
||||
MAX_BODY_PADDED_BYTES,
|
||||
STRING_PRESELECTOR,
|
||||
} from "../../src/helpers/constants";
|
||||
import { shaHash } from "../../src/helpers/shaHash";
|
||||
import { dkimVerify } from "../../src/helpers/dkim";
|
||||
import { assert } from "console";
|
||||
import { Hash } from "./fast-sha256"
|
||||
import * as fs from "fs";
|
||||
var Cryo = require('cryo');
|
||||
const pki = require("node-forge").pki;
|
||||
|
||||
interface ICircuitInputs {
|
||||
modulus?: string[];
|
||||
signature?: string[];
|
||||
base_message?: string[];
|
||||
in_padded?: string[];
|
||||
in_body_padded?: string[];
|
||||
in_body_len_padded_bytes?: string[];
|
||||
in_padded_n_bytes?: string[];
|
||||
in_len_padded_bytes?: string[];
|
||||
in_body_hash?: string[];
|
||||
precomputed_sha?: string[];
|
||||
}
|
||||
|
||||
enum CircuitType {
|
||||
RSA = "rsa",
|
||||
SHA = "sha",
|
||||
TEST = "test",
|
||||
EMAIL = "email",
|
||||
}
|
||||
|
||||
// Works only on 32 bit sha text lengths
|
||||
function int32toBytes(num: number): Uint8Array {
|
||||
let arr = new ArrayBuffer(4); // an Int32 takes 4 bytes
|
||||
let view = new DataView(arr);
|
||||
view.setUint32(0, num, false); // byteOffset = 0; litteEndian = false
|
||||
return new Uint8Array(arr);
|
||||
}
|
||||
|
||||
// Works only on 32 bit sha text lengths
|
||||
function int8toBytes(num: number): Uint8Array {
|
||||
let arr = new ArrayBuffer(1); // an Int8 takes 4 bytes
|
||||
let view = new DataView(arr);
|
||||
view.setUint8(0, num); // byteOffset = 0; litteEndian = false
|
||||
return new Uint8Array(arr);
|
||||
}
|
||||
|
||||
function mergeUInt8Arrays(a1: Uint8Array, a2: Uint8Array): Uint8Array {
|
||||
// sum of individual array lengths
|
||||
var mergedArray = new Uint8Array(a1.length + a2.length);
|
||||
mergedArray.set(a1);
|
||||
mergedArray.set(a2, a1.length);
|
||||
return mergedArray;
|
||||
}
|
||||
|
||||
// Puts an end selector, a bunch of 0s, then the length, then fill the rest with 0s.
|
||||
async function sha256Pad(prehash_prepad_m: Uint8Array, maxShaBytes: number): Promise<[Uint8Array, number]> {
|
||||
|
||||
let length_bits = prehash_prepad_m.length * 8; // bytes to bits
|
||||
let length_in_bytes = int32toBytes(length_bits);
|
||||
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int8toBytes(2 ** 7));
|
||||
while ((prehash_prepad_m.length * 8 + length_in_bytes.length * 8) % 512 !== 0) {
|
||||
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int8toBytes(0));
|
||||
}
|
||||
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, length_in_bytes);
|
||||
console.assert((prehash_prepad_m.length * 8) % 512 === 0, "Padding did not complete properly!");
|
||||
let messageLen = prehash_prepad_m.length;
|
||||
while (prehash_prepad_m.length < maxShaBytes) {
|
||||
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int32toBytes(0));
|
||||
}
|
||||
console.assert(prehash_prepad_m.length === maxShaBytes, "Padding to max length did not complete properly!");
|
||||
|
||||
return [prehash_prepad_m, messageLen];
|
||||
}
|
||||
|
||||
async function Uint8ArrayToCharArray(a: Uint8Array): Promise<string[]> {
|
||||
return Array.from(a).map((x) => x.toString());
|
||||
}
|
||||
|
||||
async function Uint8ArrayToString(a: Uint8Array): Promise<string> {
|
||||
return Array.from(a).map((x) => x.toString()).join(";");
|
||||
}
|
||||
|
||||
async function findSelector(a: Uint8Array, selector: number[]): Promise<number> {
|
||||
let i = 0;
|
||||
let j = 0;
|
||||
while (i < a.length) {
|
||||
if (a[i] === selector[j]) {
|
||||
j++;
|
||||
if (j === selector.length) {
|
||||
return i - j + 1;
|
||||
}
|
||||
} else {
|
||||
j = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
async function partialSha(msg:Uint8Array, msgLen: number): Promise<Uint8Array> {
|
||||
const shaGadget = new Hash();
|
||||
return await shaGadget.update(msg, msgLen).cacheState()
|
||||
}
|
||||
|
||||
export async function getCircuitInputs(
|
||||
rsa_signature: BigInt,
|
||||
rsa_modulus: BigInt,
|
||||
message: Buffer,
|
||||
body: Buffer,
|
||||
body_hash: string,
|
||||
circuit: CircuitType
|
||||
): Promise<{
|
||||
valid: {
|
||||
validSignatureFormat?: boolean;
|
||||
validMessage?: boolean;
|
||||
};
|
||||
circuitInputs?: ICircuitInputs;
|
||||
}> {
|
||||
// Derive modulus from signature
|
||||
// const modulusBigInt = bytesToBigInt(pubKeyParts[2]);
|
||||
const modulusBigInt = rsa_modulus;
|
||||
const prehash_message_string = message;
|
||||
const baseMessageBigInt = AAYUSH_PREHASH_MESSAGE_INT; // bytesToBigInt(stringToBytes(message)) ||
|
||||
const postShaBigint = AAYUSH_POSTHASH_MESSAGE_PADDED_INT;
|
||||
const signatureBigInt = rsa_signature;
|
||||
|
||||
// Perform conversions
|
||||
const prehashBytesUnpadded = typeof prehash_message_string == "string" ? new TextEncoder().encode(prehash_message_string) : Uint8Array.from(prehash_message_string);
|
||||
const postShaBigintUnpadded = bytesToBigInt(stringToBytes((await shaHash(prehashBytesUnpadded)).toString())) % CIRCOM_FIELD_MODULUS;
|
||||
|
||||
// Sha add padding
|
||||
const [messagePadded, messagePaddedLen] = await sha256Pad(prehashBytesUnpadded, MAX_HEADER_PADDED_BYTES);
|
||||
const [bodyPadded, bodyPaddedLen] = await sha256Pad(body, MAX_BODY_PADDED_BYTES);
|
||||
|
||||
// Precompute SHA prefix
|
||||
const selector = STRING_PRESELECTOR.split('').map(char => char.charCodeAt(0))
|
||||
console.log(await findSelector(bodyPadded, selector));
|
||||
let shaCutoffIndex = Math.floor(((await findSelector(bodyPadded, selector)) / 512)) * 512;
|
||||
const precomputeText = bodyPadded.slice(0, shaCutoffIndex);
|
||||
const bodyShaPrecompute = bytesToBigInt(stringToBytes((await partialSha(precomputeText, shaCutoffIndex)).toString())) % CIRCOM_FIELD_MODULUS;
|
||||
console.log(bodyShaPrecompute);
|
||||
|
||||
// Ensure SHA manual unpadded is running the correct function
|
||||
const shaOut = await partialSha(messagePadded, messagePaddedLen);
|
||||
assert(await Uint8ArrayToString(shaOut) === await Uint8ArrayToString(Uint8Array.from(await shaHash(prehashBytesUnpadded))), "SHA256 calculation did not match!");
|
||||
|
||||
// Compute identity revealer
|
||||
let circuitInputs;
|
||||
const modulus = toCircomBigIntBytes(modulusBigInt);
|
||||
const signature = toCircomBigIntBytes(signatureBigInt);
|
||||
const in_len_padded_bytes = await Uint8ArrayToCharArray(stringToBytes(messagePaddedLen.toString()));
|
||||
const in_padded = await Uint8ArrayToCharArray(messagePadded); // Packed into 1 byte signals
|
||||
const in_body_len_padded_bytes = await Uint8ArrayToCharArray(stringToBytes(bodyPaddedLen.toString()));
|
||||
const in_body_padded = await Uint8ArrayToCharArray(bodyPadded);
|
||||
const base_message = toCircomBigIntBytes(postShaBigintUnpadded);
|
||||
const precomputed_sha = toCircomBigIntBytes(bodyShaPrecompute);
|
||||
let body_hash_idx = message.indexOf(Buffer.from(body_hash));
|
||||
|
||||
if (circuit === CircuitType.RSA) {
|
||||
circuitInputs = {
|
||||
modulus,
|
||||
signature,
|
||||
base_message,
|
||||
};
|
||||
} else if (circuit === CircuitType.EMAIL) {
|
||||
circuitInputs = {
|
||||
modulus,
|
||||
signature,
|
||||
in_padded,
|
||||
in_len_padded_bytes,
|
||||
in_body_padded,
|
||||
in_body_len_padded_bytes,
|
||||
precomputed_sha
|
||||
body_hash_idx
|
||||
};
|
||||
} else if (circuit === CircuitType.SHA) {
|
||||
circuitInputs = {
|
||||
in_padded,
|
||||
in_len_padded_bytes,
|
||||
precomputed_sha
|
||||
};
|
||||
}
|
||||
return {
|
||||
circuitInputs,
|
||||
valid: {},
|
||||
};
|
||||
}
|
||||
|
||||
export async function generate_inputs(email: Buffer) {
|
||||
var result;
|
||||
try {
|
||||
result = await dkimVerify(email);
|
||||
const _ = result.results[0].publicKey.toString();
|
||||
var frozen = Cryo.stringify(result);
|
||||
fs.writeFileSync(`./email_cache.json`, frozen, { flag: "w" });
|
||||
} catch (e) {
|
||||
console.log("Reading cached email instead!")
|
||||
let frozen = fs.readFileSync(`./email_cache.json`, { encoding: "utf-8" });
|
||||
result = Cryo.parse(frozen);
|
||||
}
|
||||
|
||||
let sig = BigInt("0x" + Buffer.from(result.results[0].signature, "base64").toString("hex"));
|
||||
let message = result.results[0].status.signature_header;
|
||||
let body = result.results[0].body;
|
||||
let body_hash = result.results[0].bodyHash;
|
||||
let circuitType = CircuitType.EMAIL;
|
||||
|
||||
let pubkey = result.results[0].publicKey;
|
||||
const pubKeyData = pki.publicKeyFromPem(pubkey.toString());
|
||||
let modulus = BigInt(pubKeyData.n.toString());
|
||||
let fin_result = await getCircuitInputs(sig, modulus, message, body, body_hash, circuitType);
|
||||
fs.writeFileSync(`./circuits/inputs/input_twitter.json`, JSON.stringify(fin_result.circuitInputs), { flag: "w" });
|
||||
return fin_result.circuitInputs;
|
||||
}
|
||||
|
||||
async function do_generate() {
|
||||
const email = fs.readFileSync("./twitter_msg.eml");
|
||||
console.log(JSON.stringify(await generate_inputs(email)));
|
||||
}
|
||||
|
||||
do_generate();
|
||||
@@ -15,6 +15,7 @@
|
||||
"circomlib": "^2.0.3",
|
||||
"circomlibjs": "^0.1.2",
|
||||
"cryo": "^0.0.6",
|
||||
"forge-std": "^1.1.2",
|
||||
"libmime": "^5.1.0",
|
||||
"localforage": "^1.10.0",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -30,6 +31,7 @@
|
||||
"react-router-dom": "^6.2.2",
|
||||
"react-scripts": "^4",
|
||||
"react-use": "^17.3.2",
|
||||
"readline": "^1.3.0",
|
||||
"snarkjs": "^0.5.0",
|
||||
"sshpk": "^1.17.0",
|
||||
"styled-components": "^5.3.5",
|
||||
|
||||
@@ -37,34 +37,23 @@ contract VerifiedEmail is ERC721Enumerable, Verifier {
|
||||
verifiedMailserverKeys["mit.edu"][16] = 343542034344264361438243465247009;
|
||||
}
|
||||
|
||||
// function getDesc(
|
||||
// address origin,
|
||||
// address sink,
|
||||
// uint256 degree
|
||||
// ) private view returns (string memory) {
|
||||
// // convert address to string
|
||||
// string memory originStr = toString(origin);
|
||||
// string memory sinkStr = toString(sink);
|
||||
// // concatenate strings
|
||||
// string memory result = string(
|
||||
// abi.encodePacked(
|
||||
// sinkStr,
|
||||
// "is ",
|
||||
// toString(degree),
|
||||
// "th degree friends with ",
|
||||
// originStr
|
||||
// )
|
||||
// );
|
||||
function getDesc(
|
||||
address origin,
|
||||
address sink,
|
||||
uint256 degree
|
||||
) private view returns (string memory) {
|
||||
// convert address to string
|
||||
string memory originStr = toString(origin);
|
||||
string memory sinkStr = toString(sink);
|
||||
// concatenate strings
|
||||
string memory result = string(abi.encodePacked(sinkStr, "is ", toString(degree), "th degree friends with ", originStr));
|
||||
|
||||
// return result;
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
// function tokenDesc(uint256 tokenId) public view returns (string memory) {
|
||||
// address origin = originAddress[tokenId];
|
||||
// address sink = sinkAddress[tokenId];
|
||||
// uint256 degree = degree[tokenId];
|
||||
// return getDesc(origin, sink, degree);
|
||||
// }
|
||||
function tokenDesc(uint256 tokenId) public view returns (string memory) {
|
||||
return string(abi.encodePacked(toString(tokenId)));
|
||||
}
|
||||
|
||||
function tokenURI(uint256 tokenId) public view override returns (string memory) {
|
||||
string[3] memory parts;
|
||||
@@ -87,7 +76,7 @@ contract VerifiedEmail is ERC721Enumerable, Verifier {
|
||||
'", "tokenId": ',
|
||||
toString(tokenId),
|
||||
"}",
|
||||
'", "description": "VerifiedEmails are ZK verified proofs of email ownership on Ethereum. They only reveal your email domain, nothing about your identity. We can construct both goods like Glassdoor and Blind, and terrible tragedy of the commons scenarios where instituition reputation is slowly spent by its members. VerifiedEmail uses ZK SNARKs to insinuate this social dynamic.", "image": "data:image/svg+xml;base64,',
|
||||
'", "description": "VerifiedEmailIDs are ZK verified proofs of email ownership on Ethereum. They only reveal your email domain, nothing about your identity. We can usee this to create trustless oracles, decentralized anonymous KYC, permission-free integration with every company, and secret three letter spying org leaks. VerifiedEmailIDs use ZK SNARKs to insinuate this debauchery. @personae_labs on Twitter for more alpha.", "image": "data:image/svg+xml;base64,',
|
||||
Base64.encode(bytes(output)),
|
||||
'"}'
|
||||
)
|
||||
@@ -203,6 +192,8 @@ contract VerifiedEmail is ERC721Enumerable, Verifier {
|
||||
for (uint32 i = msg_len - 17; i < msg_len; i++) {
|
||||
require(signals[i] == verifiedMailserverKeys[domain][i], "Invalid modulus not matched");
|
||||
}
|
||||
|
||||
// ENSURE THE FOLLOWING IS UNCOMMENTED
|
||||
require(verifyProof(a, b, c, signals), "Invalid Proof"); // checks effects iteractions, this should come first
|
||||
|
||||
uint256 tokenId = tokenCounter.current() + 1;
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.fromHex = exports.toHex = exports.toCircomBigIntBytes = exports.bytesToBigInt = exports.stringToBytes = void 0;
|
||||
var constants_1 = require("./constants");
|
||||
function stringToBytes(str) {
|
||||
return Uint8Array.from(str, function (x) { return x.charCodeAt(0); });
|
||||
}
|
||||
exports.stringToBytes = stringToBytes;
|
||||
function bytesToBigInt(bytes) {
|
||||
var res = 0n;
|
||||
for (var i = 0; i < bytes.length; ++i) {
|
||||
res = (res << 8n) + BigInt(bytes[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
exports.bytesToBigInt = bytesToBigInt;
|
||||
function toCircomBigIntBytes(num) {
|
||||
var res = [];
|
||||
var msk = (1n << BigInt(constants_1.CIRCOM_BIGINT_N)) - 1n;
|
||||
for (var i = 0; i < constants_1.CIRCOM_BIGINT_K; ++i) {
|
||||
res.push(((num >> BigInt(i * constants_1.CIRCOM_BIGINT_N)) & msk).toString());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
exports.toCircomBigIntBytes = toCircomBigIntBytes;
|
||||
// https://stackoverflow.com/a/69585881
|
||||
var HEX_STRINGS = "0123456789abcdef";
|
||||
var MAP_HEX = {
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 3,
|
||||
4: 4,
|
||||
5: 5,
|
||||
6: 6,
|
||||
7: 7,
|
||||
8: 8,
|
||||
9: 9,
|
||||
a: 10,
|
||||
b: 11,
|
||||
c: 12,
|
||||
d: 13,
|
||||
e: 14,
|
||||
f: 15,
|
||||
A: 10,
|
||||
B: 11,
|
||||
C: 12,
|
||||
D: 13,
|
||||
E: 14,
|
||||
F: 15
|
||||
};
|
||||
// Fast Uint8Array to hex
|
||||
function toHex(bytes) {
|
||||
return Array.from(bytes || [])
|
||||
.map(function (b) { return HEX_STRINGS[b >> 4] + HEX_STRINGS[b & 15]; })
|
||||
.join("");
|
||||
}
|
||||
exports.toHex = toHex;
|
||||
// Mimics Buffer.from(x, 'hex') logic
|
||||
// Stops on first non-hex string and returns
|
||||
// https://github.com/nodejs/node/blob/v14.18.1/src/string_bytes.cc#L246-L261
|
||||
function fromHex(hexString) {
|
||||
var bytes = new Uint8Array(Math.floor((hexString || "").length / 2));
|
||||
var i;
|
||||
for (i = 0; i < bytes.length; i++) {
|
||||
var a = MAP_HEX[hexString[i * 2]];
|
||||
var b = MAP_HEX[hexString[i * 2 + 1]];
|
||||
if (a === undefined || b === undefined) {
|
||||
break;
|
||||
}
|
||||
bytes[i] = (a << 4) | b;
|
||||
}
|
||||
return i === bytes.length ? bytes : bytes.slice(0, i);
|
||||
}
|
||||
exports.fromHex = fromHex;
|
||||
@@ -1,6 +1,5 @@
|
||||
// @ts-ignore
|
||||
import React, { useMemo } from "react";
|
||||
import { useState } from "react";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useAsync, useMount, useUpdateEffect } from "react-use";
|
||||
// @ts-ignore
|
||||
// @ts-ignore
|
||||
@@ -32,7 +31,7 @@ import localforage from "localforage";
|
||||
import { dkimVerify } from '../helpers/dkim';
|
||||
import atob from "atob";
|
||||
import { downloadProofFiles, generateProof, verifyProof, buildInput } from '../helpers/zkp';
|
||||
const generate_input = require('../helpers/generate_input');
|
||||
const generate_input = require('../scripts/generate_input');
|
||||
|
||||
const demoUrl =
|
||||
"/?message=I%20like%20cats&group_name=https%3A%2F%2Fgithub.com%2Forgs%2Fdoubleblind-xyz%2Fpeople&group_members=ssh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAACAQCq8ZasN4NVES99%2B9XRhFLkuT4deiyen01D5nWt8%2FBoqdcCW0jH%2FLLiew%2FxVQ7%2FmMYmEg%2Fw6In8kUMJTCd7oXBDYHNBGxhuIqKEDh15yN5loQykW8YCA74m8V6fdnZ22krFGS%2FnixYr19xEJ2cY28Jq8QNO03421T4QiZsqB8LcMOfMvVPzU96UWHR16LW1Lgj7pGLwbP%2FDBQRWn%2BAlaSYi%2FyHgCit9GgqOf2O7JqQ01p7d9AlBHyTPfDJHJOosKMKiwNwP4Rwyir%2FKeRde65v%2FMqRnBWoQogjTNAylyCMOUDhNZQbiF8ttIynY2xtg5i52Qc9qY%2FBZAk1J%2FSK8MjEae4o8JU%2BfwBGH4aXDLx5AGwD5EHm95M2WiEu8kvcGv%2BbnPp4OED8W2pvoI8Q0PmYJ8WC6vebM4fOg9dnvZ52jUb5mpfWmUy0%2FPeOPyxsfTjpptirNhJUpWWdhDfPNxT19jSka4BYlhHEVXeR1%2BepBXe7z1m0w4RMVFHyDvsr1gUlcWjO9ufccdqNnNjrWcKLIm455RJivh8V1JC%2F2mJdMrYGKf54%2FOXa%2BEMcRpgKO1kjhqDCMitA8IVa8bcVFcvwmB1myoondETeO7bdGIVBMV1o8H%2BU6GL29p%2B5nKzKWUN1IRPgIuMS80sq7MDBkKChzQxJHE%2FhhkszQvAgR9OdzjQ%3D%3D%20scott%0Assh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAABAQCqu5UxDsmcu7ibKB20ucaYyEsk1EDAa5uXfyDJiH30x4t%2FXwS7b7qdegO1HlvfE1HA7iPqjtbWj70qwDFJwwGazxze33J1oh%2FLMKfPUzZ32y8tRU0JHR9nHZHMOcoUYPNeXLVDh6jdEX3%2B2%2FodIbSVbu54wUF5j6q7iAv%2B6Ch9qcMaO9vPEt3z6QX5LnUAqvCwu5sUgobWB7I10iGD4jFYDL%2Ff22pOGK%2BKyW26vkMh%2Fcg8FNC07ilRiYqQIxfdj7lWaYbO0VhxhQtTH5HcgQ2bAWZ6Rp9%2FcXOAegboV2dxjQ%2FuIumcdaqkXeHNypC3j%2F6%2BTBi5BFMQit8gy1H9R86x%20scott%0A%0Assh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAABAQDRvpOL7TZcYtHsSSz4lj8vTyIEuFSQnUqHTxhhsEWzAbq9LHMqYm4Whg1oRm430QvJF5xfOaLk%2BbmO6hN1g4Y9yJUj4uhaNSfSl3wGLBxu5OQNngnIDCbxTLjat4Jgz79ZiAo79c6bVq13xcfG0fjtFoC3FbZD0VEmqmwd%2FlYCLLVqtjccQur8B56O9Pj%2FgiDMby0iQPFEe9vlpP8Wg3WVjFRQkwNOhGzvLNrlOBkJXpG9xty43O9T09qHJzKYobrAnlKeRTqYqppVfwmYI7rqr2rqTXF9mBB4s1zUCXJzTVrnqexzeH%2BUv54KIaXxR2CAn3%2BDDtDBfJ4wqk%2F8OBNN%20andrew%0A%0Assh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAACAQDcJSRy%2BRXANfCgJpzhX9fWEnslgCcgffw5t2mWW5Ltc2cfiWr1w3dUGoSa6oNs1QTwYkdfvy9cv1zwG%2B77a1AhtmjwywahSuOE3yg1IIe6Qo4U7Ae%2B7r8F08Qob7Ct8ZoUHPupbFYyXF759xYpN%2Bvvjuy3MbgTwnbijqH2HUAIwBT2V%2FxbGuwVBNK80i9ib3DNchW%2FwYu9oSukXufzBpPYBZUzAcejCTjPuv3ts%2FL%2BVPJSgaiHeZ%2FqlzU01BQ37dbEieDI6k64IKNppW2l%2BC0ERGtsKjPSINC%2Bx%2BOvS7puOtI%2BAu%2Bp72soaBIrfONsL3oTUgtj82bRzVALCM1Dxh%2BK7O0i00H%2F5xICB4%2Bb%2FGRgho%2BF4IlDf2mDy9qMoyNA8vemH%2FLC9Rc%2BujzIJJHD9WL8nDvg2v8lQGtWDrSlwjRKlp7MtVad%2BCOF6K9oCXjhFWUVirvG%2F1cG%2FYnmzn9%2F2ZEdsYuqL6TEflxtuIM2YdJWIubgnINs3l8P8UwuNa%2FUoM4leBT05LP%2BxbD7%2BHWSXNuWK9%2B7d3t03qOoGdfsbonk9wolM5l04QlTI%2BlOmQObBxHBT7CH4cwWC%2FevovPK9jKkAk%2FAC68YTWAV1U43O9gKmtq67TsShJ9YOeZU6xAp7kAcFVjpABz6suhQa6vGrGCKO8ERp4rLV9KUrgJin86KzQ%3D%3D%20steven%0Assh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAACAQDBN%2BISLXgsf3xxG18ZSKAwARj%2F0mw0x8JGQoWuCcDB5C99bgC5CMIsm%2F7ZYHye6BdB7GbY3RV%2FaVuLzm2lh2Q9opPT2AJhWDdeYyLhrIRsexNfnUXZsETxI4M7P5mZXNHAVASG%2FQ%2Fgu2lb1aPt5oOiRCI7tvitKLOGrUtb0%2FKToaityX2OJFmEnmH%2BRM6t2ICwmfObterWjzm%2BJ5k1ydFjSSwkx669U%2FGWVf56Rruburz%2FXlDwUm9liVef5iTOH8%2FrSu82ejamZXoYJFCaSq3nCZRw8mb6xs%2BzoiYcKiGozlhg6Zbpkexr4i20vPR5d9rQItaZ38cmbk2HwZzpaqUx%2Ft055CpmUQ2N%2Fvfvzr3rUCeG0SkWsew0m8UDB0AU6LYKCQS50kr0KBYEtE%2Blt46iLf%2B5XrlBhFj99xqx5qOeSY9Pz8xuu3Ti2ckDKhyMTj9uONSBPVOxRslX8PK35L0lQdM8TOjKBpVAWx4Fyag93QWyPFdUD4kB%2BHHSo9FgC9vZxtoxPOpTf8GgIzspGVHL%2BMjW7QmBs%2BcD48K9k6XMmaSq1AEx1JjeysoO5d9bzTygyHAhyZtZftnaTQ6r8OjUGL%2BU9J16Ezp1CwxY8tHpIyh2e6HUuVE8CNkeKLf6j2VIgdQd7b%2BiSPtr3bc43tMYRW9576Qov%2Ft8pP8gEla83w%3D%3D%20steven";
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2020",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
@@ -14,8 +18,13 @@
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"module": "commonjs",
|
||||
"types": ["node"]
|
||||
"module": "esnext",
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": ["src", "circuits/scripts/"]
|
||||
"include": [
|
||||
"src",
|
||||
"circuits/scripts/"
|
||||
]
|
||||
}
|
||||
|
||||
16
yarn.lock
16
yarn.lock
@@ -6788,6 +6788,7 @@ __metadata:
|
||||
circomlib: ^2.0.3
|
||||
circomlibjs: ^0.1.2
|
||||
cryo: ^0.0.6
|
||||
forge-std: ^1.1.2
|
||||
libmime: ^5.1.0
|
||||
localforage: ^1.10.0
|
||||
lodash: ^4.17.21
|
||||
@@ -6804,6 +6805,7 @@ __metadata:
|
||||
react-router-dom: ^6.2.2
|
||||
react-scripts: ^4
|
||||
react-use: ^17.3.2
|
||||
readline: ^1.3.0
|
||||
snarkjs: ^0.5.0
|
||||
sshpk: ^1.17.0
|
||||
styled-components: ^5.3.5
|
||||
@@ -8127,6 +8129,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"forge-std@npm:^1.1.2":
|
||||
version: 1.1.2
|
||||
resolution: "forge-std@npm:1.1.2"
|
||||
checksum: d5b36b909269a39dd30b619ac09a78e59b1a65e7887872ef99304298c4ffe2aa16f5dc5238c77e481a5e615582191b446401098a2ed567283d7df87e099a9d3c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fork-ts-checker-webpack-plugin@npm:4.1.6":
|
||||
version: 4.1.6
|
||||
resolution: "fork-ts-checker-webpack-plugin@npm:4.1.6"
|
||||
@@ -14208,6 +14217,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readline@npm:^1.3.0":
|
||||
version: 1.3.0
|
||||
resolution: "readline@npm:1.3.0"
|
||||
checksum: dfaf8e6ac20408ea00d650e95f7bb47f77c4c62dd12ed7fb51731ee84532a2f3675fcdc4cab4923dc1eef227520a2e082a093215190907758bea9f585b19438e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"recursive-readdir@npm:2.2.2":
|
||||
version: 2.2.2
|
||||
resolution: "recursive-readdir@npm:2.2.2"
|
||||
|
||||
Reference in New Issue
Block a user