noir-lang / noir

Noir is a domain specific language for zero knowledge proofs
https://noir-lang.org
Apache License 2.0
887 stars 197 forks source link

`to_le_bits` Cannot satisfy constraints #2968

Closed SleepingShell closed 1 year ago

SleepingShell commented 1 year ago

Aim

Successfully run the below code snippet

Expected Behavior

No error for running the code

Bug

Running the below code with nargo prove will throw the following error:

error: Failed constraint
  ┌─ /home/user/dev/projects/darkforest-noir/mini/src/main.nr:7:16
  │
7 │     let bits = t.to_le_bits(32);
  │                ----------------
  │
  = Call stack:
    1. /home/user/dev/projects/darkforest-noir/mini/src/main.nr:12:15
    2. /home/user/dev/projects/darkforest-noir/mini/src/main.nr:7:16

Error: Cannot satisfy constraint 1924

Location:
    crates/nargo_cli/src/cli/mod.rs:79:5

nargo test does not cause this issue.

To Reproduce

use dep::std;
use dep::std::hash::mimc_bn254;

fn random(x: u124, y: u124, scale: u124, seed: Field) -> u4 {
    let t = std::hash::mimc_bn254([x as Field, y as Field, scale as Field, seed]);

    let bits = t.to_le_bits(32);
    8*(bits[3] as u4) + 4*(bits[2] as u4) + 2*(bits[1] as u4) + (bits[0] as u4)
}

fn main(x : u124, y : u124, scale: u124, seed: Field, result: pub u4) {
    let res = random(x,y,scale,seed);
    assert(res == result);
}

#[test]
fn test_main() {
    main(100, 100, 100, 100, 6);
}

Installation Method

Compiled from source

Nargo Version

nargo 0.13.0 (git version hash: 85965c324f7d5f813bbeffb105bba96f6ea5acfc, is dirty: false)

Additional Context

No response

Would you like to submit a PR for this Issue?

No

Support Needs

No response

guipublic commented 1 year ago

t.to_le_bits(32); is failing because t does not fit into 32 bits. You can simply do t as u4 instead of bit decomposition and then taking the first 4 bits.

SleepingShell commented 1 year ago

t.to_le_bits(32); is failing because t does not fit into 32 bits. You can simply do t as u4 instead of bit decomposition and then taking the first 4 bits.

Ah that makes sense, thank you. Oddly this worked on older compiler versions, which is why I thought this was a bug.

Just to confirm - casting an integer to a smaller sized integer removes the upper bits.