-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: update js config for new AES & add tests
- Loading branch information
1 parent
ab157c9
commit 0aa92ca
Showing
4 changed files
with
87 additions
and
67 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,91 +1,111 @@ | ||
import { CONFIG } from '../config' | ||
import { makeLocalFileFetch } from '../file-fetch' | ||
import { makeGnarkOPRFOperator } from '../gnark/toprf' | ||
import { strToUint8Array } from '../gnark/utils' | ||
import { OPRFResponseData, ZKTOPRFPublicSignals } from '../types' | ||
import { EncryptionAlgorithm, OPRFOperator, OPRFResponseData, ZKEngine, ZKTOPRFPublicSignals } from '../types' | ||
import { generateProof, verifyProof } from '../zk' | ||
import { encryptData } from './utils' | ||
|
||
const fetcher = makeLocalFileFetch() | ||
const operator = makeGnarkOPRFOperator({ fetcher, algorithm: 'chacha20' }) | ||
const threshold = 1 | ||
|
||
const POSITIONS = [ | ||
0, | ||
10 | ||
] | ||
|
||
describe('TOPRF circuits Tests', () => { | ||
type Config = { | ||
make: (alg: EncryptionAlgorithm) => OPRFOperator | ||
algorithms: EncryptionAlgorithm[] | ||
} | ||
|
||
it.each(POSITIONS)('should prove & verify TOPRF at pos=%s', async pos => { | ||
const email = 'test@email.com' | ||
const domainSeparator = 'reclaim' | ||
const OPRF_ZK_ENGINES_MAP: { [E in ZKEngine]?: Config } = { | ||
'gnark': { | ||
make: algorithm => makeGnarkOPRFOperator({ fetcher, algorithm }), | ||
algorithms: ['chacha20', 'aes-128-ctr', 'aes-256-ctr'], | ||
} | ||
} | ||
|
||
const keys = await operator.generateThresholdKeys(5, threshold) | ||
const req = await operator | ||
.generateOPRFRequestData(strToUint8Array(email), domainSeparator) | ||
const OPRF_ENGINES = Object.keys(OPRF_ZK_ENGINES_MAP) as ZKEngine[] | ||
|
||
const resps: OPRFResponseData[] = [] | ||
for(let i = 0; i < threshold; i++) { | ||
const evalResult = await operator.evaluateOPRF( | ||
keys.shares[i].privateKey, | ||
req.maskedData | ||
) | ||
describe.each(OPRF_ENGINES)('%s TOPRF circuits Tests', engine => { | ||
|
||
resps.push({ | ||
publicKeyShare: keys.shares[i].publicKey, | ||
evaluated: evalResult.evaluated, | ||
c: evalResult.c, | ||
r: evalResult.r, | ||
}) | ||
} | ||
|
||
const nullifier = await operator | ||
.finaliseOPRF(keys.publicKey, req, resps) | ||
const len = email.length | ||
|
||
const plaintext = new Uint8Array(Buffer.alloc(64)) | ||
//replace part of plaintext with email | ||
plaintext.set(new Uint8Array(Buffer.from(email)), pos) | ||
|
||
const key = new Uint8Array(Array.from(Array(32).keys())) | ||
const iv = new Uint8Array(Array.from(Array(12).keys())) | ||
|
||
const ciphertext = encryptData('chacha20', plaintext, key, iv) | ||
|
||
const toprf: ZKTOPRFPublicSignals = { | ||
pos: pos, //pos in plaintext | ||
len: len, // length of data to "hash" | ||
domainSeparator, | ||
output: nullifier, | ||
responses: resps | ||
} | ||
|
||
const proof = await generateProof({ | ||
algorithm: 'chacha20', | ||
privateInput: { | ||
key, | ||
}, | ||
publicInput: { | ||
iv, | ||
ciphertext, | ||
offset: 0 | ||
}, | ||
operator, | ||
mask: req.mask, | ||
toprf, | ||
}) | ||
const { make, algorithms } = OPRF_ZK_ENGINES_MAP[engine]! | ||
|
||
describe.each(algorithms)('%s', algorithm => { | ||
|
||
const operator = make(algorithm) | ||
|
||
it.each(POSITIONS)('should prove & verify TOPRF at pos=%s', async pos => { | ||
const email = 'test@email.com' | ||
const domainSeparator = 'reclaim' | ||
|
||
const keys = await operator.generateThresholdKeys(5, threshold) | ||
const req = await operator | ||
.generateOPRFRequestData(strToUint8Array(email), domainSeparator) | ||
|
||
const resps: OPRFResponseData[] = [] | ||
for(let i = 0; i < threshold; i++) { | ||
const evalResult = await operator.evaluateOPRF( | ||
keys.shares[i].privateKey, | ||
req.maskedData | ||
) | ||
|
||
resps.push({ | ||
publicKeyShare: keys.shares[i].publicKey, | ||
evaluated: evalResult.evaluated, | ||
c: evalResult.c, | ||
r: evalResult.r, | ||
}) | ||
} | ||
|
||
await expect( | ||
verifyProof({ | ||
proof, | ||
const nullifier = await operator | ||
.finaliseOPRF(keys.publicKey, req, resps) | ||
const len = email.length | ||
|
||
const plaintext = new Uint8Array(Buffer.alloc(64)) | ||
//replace part of plaintext with email | ||
plaintext.set(new Uint8Array(Buffer.from(email)), pos) | ||
|
||
const { keySizeBytes } = CONFIG[algorithm] | ||
const key = new Uint8Array(Array.from(Array(keySizeBytes).keys())) | ||
const iv = new Uint8Array(Array.from(Array(12).keys())) | ||
|
||
const ciphertext = encryptData(algorithm, plaintext, key, iv) | ||
|
||
const toprf: ZKTOPRFPublicSignals = { | ||
pos: pos, //pos in plaintext | ||
len: len, // length of data to "hash" | ||
domainSeparator, | ||
output: nullifier, | ||
responses: resps | ||
} | ||
|
||
const proof = await generateProof({ | ||
algorithm, | ||
privateInput: { | ||
key, | ||
}, | ||
publicInput: { | ||
iv, | ||
ciphertext, | ||
offset: 0 | ||
}, | ||
operator, | ||
mask: req.mask, | ||
toprf, | ||
operator | ||
}) | ||
).resolves.toBeUndefined() | ||
|
||
await expect( | ||
verifyProof({ | ||
proof, | ||
publicInput: { iv, ciphertext, | ||
offset: 0 | ||
}, | ||
toprf, | ||
operator | ||
}) | ||
).resolves.toBeUndefined() | ||
}) | ||
}) | ||
}) |