Skip to content

Commit

Permalink
uint32 to./from bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
mitschabaude committed Oct 11, 2024
1 parent 0384736 commit 8e3ac5e
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/lib/provable/int.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
lessThanOrEqualGeneric,
} from './gadgets/comparison.js';
import { assert } from '../util/assert.js';
import { TupleN } from '../util/types.js';

// external API
export { UInt8, UInt32, UInt64, Int64, Sign };
Expand Down Expand Up @@ -956,6 +957,47 @@ class UInt32 extends CircuitValue {
): InstanceType<T> {
return UInt32.from(x) as any;
}

/**
* Split a UInt32 into 4 UInt8s, in little-endian order.
*/
toBytes(): TupleN<UInt8, 4> {
// 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);
}

/**
* Split a UInt32 into 4 UInt8s, in big-endian order.
*/
toBytesBE(): TupleN<UInt8, 4> {
return TupleN.fromArray(4, this.toBytes().reverse());
}

/**
* Combine 4 UInt8s into a UInt32, in little-endian order.
*/
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);
}

/**
* Combine 4 UInt8s into a UInt32, in big-endian order.
*/
static fromBytesBE(bytes: UInt8[]): UInt32 {
return UInt32.fromBytes([...bytes].reverse());
}
}

class Sign extends CircuitValue {
Expand Down

0 comments on commit 8e3ac5e

Please sign in to comment.