From 0cb986fcf566a88b7f5187bad234867412bf49bb Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 25 Apr 2024 07:15:05 +0000 Subject: [PATCH 1/3] feat: AES oracle padding --- .../contracts/test_contract/src/main.nr | 5 ++--- yarn-project/end-to-end/package.json | 9 ++++++++- yarn-project/end-to-end/src/e2e_encryption.test.ts | 12 +++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 107df25dc72..3f071298b65 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -310,9 +310,8 @@ contract Test { } #[aztec(private)] - fn encrypt(input: [u8; 64], iv: [u8; 16], key: [u8; 16]) { - let result = aes128_encrypt(input, iv, key); - context.emit_unencrypted_log(result); + fn encrypt(input: [u8; 64], iv: [u8; 16], key: [u8; 16]) -> [u8; 64] { + aes128_encrypt(input, iv, key) } #[aztec(public)] diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index 524ecfedde8..e5e5c0ba6ba 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -110,7 +110,14 @@ "@swc/jest" ] }, - "reporters": [["default", {"summaryThreshold": 9999}]], + "reporters": [ + [ + "default", + { + "summaryThreshold": 9999 + } + ] + ], "moduleNameMapper": { "^(\\.{1,2}/.*)\\.[cm]?js$": "$1" }, diff --git a/yarn-project/end-to-end/src/e2e_encryption.test.ts b/yarn-project/end-to-end/src/e2e_encryption.test.ts index 861a7c573c3..5edff5997e3 100644 --- a/yarn-project/end-to-end/src/e2e_encryption.test.ts +++ b/yarn-project/end-to-end/src/e2e_encryption.test.ts @@ -21,21 +21,15 @@ describe('e2e_encryption', () => { afterAll(() => teardown()); - it('encrypts', async () => { + it('encrypts 🔒📄🔑💻', async () => { const input = randomBytes(64); const iv = randomBytes(16); const key = randomBytes(16); const expectedCiphertext = aes128.encryptBufferCBC(input, iv, key); - const logs = await contract.methods - .encrypt(Array.from(input), Array.from(iv), Array.from(key)) - .send() - .getUnencryptedLogs(); - // Each byte of encrypted data is in its own field and it's all serialized into a long buffer so we simply extract - // each 32nd byte from the buffer to get the encrypted data - const recoveredCiphertext = logs.logs[0].log.data.filter((_, i) => (i + 1) % 32 === 0); + const ciphertext = await contract.methods.encrypt(Array.from(input), Array.from(iv), Array.from(key)).simulate(); - expect(recoveredCiphertext).toEqual(expectedCiphertext); + expect(ciphertext).toEqual(expectedCiphertext); }); }); From 110476e5620e7fcca5b799d15b70bb6237835e25 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 25 Apr 2024 07:44:07 +0000 Subject: [PATCH 2/3] padding --- .../aztec-nr/aztec/src/oracle/encryption.nr | 4 ++-- .../contracts/test_contract/src/main.nr | 5 ++++ .../end-to-end/src/e2e_encryption.test.ts | 24 +++++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr b/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr index cb655c756ce..b12d76d0d6e 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr @@ -1,7 +1,7 @@ #[oracle(aes128Encrypt)] -pub fn aes128_encrypt_oracle(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; N] {} +pub fn aes128_encrypt_oracle(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; M] {} -unconstrained pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; N] { +unconstrained pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; M] { aes128_encrypt_oracle(input, iv, key) } diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 3f071298b65..1c14b54c96a 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -314,6 +314,11 @@ contract Test { aes128_encrypt(input, iv, key) } + #[aztec(private)] + fn encrypt_with_padding(input: [u8; 65], iv: [u8; 16], key: [u8; 16]) -> [u8; 80] { + aes128_encrypt(input, iv, key) + } + #[aztec(public)] fn assert_public_global_vars( chain_id: Field, diff --git a/yarn-project/end-to-end/src/e2e_encryption.test.ts b/yarn-project/end-to-end/src/e2e_encryption.test.ts index 5edff5997e3..c776ff6c88c 100644 --- a/yarn-project/end-to-end/src/e2e_encryption.test.ts +++ b/yarn-project/end-to-end/src/e2e_encryption.test.ts @@ -21,14 +21,34 @@ describe('e2e_encryption', () => { afterAll(() => teardown()); - it('encrypts 🔒📄🔑💻', async () => { + it('🔒📄🔑💻', async () => { const input = randomBytes(64); const iv = randomBytes(16); const key = randomBytes(16); const expectedCiphertext = aes128.encryptBufferCBC(input, iv, key); - const ciphertext = await contract.methods.encrypt(Array.from(input), Array.from(iv), Array.from(key)).simulate(); + const ciphertextAsBigInts = await contract.methods + .encrypt(Array.from(input), Array.from(iv), Array.from(key)) + .simulate(); + const ciphertext = Buffer.from(ciphertextAsBigInts.map((x: bigint) => Number(x))); + + expect(ciphertext).toEqual(expectedCiphertext); + }); + + it('🔒📄🔑💻 with padding', async () => { + const input = randomBytes(65); + const iv = randomBytes(16); + const key = randomBytes(16); + + const expectedCiphertext = aes128.encryptBufferCBC(input, iv, key); + // AES 128 CBC with PKCS7 is padding to multiples of 16 bytes so from 65 bytes long input we get 80 bytes long output + expect(expectedCiphertext.length).toBe(80); + + const ciphertextAsBigInts = await contract.methods + .encrypt_with_padding(Array.from(input), Array.from(iv), Array.from(key)) + .simulate(); + const ciphertext = Buffer.from(ciphertextAsBigInts.map((x: bigint) => Number(x))); expect(ciphertext).toEqual(expectedCiphertext); }); From 8438a8218c9c6a2deec89a085cbc10f8a0506c84 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 25 Apr 2024 09:11:23 +0000 Subject: [PATCH 3/3] comment --- noir-projects/aztec-nr/aztec/src/oracle/encryption.nr | 2 ++ yarn-project/end-to-end/src/e2e_encryption.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr b/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr index b12d76d0d6e..c8084432437 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/encryption.nr @@ -2,6 +2,8 @@ #[oracle(aes128Encrypt)] pub fn aes128_encrypt_oracle(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; M] {} +// AES 128 CBC with PKCS7 is padding to multiples of 16 bytes so M has to be a multiple of 16! +// (e.g. from 65 bytes long input you get 80 bytes long output and M has to be set to `80`) unconstrained pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; M] { aes128_encrypt_oracle(input, iv, key) } diff --git a/yarn-project/end-to-end/src/e2e_encryption.test.ts b/yarn-project/end-to-end/src/e2e_encryption.test.ts index c776ff6c88c..9206c566aea 100644 --- a/yarn-project/end-to-end/src/e2e_encryption.test.ts +++ b/yarn-project/end-to-end/src/e2e_encryption.test.ts @@ -21,7 +21,7 @@ describe('e2e_encryption', () => { afterAll(() => teardown()); - it('🔒📄🔑💻', async () => { + it('encrypts 🔒📄🔑💻', async () => { const input = randomBytes(64); const iv = randomBytes(16); const key = randomBytes(16); @@ -36,7 +36,7 @@ describe('e2e_encryption', () => { expect(ciphertext).toEqual(expectedCiphertext); }); - it('🔒📄🔑💻 with padding', async () => { + it('encrypts with padding 🔒📄🔑💻 ➕ 📦', async () => { const input = randomBytes(65); const iv = randomBytes(16); const key = randomBytes(16);