UNPKG

@zkp2p/reclaim-witness-sdk

Version:

<div> <div> <img src="https://raw.githubusercontent.com/reclaimprotocol/.github/main/assets/banners/Attestor-Core.png" /> </div> </div>

148 lines 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.REDACTION_CHAR_CODE = exports.REDACTION_CHAR = void 0; exports.isRedactionCongruent = isRedactionCongruent; exports.isFullyRedacted = isFullyRedacted; exports.getBlocksToReveal = getBlocksToReveal; exports.redactSlices = redactSlices; exports.binaryHashToStr = binaryHashToStr; const wire_1 = require("@bufbuild/protobuf/wire"); const tls_1 = require("@reclaimprotocol/tls"); exports.REDACTION_CHAR = '*'; exports.REDACTION_CHAR_CODE = exports.REDACTION_CHAR.charCodeAt(0); /** * Check if a redacted string is congruent with the original string. * @param redacted the redacted content, redacted content is replaced by '*' * @param original the original content */ function isRedactionCongruent(redacted, original) { // eslint-disable-next-line unicorn/no-for-loop for (let i = 0; i < redacted.length; i++) { const element = redacted[i]; const areSame = element === original[i] || (typeof element === 'string' && element === exports.REDACTION_CHAR) || (typeof element === 'number' && element === exports.REDACTION_CHAR_CODE); if (!areSame) { return false; } } return true; } /** * Is the string fully redacted? */ function isFullyRedacted(redacted) { for (const element of redacted) { if (element !== exports.REDACTION_CHAR && element !== exports.REDACTION_CHAR_CODE) { return false; } } return true; } /** * Given some plaintext blocks and a redaction function, return the blocks that * need to be revealed to the other party * * Use case: we get the response for a request in several blocks, and want to redact * pieces that go through multiple blocks. We can use this function to get the * blocks that need to be revealed to the other party * * @example if we received ["secret is 12","345","678. Thanks"]. We'd want * to redact the "12345678" and reveal the rest. We'd pass in the blocks and * the redact function will return the redactions, namely [10,19]. * The function will return the blocks ["secret is **","***. Thanks"]. * The middle block is fully redacted, so it's not returned * * @param blocks blocks to reveal * @param redact function that returns the redactions * @returns blocks to reveal */ async function getBlocksToReveal(blocks, redact, performOprf) { const slicesWithReveal = blocks.map(block => ({ block, // copy the plaintext to avoid mutating the original redactedPlaintext: new Uint8Array(block.plaintext) })); const total = (0, tls_1.concatenateUint8Arrays)(blocks.map(b => b.plaintext)); const redactions = redact(total); if (!redactions.length) { return 'all'; } let blockIdx = 0; let cursorInBlock = 0; let cursor = 0; for (const redaction of redactions) { await redactBlocks(redaction); } // only reveal blocks that have some data to reveal, // or are completely plaintext return slicesWithReveal .filter(s => !isFullyRedacted(s.redactedPlaintext)); async function redactBlocks(slice) { while (cursor < slice.fromIndex) { advance(); } if (slice.hash) { const plaintext = total.slice(slice.fromIndex, slice.toIndex); const { nullifier, responses, mask } = await performOprf(plaintext); // set the TOPRF claim on the first blocks this // redaction covers const toprf = { nullifier, responses, dataLocation: { fromIndex: cursorInBlock, length: slice.toIndex - slice.fromIndex }, mask, plaintext }; const block = slicesWithReveal[blockIdx]; block.toprfs || (block.toprfs = []); block.toprfs.push(toprf); const nullifierStr = binaryHashToStr(nullifier, toprf.dataLocation.length); let i = 0; while (cursor < slice.toIndex) { slicesWithReveal[blockIdx].redactedPlaintext[cursorInBlock] = nullifierStr.charCodeAt(i); advance(); i += 1; } } while (cursor < slice.toIndex) { slicesWithReveal[blockIdx] .redactedPlaintext[cursorInBlock] = exports.REDACTION_CHAR_CODE; advance(); } } function advance() { cursor += 1; cursorInBlock += 1; if (cursorInBlock >= blocks[blockIdx].plaintext.length) { blockIdx += 1; cursorInBlock = 0; } } } /** * Redact the following slices from the total */ function redactSlices(total, slices) { const redacted = new Uint8Array(total); for (const slice of slices) { for (let i = slice.fromIndex; i < slice.toIndex; i++) { redacted[i] = exports.REDACTION_CHAR_CODE; } } return redacted; } /** * Converts the binary hash to an ASCII string of the expected length. * If the hash is shorter than the expected length, it will be padded with * '0' characters. If it's longer, it will be truncated. */ function binaryHashToStr(hash, expLength) { return (0, wire_1.base64Encode)(hash).padEnd(expLength, '0').slice(0, expLength); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkYWN0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9yZWRhY3Rpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXVCQSxvREFnQkM7QUFLRCwwQ0FhQztBQW9CRCw4Q0EwRkM7QUFLRCxvQ0FVQztBQU9ELDBDQUVDO0FBL0xELGtEQUFzRDtBQUN0RCw4Q0FBNkQ7QUFHaEQsUUFBQSxjQUFjLEdBQUcsR0FBRyxDQUFBO0FBQ3BCLFFBQUEsbUJBQW1CLEdBQUcsc0JBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFhL0Q7Ozs7R0FJRztBQUNILFNBQWdCLG9CQUFvQixDQUNuQyxRQUFXLEVBQ1gsUUFBVztJQUVYLCtDQUErQztJQUMvQyxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUMzQixNQUFNLE9BQU8sR0FBRyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztlQUNuQyxDQUFDLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxPQUFPLEtBQUssc0JBQWMsQ0FBQztlQUMzRCxDQUFDLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxPQUFPLEtBQUssMkJBQW1CLENBQUMsQ0FBQTtRQUNwRSxJQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixPQUFPLEtBQUssQ0FBQTtRQUNiLENBQUM7SUFDRixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUE7QUFDWixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixlQUFlLENBQzlCLFFBQVc7SUFFWCxLQUFJLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQy9CLElBQ0MsT0FBTyxLQUFLLHNCQUFjO2VBQ3ZCLE9BQU8sS0FBSywyQkFBbUIsRUFDakMs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