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", diff --git a/src/sdk/decrypt.test.ts b/src/sdk/decrypt.test.ts index 50407e1..d4d1034 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('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 f663c4c..3ca24b5 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.slice(2).padStart(40, '0'); +} + return getAddress(hexString); }; diff --git a/src/utils.ts b/src/utils.ts index 9a8dde9..a74dc06 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -18,13 +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'); - - return result; + return `0x${buffer.toString('hex')}`; }; export const bytesToBigInt = function (byteArray: Uint8Array): bigint { @@ -32,11 +27,8 @@ export const bytesToBigInt = function (byteArray: Uint8Array): bigint { return BigInt(0); } - const length = byteArray.length; - const buffer = Buffer.from(byteArray); const result = toBigIntBE(buffer); - return result; };