From ed996117d8f03c7018285e7fab57b15b96937a2a Mon Sep 17 00:00:00 2001 From: Arseniy Klempner Date: Fri, 19 Dec 2025 12:22:41 -0800 Subject: [PATCH] fix: use viem for bytes32/bigint conversion --- packages/rln/src/proof.spec.ts | 4 ++-- packages/rln/src/utils/bytes.ts | 26 ++++---------------------- packages/rln/src/utils/epoch.ts | 2 +- packages/rln/src/utils/hash.ts | 2 +- packages/rln/src/zerokit.ts | 8 ++++---- 5 files changed, 12 insertions(+), 30 deletions(-) diff --git a/packages/rln/src/proof.spec.ts b/packages/rln/src/proof.spec.ts index 6a1499db86..e032bb57b7 100644 --- a/packages/rln/src/proof.spec.ts +++ b/packages/rln/src/proof.spec.ts @@ -77,14 +77,14 @@ describe("RLN Proof Integration Tests", function () { BytesUtils.bytes32FromBigInt(element, "little") ), proofElementIndexes.map((index) => - BytesUtils.writeUIntLE(new Uint8Array(1), index, 0, 1) + BytesUtils.writeUintLE(new Uint8Array(1), index, 0, 1) ), Number(rateLimit), 0 ); const isValid = rlnInstance.zerokit.verifyRLNProof( - BytesUtils.writeUIntLE(new Uint8Array(8), testMessage.length, 0, 8), + BytesUtils.writeUintLE(new Uint8Array(8), testMessage.length, 0, 8), testMessage, proof, [BytesUtils.bytes32FromBigInt(merkleRoot, "little")] diff --git a/packages/rln/src/utils/bytes.ts b/packages/rln/src/utils/bytes.ts index 61d4528fae..fbf7fc47be 100644 --- a/packages/rln/src/utils/bytes.ts +++ b/packages/rln/src/utils/bytes.ts @@ -1,3 +1,4 @@ +import { bytesToBigInt, numberToBytes } from "viem"; export class BytesUtils { /** * Concatenate Uint8Arrays @@ -32,21 +33,13 @@ export class BytesUtils { return 0n; } - // Create a copy to avoid modifying the original array const workingBytes = new Uint8Array(bytes); - // Reverse bytes if input is little-endian to work with big-endian internally if (inputEndianness === "little") { workingBytes.reverse(); } - // Convert to BigInt - let result = 0n; - for (let i = 0; i < workingBytes.length; i++) { - result = (result << 8n) | BigInt(workingBytes[i]); - } - - return result; + return bytesToBigInt(workingBytes, { size: 32 }); } /** @@ -69,18 +62,7 @@ export class BytesUtils { ); } - if (value === 0n) { - return new Uint8Array(32); - } - - const result = new Uint8Array(32); - let workingValue = value; - - // Extract bytes in big-endian order - for (let i = 31; i >= 0; i--) { - result[i] = Number(workingValue & 0xffn); - workingValue = workingValue >> 8n; - } + const result = numberToBytes(value, { size: 32 }); // If we need little-endian output, reverse the array if (outputEndianness === "little") { @@ -93,7 +75,7 @@ export class BytesUtils { /** * Writes an unsigned integer to a buffer in little-endian format */ - public static writeUIntLE( + public static writeUintLE( buf: Uint8Array, value: number, offset: number, diff --git a/packages/rln/src/utils/epoch.ts b/packages/rln/src/utils/epoch.ts index bf89d40aa5..458ec46246 100644 --- a/packages/rln/src/utils/epoch.ts +++ b/packages/rln/src/utils/epoch.ts @@ -17,7 +17,7 @@ export function dateToEpoch( } export function epochIntToBytes(epoch: number): Uint8Array { - return BytesUtils.writeUIntLE(new Uint8Array(32), epoch, 0, 32); + return BytesUtils.writeUintLE(new Uint8Array(32), epoch, 0, 32); } export function epochBytesToInt(bytes: Uint8Array): number { diff --git a/packages/rln/src/utils/hash.ts b/packages/rln/src/utils/hash.ts index 43908ce45d..c7a39152a7 100644 --- a/packages/rln/src/utils/hash.ts +++ b/packages/rln/src/utils/hash.ts @@ -3,7 +3,7 @@ import { hash, poseidonHash as poseidon } from "@waku/zerokit-rln-wasm-utils"; import { BytesUtils } from "./bytes.js"; export function poseidonHash(...input: Array): Uint8Array { - const inputLen = BytesUtils.writeUIntLE( + const inputLen = BytesUtils.writeUintLE( new Uint8Array(8), input.length, 0, diff --git a/packages/rln/src/zerokit.ts b/packages/rln/src/zerokit.ts index d39aebde85..ccf6fbda57 100644 --- a/packages/rln/src/zerokit.ts +++ b/packages/rln/src/zerokit.ts @@ -52,7 +52,7 @@ export class Zerokit { sha256(this.rlnIdentifier) ); const pathElementsBytes = new Uint8Array(8 + pathElements.length * 32); - BytesUtils.writeUIntLE(pathElementsBytes, pathElements.length, 0, 8); + BytesUtils.writeUintLE(pathElementsBytes, pathElements.length, 0, 8); for (let i = 0; i < pathElements.length; i++) { // We assume that the path elements are already in little-endian format pathElementsBytes.set(pathElements[i], 8 + i * 32); @@ -60,7 +60,7 @@ export class Zerokit { const identityPathIndexBytes = new Uint8Array( 8 + identityPathIndex.length * 1 ); - BytesUtils.writeUIntLE( + BytesUtils.writeUintLE( identityPathIndexBytes, identityPathIndex.length, 0, @@ -73,8 +73,8 @@ export class Zerokit { const x = sha256(msg); return BytesUtils.concatenate( idSecretHash, - BytesUtils.writeUIntLE(new Uint8Array(32), rateLimit, 0, 32), - BytesUtils.writeUIntLE(new Uint8Array(32), messageId, 0, 32), + BytesUtils.writeUintLE(new Uint8Array(32), rateLimit, 0, 32), + BytesUtils.writeUintLE(new Uint8Array(32), messageId, 0, 32), pathElementsBytes, identityPathIndexBytes, x,