UNPKG

@nori-zk/o1js-zk-utils

Version:

o1js-zk-utils supporting Nori Bridge

135 lines (123 loc) 4.58 kB
import { Bytes, Field, Struct, UInt8, } from 'o1js'; export class Bytes32 extends Bytes(32) { static get zero() { return new this(new Array(32).map(() => new UInt8(0))); } } export class Bytes20 extends Bytes(20) { static get zero() { return new this(new Array(20).map(() => new UInt8(0))); } } export class Bytes32FieldPair extends Struct({ highByteField: Field, lowerBytesField: Field, }) { static fromBytes32(bytes32) { // Convert the store hash's higher byte into a provable field. let storeHashHighByteField = new Field(0); storeHashHighByteField = storeHashHighByteField.add(bytes32.bytes[0].value); // Convert the store hash's lower 31 bytes into a provable field. let storeHashLowerBytesField = new Field(0); for (let i = 1; i < 32; i++) { storeHashLowerBytesField = storeHashLowerBytesField .mul(256) .add(bytes32.bytes[i].value); } return new this({ highByteField: storeHashHighByteField, lowerBytesField: storeHashLowerBytesField, }); } } // Next version could do something like this: // (we could then fit two state into the contract a->b to allow the client minting more time) /* // Extract and accumulate lower 31 bytes of each Bytes32 field function extractHighAndLowerBytes(bytes32: Bytes32): { high: Field; low: Field; } { const high = new Field(bytes32.bytes[0].value); let low = new Field(0); for (let i = 1; i < 32; i++) { low = low.mul(256).add(bytes32.bytes[i].value); } return { high, low }; } // Extract 31 bytes from a Field using bit manipulation (little-endian) // Probably better with a witness. export function extractBytesFromField(packed: Field): UInt8[] { const bits = packed.toBits(); const bytes: UInt8[] = []; for (let i = 0; i < 31; i++) { let value = new Field(0); for (let j = 7; j >= 0; j--) { value = value.mul(2); const bit = bits[i * 8 + j]; value = Provable.if(bit, value.add(1), value); } bytes.push(UInt8.from(value)); } return bytes; } // Reconstruct a Bytes32 from high byte + packed lower 31 bytes function reconstructBytes32(highByte: UInt8, lowerBytesField: Field): Bytes32 { const lowerBytes = extractBytesFromField(lowerBytesField); const allBytes = [highByte, ...lowerBytes]; return Bytes32.from(allBytes); } // Input Struct export class EthProcessorMutateStateInputs extends Struct({ storageHash: Bytes32, verifiedContractDepositsRoot: Bytes32, verifiedStateRoot: Bytes32, }) {} // Internal Mutable State Struct export class EthProcessorMutableState extends Struct({ storageHashLower: Field, verifiedDepositsCurrentRootLower: Field, verifiedCurrentStateRootLower: Field, contractMiscField: Field, // 3 high bytes packed: storageHigh, depositHigh, stateHigh }) { static fromInputs( storageHash: Bytes32, verifiedContractDepositsCurrentRoot: Bytes32, verifiedCurrentStateRoot: Bytes32 ) { const { high: storageHigh, low: storageHashLower } = extractHighAndLowerBytes(storageHash); const { high: depositHigh, low: verifiedDepositsCurrentRootLower } = extractHighAndLowerBytes(verifiedContractDepositsCurrentRoot); const { high: stateHigh, low: verifiedCurrentStateRootLower } = extractHighAndLowerBytes(verifiedCurrentStateRoot); // Pack high bytes: [storageHigh, depositHigh, stateHigh] -> into one Field let contractMiscField = new Field(0); contractMiscField = contractMiscField .add(stateHigh) // LSB .mul(256) .add(depositHigh) .mul(256) .add(storageHigh); // MSB return new this({ storageHashLower, verifiedDepositsCurrentRootLower, verifiedCurrentStateRootLower, contractMiscField, }); } toInputs(): EthProcessorMutateStateInputs { const miscBytes = extractBytesFromField(this.contractMiscField); // Unpack in same order as packed const stateHigh = miscBytes[0]; const depositHigh = miscBytes[1]; const storageHigh = miscBytes[2]; const storageHash = reconstructBytes32(storageHigh, this.storageHashLower); const verifiedContractDepositsRoot = reconstructBytes32(depositHigh, this.verifiedDepositsCurrentRootLower); const verifiedStateRoot = reconstructBytes32(stateHigh, this.verifiedCurrentStateRootLower); return new EthProcessorMutateStateInputs({ storageHash, verifiedContractDepositsRoot, verifiedStateRoot, }); } } */ //# sourceMappingURL=types.js.map