diff --git a/src/lib/provable/gadgets/sha256.ts b/src/lib/provable/gadgets/sha256.ts index 4d92c2e8f..60fc64ae0 100644 --- a/src/lib/provable/gadgets/sha256.ts +++ b/src/lib/provable/gadgets/sha256.ts @@ -8,7 +8,6 @@ import { Bytes } from '../wrapped-classes.js'; import { chunk } from '../../util/arrays.js'; import { TupleN } from '../../util/types.js'; import { divMod32 } from './arithmetic.js'; -import { bytesToWord, wordToBytes } from './bit-slices.js'; import { bitSlice } from './common.js'; import { rangeCheck16 } from './range-check.js'; @@ -70,11 +69,7 @@ function padding(data: FlexibleBytes): UInt32[][] { for (let i = 0; i < paddedMessage.length; i += 4) { // chunk 4 bytes into one UInt32, as expected by SHA256 // bytesToWord expects little endian, so we reverse the bytes - chunks.push( - UInt32.Unsafe.fromField( - bytesToWord(paddedMessage.slice(i, i + 4).reverse()) - ) - ); + chunks.push(UInt32.fromBytesBE(paddedMessage.slice(i, i + 4))); } // split message into 16 element sized message blocks @@ -97,8 +92,7 @@ const SHA256 = { } // the working variables H[i] are 32bit, however we want to decompose them into bytes to be more compatible - // wordToBytes expects little endian, so we reverse the bytes - return Bytes.from(H.map((x) => wordToBytes(x.value, 4).reverse()).flat()); + return Bytes.from(H.map((x) => x.toBytesBE()).flat()); }, compression: sha256Compression, createMessageSchedule, diff --git a/src/lib/provable/int.ts b/src/lib/provable/int.ts index e26c2cca0..1f4dee251 100644 --- a/src/lib/provable/int.ts +++ b/src/lib/provable/int.ts @@ -19,6 +19,7 @@ import { } from './gadgets/comparison.js'; import { assert } from '../util/assert.js'; import { TupleN } from '../util/types.js'; +import { bytesToWord, wordToBytes } from './gadgets/bit-slices.js'; // external API export { UInt8, UInt32, UInt64, Int64, Sign }; @@ -961,22 +962,15 @@ class UInt32 extends CircuitValue { /** * Split a UInt32 into 4 UInt8s, in little-endian order. */ - toBytes(): TupleN { - // witness the bytes - let bytes = Provable.witness(Provable.Array(UInt8, 4), () => { - let x = this.value.toBigInt(); - return [0, 1, 2, 3].map((i) => UInt8.from((x >> BigInt(8 * i)) & 0xffn)); - }); - // prove that bytes are correct - UInt32.fromBytes(bytes).assertEquals(this); - return TupleN.fromArray(4, bytes); + toBytes() { + return TupleN.fromArray(4, wordToBytes(this.value, 4)); } /** * Split a UInt32 into 4 UInt8s, in big-endian order. */ - toBytesBE(): TupleN { - return TupleN.fromArray(4, this.toBytes().reverse()); + toBytesBE() { + return TupleN.fromArray(4, wordToBytes(this.value, 4).reverse()); } /** @@ -984,12 +978,7 @@ class UInt32 extends CircuitValue { */ static fromBytes(bytes: UInt8[]): UInt32 { assert(bytes.length === 4, '4 bytes needed to create a uint32'); - - let word = Field(0); - bytes.forEach(({ value }, i) => { - word = word.add(value.mul(1n << BigInt(8 * i))); - }); - return UInt32.Unsafe.fromField(word); + return UInt32.Unsafe.fromField(bytesToWord(bytes)); } /**