From e88c209965f862a1478422980d0a1a9a3df46295 Mon Sep 17 00:00:00 2001 From: Lasse Herskind <16536249+LHerskind@users.noreply.github.com> Date: Wed, 15 May 2024 13:49:15 +0100 Subject: [PATCH] refactor: cleanup the encrypted log incoming body (#6325) Cleans up the incoming body slightly to make it more clear that it is incoming and not to be used for both incoming and outgoing. --- .../aztec-nr/aztec/src/encrypted_logs.nr | 2 +- .../{body.nr => incoming_body.nr} | 22 ++++++------- .../contracts/test_contract/src/main.nr | 6 ++-- yarn-project/aztec.js/src/index.ts | 2 +- ...ts => encrypted_log_incoming_body.test.ts} | 16 +++++----- ...body.ts => encrypted_log_incoming_body.ts} | 31 ++++++++++--------- yarn-project/circuit-types/src/logs/index.ts | 2 +- .../end-to-end/src/e2e_encryption.test.ts | 12 +++---- 8 files changed, 48 insertions(+), 45 deletions(-) rename noir-projects/aztec-nr/aztec/src/encrypted_logs/{body.nr => incoming_body.nr} (89%) rename yarn-project/circuit-types/src/logs/{encrypted_log_body.test.ts => encrypted_log_incoming_body.test.ts} (75%) rename yarn-project/circuit-types/src/logs/{encrypted_log_body.ts => encrypted_log_incoming_body.ts} (64%) diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs.nr index a81b22fd87b..25f085412e5 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs.nr @@ -1,2 +1,2 @@ mod header; -mod body; +mod incoming_body; diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr similarity index 89% rename from noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr rename to noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr index 9f490c768e0..1016e7f4d09 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr @@ -4,13 +4,13 @@ use dep::protocol_types::{grumpkin_private_key::GrumpkinPrivateKey, grumpkin_poi use dep::std::aes128::aes128_encrypt_slice; use crate::keys::point_to_symmetric_key::point_to_symmetric_key; -struct EncryptedLogBody { +struct EncryptedLogIncomingBody { storage_slot: Field, note_type_id: Field, note: Note, } -impl EncryptedLogBody { +impl EncryptedLogIncomingBody { pub fn new( storage_slot: Field, note_type_id: Field, @@ -21,8 +21,8 @@ impl EncryptedLogBody { pub fn compute_ciphertext( self, - secret: GrumpkinPrivateKey, - point: GrumpkinPoint + eph_sk: GrumpkinPrivateKey, + ivpk_app: GrumpkinPoint ) -> [u8] where Note: NoteInterface { let serialized_note: [Field; N] = self.note.serialize_content(); @@ -46,7 +46,7 @@ impl EncryptedLogBody { } } - let full_key = point_to_symmetric_key(secret, point); + let full_key = point_to_symmetric_key(eph_sk, ivpk_app); let mut sym_key = [0; 16]; let mut iv = [0; 16]; @@ -59,7 +59,7 @@ impl EncryptedLogBody { } mod test { - use crate::encrypted_logs::body::EncryptedLogBody; + use crate::encrypted_logs::incoming_body::EncryptedLogIncomingBody; use dep::protocol_types::{ address::AztecAddress, traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER, grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint @@ -109,7 +109,7 @@ mod test { } #[test] - fn test_encrypted_log_body() { + fn test_encrypted_log_incoming_body() { let note = AddressNote::new( AztecAddress::from_field(0x1), AztecAddress::from_field(0x2), @@ -118,18 +118,18 @@ mod test { let note_type_id = 1; let storage_slot = 2; - let body = EncryptedLogBody::new(storage_slot, note_type_id, note); + let body = EncryptedLogIncomingBody::new(storage_slot, note_type_id, note); - let secret = GrumpkinPrivateKey::new( + let eph_sk = GrumpkinPrivateKey::new( 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06, 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd ); - let point = GrumpkinPoint::new( + let ivpk_app = GrumpkinPoint::new( 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186, 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e ); - let ciphertext = body.compute_ciphertext(secret, point); + let ciphertext = body.compute_ciphertext(eph_sk, ivpk_app); let expected_body_ciphertext = [ 131, 119, 105, 129, 244, 32, 151, 205, 12, 99, 93, 62, 10, 180, 72, 21, 47, 232, 95, 17, 240, 230, 80, 129, 174, 158, 23, 76, 114, 185, 43, 18, 254, 148, 147, 230, 66, 216, 167, 62, 180, 213, 238, 33, 108, 29, 84, 139, 99, 206, 212, 253, 92, 116, 137, 31, 0, 104, 45, 91, 250, 109, 141, 114, 189, 53, 35, 60, 108, 156, 170, 206, 150, 114, 150, 187, 198, 13, 62, 153, 133, 13, 169, 167, 242, 221, 40, 168, 186, 203, 104, 82, 47, 238, 142, 179, 90, 37, 9, 70, 245, 176, 122, 247, 42, 87, 75, 7, 20, 89, 166, 123, 14, 26, 230, 156, 49, 94, 0, 94, 72, 58, 171, 239, 115, 174, 155, 7, 151, 17, 60, 206, 193, 134, 70, 87, 215, 88, 21, 194, 63, 26, 106, 105, 124, 213, 252, 152, 192, 71, 115, 13, 181, 5, 169, 15, 170, 196, 174, 228, 170, 192, 91, 76, 110, 220, 89, 47, 248, 144, 189, 251, 167, 149, 248, 226 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 619b30fd2b9..16f8cfe19c9 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -16,7 +16,7 @@ contract Test { }; use dep::aztec::encrypted_logs::header::EncryptedLogHeader; - use dep::aztec::encrypted_logs::body::EncryptedLogBody; + use dep::aztec::encrypted_logs::incoming_body::EncryptedLogIncomingBody; use dep::aztec::note::constants::MAX_NOTES_PER_PAGE; @@ -364,14 +364,14 @@ contract Test { // 64 bytes + 32 * #fields + 16 = 112 bytes #[aztec(private)] - fn compute_note_body_ciphertext( + fn compute_incoming_log_body_ciphertext( secret: GrumpkinPrivateKey, point: GrumpkinPoint, storage_slot: Field, value: Field ) -> [u8; 112] { let note = TestNote::new(value); - EncryptedLogBody::new(storage_slot, TestNote::get_note_type_id(), note).compute_ciphertext(secret, point).as_array() + EncryptedLogIncomingBody::new(storage_slot, TestNote::get_note_type_id(), note).compute_ciphertext(secret, point).as_array() } #[aztec(public)] diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 070ecb51b94..e89316b4230 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -124,7 +124,7 @@ export { Comparator, SiblingPath, EncryptedLogHeader, - EncryptedLogBody, + EncryptedLogIncomingBody, } from '@aztec/circuit-types'; export { NodeInfo } from '@aztec/types/interfaces'; diff --git a/yarn-project/circuit-types/src/logs/encrypted_log_body.test.ts b/yarn-project/circuit-types/src/logs/encrypted_log_incoming_body.test.ts similarity index 75% rename from yarn-project/circuit-types/src/logs/encrypted_log_body.test.ts rename to yarn-project/circuit-types/src/logs/encrypted_log_incoming_body.test.ts index db814bc0d98..bb1ab2c2588 100644 --- a/yarn-project/circuit-types/src/logs/encrypted_log_body.test.ts +++ b/yarn-project/circuit-types/src/logs/encrypted_log_incoming_body.test.ts @@ -2,17 +2,17 @@ import { Fr, GrumpkinScalar } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { updateInlineTestData } from '@aztec/foundation/testing'; -import { EncryptedLogBody } from './encrypted_log_body.js'; +import { EncryptedLogIncomingBody } from './encrypted_log_incoming_body.js'; import { Note } from './l1_note_payload/note.js'; -describe('encrypt log body', () => { +describe('encrypt log incoming body', () => { let grumpkin: Grumpkin; beforeAll(() => { grumpkin = new Grumpkin(); }); - it('encrypt and decrypt a log body', () => { + it('encrypt and decrypt a log incoming body', () => { const ephSecretKey = GrumpkinScalar.random(); const viewingSecretKey = GrumpkinScalar.random(); @@ -23,16 +23,16 @@ describe('encrypt log body', () => { const noteTypeId = Fr.random(); const storageSlot = Fr.random(); - const body = new EncryptedLogBody(noteTypeId, storageSlot, note); + const body = new EncryptedLogIncomingBody(noteTypeId, storageSlot, note); const encrypted = body.computeCiphertext(ephSecretKey, viewingPubKey); - const recreated = EncryptedLogBody.fromCiphertext(encrypted, viewingSecretKey, ephPubKey); + const recreated = EncryptedLogIncomingBody.fromCiphertext(encrypted, viewingSecretKey, ephPubKey); expect(recreated.toBuffer()).toEqual(body.toBuffer()); }); - it('encrypt a log body, generate input for noir test', () => { + it('encrypt a log incoming body, generate input for noir test', () => { // The following 2 are arbitrary fixed values - fixed in order to test a match with Noir const viewingSecretKey: GrumpkinScalar = new GrumpkinScalar( 0x23b3127c127b1f29a7adff5cccf8fb06649e7ca01d9de27b21624098b897babdn, @@ -47,7 +47,7 @@ describe('encrypt log body', () => { const noteTypeId = new Fr(1); const storageSlot = new Fr(2); - const body = new EncryptedLogBody(storageSlot, noteTypeId, note); + const body = new EncryptedLogIncomingBody(storageSlot, noteTypeId, note); const encrypted = body.computeCiphertext(ephSecretKey, viewingPubKey); @@ -58,7 +58,7 @@ describe('encrypt log body', () => { // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data updateInlineTestData( - 'noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr', + 'noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr', 'expected_body_ciphertext', byteArrayString, ); diff --git a/yarn-project/circuit-types/src/logs/encrypted_log_body.ts b/yarn-project/circuit-types/src/logs/encrypted_log_incoming_body.ts similarity index 64% rename from yarn-project/circuit-types/src/logs/encrypted_log_body.ts rename to yarn-project/circuit-types/src/logs/encrypted_log_incoming_body.ts index 40a4d2e4c4e..45e1f5382bf 100644 --- a/yarn-project/circuit-types/src/logs/encrypted_log_body.ts +++ b/yarn-project/circuit-types/src/logs/encrypted_log_incoming_body.ts @@ -4,7 +4,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { Note, deriveAESSecret } from './l1_note_payload/index.js'; -export class EncryptedLogBody { +export class EncryptedLogIncomingBody { constructor(public storageSlot: Fr, public noteTypeId: Fr, public note: Note) {} /** @@ -23,7 +23,7 @@ export class EncryptedLogBody { * @param buf - The buffer to deserialize * @returns The deserialized log body */ - public static fromBuffer(buf: Buffer): EncryptedLogBody { + public static fromBuffer(buf: Buffer): EncryptedLogIncomingBody { const reader = BufferReader.asReader(buf); const storageSlot = Fr.fromBuffer(reader); const noteTypeId = Fr.fromBuffer(reader); @@ -32,19 +32,19 @@ export class EncryptedLogBody { const fieldsInNote = reader.getLength() / 32 - 2; const note = new Note(reader.readArray(fieldsInNote, Fr)); - return new EncryptedLogBody(storageSlot, noteTypeId, note); + return new EncryptedLogIncomingBody(storageSlot, noteTypeId, note); } /** * Encrypts a log body * - * @param secret - The ephemeral secret key - * @param publicKey - The incoming viewing key for the recipient of this log + * @param ephSk - The ephemeral secret key + * @param ivpkApp - The application scoped incoming viewing key for the recipient of this log * * @returns The ciphertext of the encrypted log body */ - public computeCiphertext(secret: GrumpkinPrivateKey, publicKey: PublicKey) { - const aesSecret = deriveAESSecret(secret, publicKey); + public computeCiphertext(ephSk: GrumpkinPrivateKey, ivpkApp: PublicKey) { + const aesSecret = deriveAESSecret(ephSk, ivpkApp); const key = aesSecret.subarray(0, 16); const iv = aesSecret.subarray(16, 32); @@ -58,24 +58,27 @@ export class EncryptedLogBody { * Decrypts a log body * * @param ciphertext - The ciphertext buffer - * @param secret - The private key matching the public key used in encryption (the viewing key secret) - * @param publicKey - The public key generated with the ephemeral secret key used in encryption + * @param ivskAppOrEphSk - The private key matching the public key used in encryption (the viewing key secret or) + * @param ephPkOrIvpkApp - The public key generated with the ephemeral secret key used in encryption + * + * The "odd" input stems from ivskApp * ephPk == ivpkApp * ephSk producing the same value. + * This is used to allow for the same decryption function to be used by both the sender and the recipient. * * @returns The decrypted log body */ public static fromCiphertext( ciphertext: Buffer | bigint[], - secret: GrumpkinPrivateKey, - publicKey: PublicKey, - ): EncryptedLogBody { + ivskAppOrEphSk: GrumpkinPrivateKey, + ephPkOrIvpkApp: PublicKey, + ): EncryptedLogIncomingBody { const input = Buffer.isBuffer(ciphertext) ? ciphertext : Buffer.from(ciphertext.map((x: bigint) => Number(x))); - const aesSecret = deriveAESSecret(secret, publicKey); + const aesSecret = deriveAESSecret(ivskAppOrEphSk, ephPkOrIvpkApp); const key = aesSecret.subarray(0, 16); const iv = aesSecret.subarray(16, 32); const aes128 = new Aes128(); const buffer = aes128.decryptBufferCBC(input, iv, key); - return EncryptedLogBody.fromBuffer(buffer); + return EncryptedLogIncomingBody.fromBuffer(buffer); } } diff --git a/yarn-project/circuit-types/src/logs/index.ts b/yarn-project/circuit-types/src/logs/index.ts index ca6b731ff80..2b91857d095 100644 --- a/yarn-project/circuit-types/src/logs/index.ts +++ b/yarn-project/circuit-types/src/logs/index.ts @@ -11,4 +11,4 @@ export * from './tx_l2_logs.js'; export * from './unencrypted_l2_log.js'; export * from './extended_unencrypted_l2_log.js'; export * from './encrypted_log_header.js'; -export * from './encrypted_log_body.js'; +export * from './encrypted_log_incoming_body.js'; 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 2cb4b3ea528..88abfabd694 100644 --- a/yarn-project/end-to-end/src/e2e_encryption.test.ts +++ b/yarn-project/end-to-end/src/e2e_encryption.test.ts @@ -1,4 +1,4 @@ -import { EncryptedLogBody, EncryptedLogHeader, Fr, GrumpkinScalar, Note, type Wallet } from '@aztec/aztec.js'; +import { EncryptedLogHeader, EncryptedLogIncomingBody, Fr, GrumpkinScalar, Note, type Wallet } from '@aztec/aztec.js'; import { Aes128, Grumpkin } from '@aztec/circuits.js/barretenberg'; import { TestContract } from '@aztec/noir-contracts.js'; @@ -55,7 +55,7 @@ describe('e2e_encryption', () => { expect(ciphertext).toEqual(expectedCiphertext); }); - it('encrypts header', async () => { + it('encrypts log header', async () => { const ephSecretKey = GrumpkinScalar.random(); const viewingSecretKey = GrumpkinScalar.random(); @@ -73,7 +73,7 @@ describe('e2e_encryption', () => { expect(recreated.address).toEqual(contract.address); }); - it('encrypted body', async () => { + it('encrypts log incoming body', async () => { const ephSecretKey = GrumpkinScalar.random(); const viewingSecretKey = GrumpkinScalar.random(); @@ -85,17 +85,17 @@ describe('e2e_encryption', () => { const value = Fr.random(); const note = new Note([value]); - const body = new EncryptedLogBody(storageSlot, noteTypeId, note); + const body = new EncryptedLogIncomingBody(storageSlot, noteTypeId, note); const encrypted = await contract.methods - .compute_note_body_ciphertext(ephSecretKey, viewingPubKey, storageSlot, value) + .compute_incoming_log_body_ciphertext(ephSecretKey, viewingPubKey, storageSlot, value) .simulate(); expect(Buffer.from(encrypted.map((x: bigint) => Number(x)))).toEqual( body.computeCiphertext(ephSecretKey, viewingPubKey), ); - const recreated = EncryptedLogBody.fromCiphertext(encrypted, viewingSecretKey, ephPubKey); + const recreated = EncryptedLogIncomingBody.fromCiphertext(encrypted, viewingSecretKey, ephPubKey); expect(recreated.toBuffer()).toEqual(body.toBuffer()); });