#multiplexer
12 messages · Page 1 of 1 (latest)
You can use ‘Provable.switch’
How to build the one-hot encoded bool array from UInt32 (the easy way)
what is needed here is a decoder.
for example, a 3-bit decoder will take input in the range 0-7 and output a 3-bit vectors
5 => [1,0,1] ; 4 => [1,0,0] ....
and you assert 5 == 4*1 + 2*0 + 1*1 etc
then you can use the switch.
I am not aware of any library support for this. if it already exists.
Could probably use the packed bool class to achieve what @marsh otter is describing.
import { Field, Provable } from "o1js";
import { PackedBoolFactory } from "o1js-pack";
class EightBits extends PackedBoolFactory(8) {
}
class OneHot extends EightBits {
static check(value: { packed: Field }): void {
let countTrue = Field(0)
const unpacked = OneHot.unpack(value.packed)
for (let i = 0; i < OneHot.l; i++) {
const isTrue = Provable.if(
unpacked[i],
Field(1),
Field(0)
)
countTrue = countTrue.add(isTrue)
}
countTrue.assertEquals(Field(1));
}
}
const valid = OneHot.fromBooleans([
false, true, false, false,
false, false, false, false
])
console.log(valid.toBooleans())
OneHot.check(valid)
const inValid = OneHot.fromBooleans([
false, true, false, false,
true, false, false, false
])
console.log(valid.toBooleans())
OneHot.check(inValid)
Sample usage
We have such a decoder in o1js, it's field.toBits(3)
@full totem for UInt32 you can use uint.value.toBits(32)
Also @full totem I'm interested in your use case! Bit decomposition is somewhat expensive (even more than in circom which uses R1CS) and we have other tools like range checks which circom doesn't have
I am checking whether a chess move is valid, here I wanted to select a piece using a provided "id" ,
const selfPieces=Provable.if(this.whitesMove.getAndAssertEquals(),this.whitePieces.getAndAssertEquals(),this.blackPieces.getAndAssertEquals());
const oppPieces=Provable.if(this.whitesMove.getAndAssertEquals(),this.blackPieces.getAndAssertEquals(),this.whitePieces.getAndAssertEquals());
const board=Board.fromEncoded(selfPieces,oppPieces);
const piece=board.selfPieces[id];
//verify:
//piece should not be captured
piece.captured.assertFalse();
//piece can move to new position
piece.canMoveTo(newPosition).assertTrue();
//1.piece does not capture own piece
board.selfPieces.forEach((piece) => {
piece.position.equals(newPosition).assertFalse();
}, 'piece cannot capture own piece');
//2.piece does pass through other pieces
Provable.switch([piece.type], {);
//3.move does not put own king in check
//update board
piece.position.set(newPosition);
let [a,b]=board.encode();
this.whitePieces.set(a);
this.blackPieces.set(b);
this.whitesMove.set(this.whitesMove.get().not());
}```
@upbeat shore If I want to pack/unpack a field X into arrays is manipulating X as a bigInt better than bool array?
Is the .toBits() expensive , I want to know why is bit decomposition expensive?