Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: AES oracle padding #6013

Merged
merged 3 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions noir-projects/aztec-nr/aztec/src/oracle/encryption.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

#[oracle(aes128Encrypt)]
pub fn aes128_encrypt_oracle<N>(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; N] {}
pub fn aes128_encrypt_oracle<N, M>(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; M] {}

unconstrained pub fn aes128_encrypt<N>(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; N] {
// 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<N, M>(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8; M] {
aes128_encrypt_oracle(input, iv, key)
}
10 changes: 7 additions & 3 deletions noir-projects/noir-contracts/contracts/test_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,13 @@ 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(private)]
fn encrypt_with_padding(input: [u8; 65], iv: [u8; 16], key: [u8; 16]) -> [u8; 80] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bow

aes128_encrypt(input, iv, key)
}

#[aztec(public)]
Expand Down
9 changes: 8 additions & 1 deletion yarn-project/end-to-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,14 @@
"@swc/jest"
]
},
"reporters": [["default", {"summaryThreshold": 9999}]],
"reporters": [
[
"default",
{
"summaryThreshold": 9999
}
]
],
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.[cm]?js$": "$1"
},
Expand Down
30 changes: 22 additions & 8 deletions yarn-project/end-to-end/src/e2e_encryption.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,35 @@ 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
const ciphertextAsBigInts = 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);
.simulate();
const ciphertext = Buffer.from(ciphertextAsBigInts.map((x: bigint) => Number(x)));

expect(recoveredCiphertext).toEqual(expectedCiphertext);
expect(ciphertext).toEqual(expectedCiphertext);
});

it('encrypts 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);
});
});
Loading