From 814db8667c8970df630d266c7100a53a22fb1c1b Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 26 Sep 2024 20:13:56 +0000 Subject: [PATCH] WIP --- yarn-project/circuit-types/src/logs/index.ts | 1 + yarn-project/circuit-types/src/logs/l2_log.ts | 121 +++++++++++------- 2 files changed, 77 insertions(+), 45 deletions(-) diff --git a/yarn-project/circuit-types/src/logs/index.ts b/yarn-project/circuit-types/src/logs/index.ts index 14cb33aa0068..d69817dd1ff9 100644 --- a/yarn-project/circuit-types/src/logs/index.ts +++ b/yarn-project/circuit-types/src/logs/index.ts @@ -4,6 +4,7 @@ export * from './get_unencrypted_logs_response.js'; export * from './function_l2_logs.js'; export * from './l2_block_l2_logs.js'; export * from './l2_logs_source.js'; +export * from './l2_log.js'; export * from './log_id.js'; export * from './log_type.js'; export * from './log_filter.js'; diff --git a/yarn-project/circuit-types/src/logs/l2_log.ts b/yarn-project/circuit-types/src/logs/l2_log.ts index b2adab2eb918..1952e212cb0d 100644 --- a/yarn-project/circuit-types/src/logs/l2_log.ts +++ b/yarn-project/circuit-types/src/logs/l2_log.ts @@ -3,6 +3,7 @@ import { Fr, GrumpkinScalar, type KeyValidationRequest, + NotOnCurveError, Point, type PublicKey, computeOvskApp, @@ -90,24 +91,39 @@ export class L2Log { * @param ivsk - The incoming viewing secret key, used to decrypt the logs * @returns The decrypted log payload */ - public static decryptAsIncoming(ciphertext: Buffer | BufferReader, ivsk: GrumpkinScalar) { + public static decryptAsIncoming(ciphertext: Buffer | BufferReader, ivsk: GrumpkinScalar): L2Log | undefined { const reader = BufferReader.asReader(ciphertext); - const incomingTag = reader.readObject(Fr); - const outgoingTag = reader.readObject(Fr); - - const ephPk = Point.fromCompressedBuffer(reader.readBytes(Point.COMPRESSED_SIZE_IN_BYTES)); - - const incomingHeader = decrypt(reader.readBytes(HEADER_SIZE), ivsk, ephPk); - - // Skipping the outgoing header and body - reader.readBytes(HEADER_SIZE); - reader.readBytes(OUTGOING_BODY_SIZE); - - // The incoming can be of variable size, so we read until the end - const incomingBodyPlaintext = decrypt(reader.readToEnd(), ivsk, ephPk); - - return new L2Log(incomingTag, outgoingTag, AztecAddress.fromBuffer(incomingHeader), incomingBodyPlaintext); + try { + const incomingTag = reader.readObject(Fr); + const outgoingTag = reader.readObject(Fr); + + const ephPk = Point.fromCompressedBuffer(reader.readBytes(Point.COMPRESSED_SIZE_IN_BYTES)); + + const incomingHeader = decrypt(reader.readBytes(HEADER_SIZE), ivsk, ephPk); + + // Skipping the outgoing header and body + reader.readBytes(HEADER_SIZE); + reader.readBytes(OUTGOING_BODY_SIZE); + + // The incoming can be of variable size, so we read until the end + const incomingBodyPlaintext = decrypt(reader.readToEnd(), ivsk, ephPk); + + return new L2Log(incomingTag, outgoingTag, AztecAddress.fromBuffer(incomingHeader), incomingBodyPlaintext); + } catch (e: any) { + // Following error messages are expected to occur when decryption fails + if ( + !(e instanceof NotOnCurveError) && + !e.message.endsWith('is greater or equal to field modulus.') && + !e.message.startsWith('Invalid AztecAddress length') && + !e.message.startsWith('Selector must fit in') && + !e.message.startsWith('Attempted to read beyond buffer length') + ) { + // If we encounter an unexpected error, we rethrow it + throw e; + } + return; + } } /** @@ -123,38 +139,53 @@ export class L2Log { * @param ovsk - The outgoing viewing secret key, used to decrypt the logs * @returns The decrypted log payload */ - public static decryptAsOutgoing(ciphertext: Buffer | BufferReader, ovsk: GrumpkinScalar) { + public static decryptAsOutgoing(ciphertext: Buffer | BufferReader, ovsk: GrumpkinScalar): L2Log | undefined { const reader = BufferReader.asReader(ciphertext); - const incomingTag = reader.readObject(Fr); - const outgoingTag = reader.readObject(Fr); - - const ephPk = Point.fromCompressedBuffer(reader.readBytes(Point.COMPRESSED_SIZE_IN_BYTES)); - - // We skip the incoming header - reader.readBytes(HEADER_SIZE); - - const outgoingHeader = decrypt(reader.readBytes(HEADER_SIZE), ovsk, ephPk); - const contractAddress = AztecAddress.fromBuffer(outgoingHeader); - - const ovskApp = computeOvskApp(ovsk, contractAddress); - - let ephSk: GrumpkinScalar; - let recipientIvpk: PublicKey; - { - const outgoingBody = decrypt(reader.readBytes(OUTGOING_BODY_SIZE), ovskApp, ephPk, derivePoseidonAESSecret); - const obReader = BufferReader.asReader(outgoingBody); - - // From outgoing body we extract ephSk, recipient and recipientIvpk - ephSk = GrumpkinScalar.fromHighLow(obReader.readObject(Fr), obReader.readObject(Fr)); - const _recipient = obReader.readObject(AztecAddress); - recipientIvpk = Point.fromCompressedBuffer(obReader.readBytes(Point.COMPRESSED_SIZE_IN_BYTES)); + try { + const incomingTag = reader.readObject(Fr); + const outgoingTag = reader.readObject(Fr); + + const ephPk = Point.fromCompressedBuffer(reader.readBytes(Point.COMPRESSED_SIZE_IN_BYTES)); + + // We skip the incoming header + reader.readBytes(HEADER_SIZE); + + const outgoingHeader = decrypt(reader.readBytes(HEADER_SIZE), ovsk, ephPk); + const contractAddress = AztecAddress.fromBuffer(outgoingHeader); + + const ovskApp = computeOvskApp(ovsk, contractAddress); + + let ephSk: GrumpkinScalar; + let recipientIvpk: PublicKey; + { + const outgoingBody = decrypt(reader.readBytes(OUTGOING_BODY_SIZE), ovskApp, ephPk, derivePoseidonAESSecret); + const obReader = BufferReader.asReader(outgoingBody); + + // From outgoing body we extract ephSk, recipient and recipientIvpk + ephSk = GrumpkinScalar.fromHighLow(obReader.readObject(Fr), obReader.readObject(Fr)); + const _recipient = obReader.readObject(AztecAddress); + recipientIvpk = Point.fromCompressedBuffer(obReader.readBytes(Point.COMPRESSED_SIZE_IN_BYTES)); + } + + // Now we decrypt the incoming body using the ephSk and recipientIvpk + const incomingBody = decrypt(reader.readToEnd(), ephSk, recipientIvpk); + + return new L2Log(incomingTag, outgoingTag, contractAddress, incomingBody); + } catch (e: any) { + // Following error messages are expected to occur when decryption fails + if ( + !(e instanceof NotOnCurveError) && + !e.message.endsWith('is greater or equal to field modulus.') && + !e.message.startsWith('Invalid AztecAddress length') && + !e.message.startsWith('Selector must fit in') && + !e.message.startsWith('Attempted to read beyond buffer length') + ) { + // If we encounter an unexpected error, we rethrow it + throw e; + } + return; } - - // Now we decrypt the incoming body using the ephSk and recipientIvpk - const incomingBody = decrypt(reader.readToEnd(), ephSk, recipientIvpk); - - return new L2Log(incomingTag, outgoingTag, contractAddress, incomingBody); } public toBuffer() {