Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8665x 8665x 8665x 8665x 8665x 8665x 8665x 8161x 8161x 8161x 8161x 8161x 8161x 8161x 8161x 8161x 8665x 8665x 8665x 8665x 8665x 8665x 8665x 8665x 8665x 8665x 8665x 8665x 8665x | import { Field, Provable, UInt64, Gadgets, Struct } from "o1js";
export class MulDivResult extends Struct({
result: UInt64,
remainder: UInt64,
}) {}
class MulDivResultInternal extends Struct({
result: Field,
remainder: Field,
}) {}
export function mulDiv(params: {
value: UInt64;
multiplier: UInt64;
denominator: UInt64;
}): MulDivResult {
const { value, multiplier, denominator } = params;
denominator.equals(UInt64.zero).assertFalse("division by zero"); // should fail in case the denominator is zero
const fields = Provable.witness(MulDivResultInternal, () => {
const valueBigInt = value.toBigInt();
const multiplierBigInt = multiplier.toBigInt();
const denominatorBigInt = denominator.toBigInt();
// handle division by zero for first pass of the prover that can pass zero instead of the real value
if (denominatorBigInt === 0n) {
return { result: Field.from(0n), remainder: Field.from(0n) };
}
const result = (valueBigInt * multiplierBigInt) / denominatorBigInt;
const remainder =
valueBigInt * multiplierBigInt - result * denominatorBigInt;
return { result: Field.from(result), remainder: Field.from(remainder) };
});
Gadgets.rangeCheck64(fields.result);
Gadgets.rangeCheck64(fields.remainder);
fields.remainder.assertLessThan(denominator.value); // should fail in case the denominator is zero
fields.result
.mul(denominator.value)
.add(fields.remainder)
.assertEquals(value.value.mul(multiplier.value)); // should fail in case the denominator is zero
return {
result: UInt64.Unsafe.fromField(fields.result),
remainder: UInt64.Unsafe.fromField(fields.remainder),
};
}
|