From 26248fb45f1b4a469726a9762da154a89b25ce8a Mon Sep 17 00:00:00 2001 From: Levent DEMIR Date: Mon, 18 Mar 2024 01:29:07 +0100 Subject: [PATCH 1/4] fixture(eaddress): truncate hex string from decrypted bytes (leading 00) The decrypted value could contain leading 0 bytes (e.g. KMS returns 32 bytes serialized big int). This behaviour triggers error with getAddress method from ethers which takes hex string and return eth plain address (if hexstring > 40 digits) --- src/sdk/decrypt.ts | 11 ++++++++++- src/utils.ts | 8 +------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/sdk/decrypt.ts b/src/sdk/decrypt.ts index f663c4c..3ea9530 100644 --- a/src/sdk/decrypt.ts +++ b/src/sdk/decrypt.ts @@ -28,5 +28,14 @@ export const decryptAddress = ( keypair.publicKey, keypair.privateKey, ); - return getAddress(bytesToHex(decrypted)); + +let hexString = bytesToHex(decrypted); +// Ensure hexString forms a valid 40-digit Ethereum address. +// Truncate or pad with leading zeros as necessary to correct length issues. +if (hexString.length > 40) { + hexString = hexString.substring(hexString.length - 40); +} else { + hexString = hexString.padStart(40, '0'); +} + return getAddress(hexString); }; diff --git a/src/utils.ts b/src/utils.ts index 9a8dde9..7283a85 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -18,12 +18,8 @@ export const bytesToHex = function (byteArray: Uint8Array): string { if (!byteArray || byteArray?.length === 0) { return '0x0'; } - - const length = byteArray.length; - const buffer = Buffer.from(byteArray); - const result = buffer.toString('hex'); - + const result = '0x' + buffer.toString('hex'); return result; }; @@ -32,8 +28,6 @@ export const bytesToBigInt = function (byteArray: Uint8Array): bigint { return BigInt(0); } - const length = byteArray.length; - const buffer = Buffer.from(byteArray); const result = toBigIntBE(buffer); From def870b610dbb824965b53551d0e2f031e6929b7 Mon Sep 17 00:00:00 2001 From: Levent DEMIR Date: Mon, 18 Mar 2024 11:01:19 +0100 Subject: [PATCH 2/4] chore(decryptAddress): add tests --- src/sdk/decrypt.test.ts | 28 ++++++++++++++++++++++++++++ src/sdk/decrypt.ts | 2 +- src/utils.ts | 4 +--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/sdk/decrypt.test.ts b/src/sdk/decrypt.test.ts index 50407e1..44c8485 100644 --- a/src/sdk/decrypt.test.ts +++ b/src/sdk/decrypt.test.ts @@ -44,4 +44,32 @@ describe('decrypt', () => { const cleartext = decryptAddress(keypair, ciphertext); expect(cleartext).toBe(getAddress(value.toString(16))); }); + + it('decrypts an address Uint8Array value bigger than 160 bits', async () => { + const keypair = sodium.crypto_box_keypair(); + const address = '0x9b8a8ba1f109551bd432803012645ac136ddd64dba72' + // Must truncate to 40-digit + const expected = '0x8ba1f109551bd432803012645ac136ddd64dba72' + const value = BigInt(address); + const ciphertext = sodium.crypto_box_seal( + bigIntToBytes(value), + keypair.publicKey, + ); + const cleartext = decryptAddress(keypair, ciphertext); + expect(cleartext).toBe(getAddress(expected)); + }); + + it.only('decrypts an address Uint8Array value lower than 160 bits', async () => { + const keypair = sodium.crypto_box_keypair(); + const address = '0x8ba1f109551bd432803012645ac136ddd64d' + // Must add padding until to 40-digit + const expected = '0x00008ba1f109551bd432803012645ac136ddd64d' + const value = BigInt(address); + const ciphertext = sodium.crypto_box_seal( + bigIntToBytes(value), + keypair.publicKey, + ); + const cleartext = decryptAddress(keypair, ciphertext); + expect(cleartext).toBe(getAddress(expected)); + }); }); diff --git a/src/sdk/decrypt.ts b/src/sdk/decrypt.ts index 3ea9530..3ca24b5 100644 --- a/src/sdk/decrypt.ts +++ b/src/sdk/decrypt.ts @@ -35,7 +35,7 @@ let hexString = bytesToHex(decrypted); if (hexString.length > 40) { hexString = hexString.substring(hexString.length - 40); } else { - hexString = hexString.padStart(40, '0'); + hexString = hexString.slice(2).padStart(40, '0'); } return getAddress(hexString); }; diff --git a/src/utils.ts b/src/utils.ts index 7283a85..a74dc06 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -19,8 +19,7 @@ export const bytesToHex = function (byteArray: Uint8Array): string { return '0x0'; } const buffer = Buffer.from(byteArray); - const result = '0x' + buffer.toString('hex'); - return result; + return `0x${buffer.toString('hex')}`; }; export const bytesToBigInt = function (byteArray: Uint8Array): bigint { @@ -30,7 +29,6 @@ export const bytesToBigInt = function (byteArray: Uint8Array): bigint { const buffer = Buffer.from(byteArray); const result = toBigIntBE(buffer); - return result; }; From 82304aa754fc1640d7d919bb77111afb4bcc4bdb Mon Sep 17 00:00:00 2001 From: Levent DEMIR Date: Mon, 18 Mar 2024 11:02:22 +0100 Subject: [PATCH 3/4] chore: remove forgotten it.only --- src/sdk/decrypt.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdk/decrypt.test.ts b/src/sdk/decrypt.test.ts index 44c8485..d4d1034 100644 --- a/src/sdk/decrypt.test.ts +++ b/src/sdk/decrypt.test.ts @@ -59,7 +59,7 @@ describe('decrypt', () => { expect(cleartext).toBe(getAddress(expected)); }); - it.only('decrypts an address Uint8Array value lower than 160 bits', async () => { + it('decrypts an address Uint8Array value lower than 160 bits', async () => { const keypair = sodium.crypto_box_keypair(); const address = '0x8ba1f109551bd432803012645ac136ddd64d' // Must add padding until to 40-digit From 1c934566260f9390b630adb3280a6e4caca94aaf Mon Sep 17 00:00:00 2001 From: Levent DEMIR Date: Mon, 18 Mar 2024 11:25:52 +0100 Subject: [PATCH 4/4] 0.4.0-9 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a21ca76..31f3bb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "fhevmjs", - "version": "0.4.0-8", + "version": "0.4.0-9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "fhevmjs", - "version": "0.4.0-8", + "version": "0.4.0-9", "license": "BSD-3-Clause-Clear", "dependencies": { "bigint-buffer": "^1.1.5", diff --git a/package.json b/package.json index 9b2b31d..5d8a753 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fhevmjs", - "version": "0.4.0-8", + "version": "0.4.0-9", "description": "fhEVM SDK for blockchain using TFHE", "main": "lib/node.cjs", "types": "lib/node.d.ts",