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

refactor: cleanup the encrypted log incoming body #6325

Merged
merged 1 commit into from
May 15, 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
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
Loading