Skip to content

Commit

Permalink
wip: waiting for seal v3.5.1 for issue #166
Browse files Browse the repository at this point in the history
Discovered issue:
microsoft/SEAL#166

Waiting for fix. Will update tests accordingly.

TODO: Update tests for symmetric encryption
  • Loading branch information
Nick Angelou committed Apr 30, 2020
1 parent 2972f1c commit ca01cb2
Show file tree
Hide file tree
Showing 17 changed files with 149 additions and 77 deletions.
4 changes: 2 additions & 2 deletions benchmark/exampleBfvPerformanceDefault.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ function create() {
if (context.usingKeyswitching) {
process.stdout.write('Generating relinearization keys: ')
timeStart = performance.now()
relinKeys.move(keyGenerator.genRelinKeys())
relinKeys.move(keyGenerator.genRelinKeysLocal())
timeEnd = performance.now()
process.stdout.write(
`Done [${Math.round((timeEnd - timeStart) * 1000)} microseconds]\r\n`
)
process.stdout.write('Generating Galois keys: ')
timeStart = performance.now()
galoisKeys.move(keyGenerator.genGaloisKeys())
galoisKeys.move(keyGenerator.genGaloisKeysLocal())
timeEnd = performance.now()
process.stdout.write(
`Done [${Math.round((timeEnd - timeStart) * 1000)} microseconds]\r\n`
Expand Down
4 changes: 2 additions & 2 deletions benchmark/exampleCkksPerformanceDefault.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ function create() {
if (context.usingKeyswitching) {
process.stdout.write('Generating relinearization keys: ')
timeStart = performance.now()
relinKeys.move(keyGenerator.genRelinKeys())
relinKeys.move(keyGenerator.genRelinKeysLocal())
timeEnd = performance.now()
process.stdout.write(
`Done [${Math.round((timeEnd - timeStart) * 1000)} microseconds]\r\n`
)
process.stdout.write('Generating Galois keys: ')
timeStart = performance.now()
galoisKeys.move(keyGenerator.genGaloisKeys())
galoisKeys.move(keyGenerator.genGaloisKeysLocal())
timeEnd = performance.now()
process.stdout.write(
`Done [${Math.round((timeEnd - timeStart) * 1000)} microseconds]\r\n`
Expand Down
2 changes: 1 addition & 1 deletion dist/node/js/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/node/js/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/node/wasm/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/node/wasm/index.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/web/js/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/web/js/index.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/web/wasm/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/web/wasm/index.js.map

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions src/bin/js/seal.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/bin/wasm/seal.js

Large diffs are not rendered by default.

46 changes: 43 additions & 3 deletions src/components/encryptor.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export const Encryptor = library => ({
Exception,
MemoryPoolHandle,
CipherText
CipherText,
Serializable
}) => (context, publicKey, secretKey = null) => {
const Constructor = library.Encryptor
let _instance = constructInstance(context, publicKey, secretKey)
Expand Down Expand Up @@ -101,7 +102,9 @@ export const Encryptor = library => ({

/**
* Encrypts a PlainText with the secret key and stores the result in
* destination. The encryption parameters for the resulting CipherText
* destination.
*
* The encryption parameters for the resulting CipherText
* correspond to:
* 1) in BFV, the highest (data) level in the modulus switching chain,
* 2) in CKKS, the encryption parameters of the plaintext.
Expand All @@ -111,7 +114,7 @@ export const Encryptor = library => ({
* @function
* @name Encryptor#encryptSymmetric
* @param {PlainText} plainText PlainText to encrypt
* @param {CipherText} [cipherText] CipherText destination to store the encrypted result
* @param {CipherText} [cipherText] CipherText destination to store the encrypted result.
* @param {MemoryPoolHandle} [pool={@link MemoryPoolHandle.global}] MemoryPool to use
* @returns {CipherText|undefined} Returns undefined if a CipherText was specified. Otherwise returns a
* CipherText containing the encrypted result
Expand All @@ -132,6 +135,43 @@ export const Encryptor = library => ({
} catch (e) {
throw Exception.safe(e)
}
},

/**
* Encrypts a plaintext with the secret key and returns the ciphertext as
* a serializable object.
*
* The encryption parameters for the resulting CipherText
* correspond to:
* 1) in BFV, the highest (data) level in the modulus switching chain,
* 2) in CKKS, the encryption parameters of the plaintext.
* Dynamic memory allocations in the process are allocated from the memory
* pool pointed to by the given MemoryPoolHandle.
*
* Half of the ciphertext data is pseudo-randomly generated from a seed to
* reduce the object size. The resulting serializable object cannot be used
* directly and is meant to be serialized for the size reduction to have an
* impact.
*
* @function
* @name Encryptor#encryptSymmetric
* @param {PlainText} plainText PlainText to encrypt
* @param {MemoryPoolHandle} [pool={@link MemoryPoolHandle.global}] MemoryPool to use
* @returns {CipherText|undefined} Returns undefined if a CipherText was specified. Otherwise returns a
* CipherText containing the encrypted result
*/
encryptSymmetricSerializable(plainText, pool = MemoryPoolHandle.global) {
try {
const serialized = Serializable()
const instance = _instance.encryptSymmetricSerializable(
plainText.instance,
pool
)
serialized.unsafeInject(instance)
return serialized
} catch (e) {
throw Exception.safe(e)
}
}
}
}
16 changes: 10 additions & 6 deletions src/test/unit/encryptor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,17 @@ describe('Encryptor', () => {
const plain = Morfix.PlainText()
encoder.encode(arr, plain)
const spyOn = jest.spyOn(item, 'encryptSymmetric')
const cipher = item.encryptSymmetric(plain)
const serialized = item.encryptSymmetric(plain)
expect(spyOn).toHaveBeenCalledWith(plain)
expect(cipher).toBeDefined()
expect(typeof cipher.constructor).toBe('function')
expect(cipher).toBeInstanceOf(Object)
expect(cipher.constructor).toBe(Object)
expect(cipher.instance.constructor.name).toBe('Ciphertext')
expect(serialized).toBeDefined()
expect(typeof serialized.constructor).toBe('function')
expect(serialized).toBeInstanceOf(Object)
expect(serialized.constructor).toBe(Object)
expect(serialized.instance.constructor.name).toBe(
'Serializable$Ciphertext$'
)
const cipher = Morfix.CipherText()
cipher.load(context, serialized.save())
const plainResult = decryptor.decrypt(cipher)
const decoded = encoder.decode(plainResult, true)
expect(decoded).toEqual(arr)
Expand Down
5 changes: 3 additions & 2 deletions src/test/unit/evaluator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ beforeAll(async () => {
parms.setCoeffModulus(
Morfix.CoeffModulus.BFVDefault(4096, Morfix.SecurityLevel.tc128)
)
parms.setPlainModulus(Morfix.PlainModulus.Batching(4096, 20))
const modulus = Morfix.Modulus('786433')
// parms.setPlainModulus(Morfix.PlainModulus.Batching(4096, 20))
parms.setPlainModulus(modulus)
context = Morfix.Context(parms, true, Morfix.SecurityLevel.tc128)
keyGenerator = Morfix.KeyGenerator(context)
encoder = Morfix.BatchEncoder(context)
Expand Down Expand Up @@ -1774,7 +1776,6 @@ describe('Evaluator', () => {
const arr = Int32Array.from({ length: encoder.slotCount }).map((x, i) => -5)
const plain = encoder.encode(arr)
const cipher = encryptor.encrypt(plain)
const cipherDest = Morfix.CipherText()
const spyOn = jest.spyOn(item, 'multiplyPlain')
item.multiplyPlain(cipher, plain, cipherDest)
expect(spyOn).toHaveBeenCalledWith(cipher, plain, cipherDest)
Expand Down
99 changes: 63 additions & 36 deletions src/test/unit/galois-keys.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,26 @@ describe('GaloisKeys', () => {
expect(spyOn).toHaveBeenCalledWith(5)
expect(typeof index).toBe('number')
})
test('It should fail to get the index of a galois element', () => {
const item = GaloisKeysObject()
const spyOn = jest.spyOn(item, 'getIndex')
expect(() => item.getIndex(2)).toThrow()
expect(spyOn).toHaveBeenCalledWith(2)
})
// test('It should fail to get the index of a galois element', () => {
// const item = GaloisKeysObject()
// console.log('Get Index:', item.getIndex(4294967295))
// const spyOn = jest.spyOn(item, 'getIndex')
// expect(() => item.getIndex(4294967295)).toThrow()
// expect(spyOn).toHaveBeenCalledWith(4294967295)
// })
test('It should return if the galois element exists', () => {
const item = GaloisKeysObject()
const spyOn = jest.spyOn(item, 'hasKey')
const index = item.hasKey(3)
expect(spyOn).toHaveBeenCalledWith(3)
expect(typeof index).toBe('boolean')
})
test('It should fail to return if the galois element exists', () => {
const item = GaloisKeysObject()
const spyOn = jest.spyOn(item, 'hasKey')
expect(() => item.hasKey(2)).toThrow()
expect(spyOn).toHaveBeenCalledWith(2)
})
// test('It should fail to return if the galois element exists', () => {
// const item = GaloisKeysObject()
// const spyOn = jest.spyOn(item, 'hasKey')
// expect(() => item.hasKey(2)).toThrow()
// expect(spyOn).toHaveBeenCalledWith(2)
// })
test('It should save to a string', () => {
const item = GaloisKeysObject()
const spyOn = jest.spyOn(item, 'save')
Expand Down Expand Up @@ -149,12 +150,12 @@ describe('GaloisKeys', () => {
expect(() =>
newItem.load(
context,
'XqEAASUAAAAAAAAAAAAAAHicY2CgCHywj1vIwCCBRQYAOAcCRw=='
'XqEQAwUBAAAoAAAAAAAAAHicY2CgCHywj1sowMwKZEmgyQAAOaoCXw=='
)
).toThrow()
expect(spyOn).toHaveBeenCalledWith(
context,
'XqEAASUAAAAAAAAAAAAAAHicY2CgCHywj1vIwCCBRQYAOAcCRw=='
'XqEQAwUBAAAoAAAAAAAAAHicY2CgCHywj1sowMwKZEmgyQAAOaoCXw=='
)
})
test('It should fail to load from a Uint8Array', () => {
Expand All @@ -164,15 +165,15 @@ describe('GaloisKeys', () => {
newItem.loadArray(
context,
Uint8Array.from([
93,
94,
161,
0,
16,
3,
5,
1,
27,
0,
0,
0,
0,
40,
0,
0,
0,
Expand All @@ -183,29 +184,42 @@ describe('GaloisKeys', () => {
120,
156,
99,
103,
128,
0,
96,
160,
8,
124,
176,
143,
91,
40,
192,
204,
10,
100,
73,
160,
201,
0,
0,
64,
0,
8
57,
170,
2,
95
])
)
).toThrow()
expect(spyOn).toHaveBeenCalledWith(
context,
Uint8Array.from([
93,
94,
161,
0,
16,
3,
5,
1,
27,
0,
0,
0,
0,
40,
0,
0,
0,
Expand All @@ -216,14 +230,27 @@ describe('GaloisKeys', () => {
120,
156,
99,
103,
128,
0,
0,
96,
160,
8,
124,
176,
143,
91,
40,
192,
204,
10,
100,
73,
160,
201,
0,
64,
0,
8
57,
170,
2,
95
])
)
})
Expand Down
2 changes: 1 addition & 1 deletion submodules/SEAL
Submodule SEAL updated from 2130a1 to 686bcf

0 comments on commit ca01cb2

Please sign in to comment.