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
Changes from 2 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
4 changes: 2 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,7 @@

#[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] {
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
@@ -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.

aes128_encrypt(input, iv, key)
}

#[aztec(public)]
9 changes: 8 additions & 1 deletion yarn-project/end-to-end/package.json
Original file line number Diff line number Diff line change
@@ -110,7 +110,14 @@
"@swc/jest"
]
},
"reporters": [["default", {"summaryThreshold": 9999}]],
"reporters": [
[
"default",
{
"summaryThreshold": 9999
}
]
],
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.[cm]?js$": "$1"
},
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
@@ -21,21 +21,35 @@ describe('e2e_encryption', () => {

afterAll(() => teardown());

it('encrypts', async () => {
it('🔒📄🔑💻', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

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('🔒📄🔑💻 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);
});
});