Skip to content

Commit

Permalink
refactor: cleanup the encrypted log incoming body (#6325)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
LHerskind authored May 15, 2024
1 parent 9df0602 commit e88c209
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 45 deletions.
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/encrypted_logs.nr
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mod header;
mod body;
mod incoming_body;
Original file line number Diff line number Diff line change
Expand Up @@ -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<Note> {
struct EncryptedLogIncomingBody<Note> {
storage_slot: Field,
note_type_id: Field,
note: Note,
}

impl<Note> EncryptedLogBody<Note> {
impl<Note> EncryptedLogIncomingBody<Note> {
pub fn new<N>(
storage_slot: Field,
note_type_id: Field,
Expand All @@ -21,8 +21,8 @@ impl<Note> EncryptedLogBody<Note> {

pub fn compute_ciphertext<N>(
self,
secret: GrumpkinPrivateKey,
point: GrumpkinPoint
eph_sk: GrumpkinPrivateKey,
ivpk_app: GrumpkinPoint
) -> [u8] where Note: NoteInterface<N> {
let serialized_note: [Field; N] = self.note.serialize_content();

Expand All @@ -46,7 +46,7 @@ impl<Note> EncryptedLogBody<Note> {
}
}

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];

Expand All @@ -59,7 +59,7 @@ impl<Note> EncryptedLogBody<Note> {
}

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
Expand Down Expand Up @@ -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),
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export {
Comparator,
SiblingPath,
EncryptedLogHeader,
EncryptedLogBody,
EncryptedLogIncomingBody,
} from '@aztec/circuit-types';
export { NodeInfo } from '@aztec/types/interfaces';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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,
Expand All @@ -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);

Expand All @@ -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,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}

/**
Expand All @@ -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);
Expand All @@ -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);

Expand All @@ -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);
}
}
2 changes: 1 addition & 1 deletion yarn-project/circuit-types/src/logs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
12 changes: 6 additions & 6 deletions yarn-project/end-to-end/src/e2e_encryption.test.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -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();

Expand All @@ -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();

Expand All @@ -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());
});
Expand Down

0 comments on commit e88c209

Please sign in to comment.