Skip to content

Use proper types for values returned from unconstrained functions #51

@TomAFrench

Description

@TomAFrench

There's a lot of cases where Zac has broken out of the type system for zero benefit. This just harms readability without improving performance, e.g. decompose is doing a bit decomposition but return in the values as Field

/**
* @brief converts a 16 bit value into 16 fake bools (Field elements that are 0 or 1)
**/
unconstrained fn decompose(val: Field) -> [Field; 16] {
let mut r: [Field; 16] = [0; 16];
let mut it = val as u32;
for i in 0..16 {
r[i] = (it & 1) as Field;
it >>= 1;
}
r
}

Rather than using Noir's automatic constraining of return types of unconstrained functions, he's instead injecting a manual boolean check here:

// we check that the path valid bits are binary
assert(path_valid_bits[i] * path_valid_bits[i] - path_valid_bits[i] == 0);

This is a direct 1:1 with what Noir would do if it was just written with the expected types from the start.


Having written this out, I noticed that Zac is just doing to_le_bits here so we can remove this function entirely.... That said, there's likely a bunch of different cases of this around the library.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    👀 To Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions