Skip to content

Commit

Permalink
fix: update js config for new AES & add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adiwajshing committed Nov 21, 2024
1 parent ab157c9 commit 0aa92ca
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 67 deletions.
Binary file modified bin/gnark/darwin-arm64-libprove.so
Binary file not shown.
Binary file modified bin/gnark/darwin-arm64-libverify.so
Binary file not shown.
8 changes: 4 additions & 4 deletions js/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ export const CONFIG: { [E in EncryptionAlgorithm]: AlgorithmConfig } = {
},
'aes-256-ctr': {
index: 2,
chunkSize: 64,
chunkSize: 80,
bitsPerWord: 8,
keySizeBytes: 32,
ivSizeBytes: 12,
startCounter: 2,
// num of blocks per chunk
blocksPerChunk: 4,
blocksPerChunk: 5,
// AES circuit uses BE encoding
isLittleEndian: false,
uint8ArrayToBits,
Expand All @@ -48,13 +48,13 @@ export const CONFIG: { [E in EncryptionAlgorithm]: AlgorithmConfig } = {
},
'aes-128-ctr': {
index: 1,
chunkSize: 64,
chunkSize: 80,
bitsPerWord: 8,
keySizeBytes: 16,
ivSizeBytes: 12,
startCounter: 2,
// num of blocks per chunk
blocksPerChunk: 4,
blocksPerChunk: 5,
// AES circuit uses BE encoding
isLittleEndian: false,
uint8ArrayToBits,
Expand Down
146 changes: 83 additions & 63 deletions js/src/tests/oprf.test.ts
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()
})
})
})

0 comments on commit 0aa92ca

Please sign in to comment.