Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blake3 output not deterministic in guest #149

Closed
lrettig opened this issue Oct 12, 2024 · 3 comments · Fixed by #150
Closed

Blake3 output not deterministic in guest #149

lrettig opened this issue Oct 12, 2024 · 3 comments · Fixed by #150
Labels
bug Something isn't working guest issues involving guest code

Comments

@lrettig
Copy link
Contributor

lrettig commented Oct 12, 2024

Blake3 is exhibiting strange, non-deterministic behavior when running in the guest. Here's a simple test:

pub fn main() {
let value = "athexp_test2";
let res = hash(value.as_bytes());
println!(
"value: {}; as_bytes: {}; hash: {}",
value,
hex::encode(value.as_bytes()),
hex::encode(res.as_bytes())
);
let res = hash(value.as_bytes());
println!(
"value: {}; as_bytes: {}; hash: {}",
value,
hex::encode(value.as_bytes()),
hex::encode(res.as_bytes())
);
let res = hash(value.as_bytes());
println!(
"value: {}; as_bytes: {}; hash: {}",
value,
hex::encode(value.as_bytes()),
hex::encode(res.as_bytes())
);
}

It produces this output:

> (cd tests/hasher && cargo athena execute)

[athena]      Finished `release` profile [optimized] target(s) in 0.04s
Root package name: "hasher-test"
Target "hasher-test" artifact path: "hasher-test"
Creating output dir "athena/athena/tests/hasher/elf"
Copying original artifact "athena/athena/tests/hasher/target/elf-compilation/riscv32em-athena-zkvm-elf/release/hasher-test" to final path: "athena/athena/tests/hasher/elf/hasher-test"
2024-10-12T19:27:42.951223Z  INFO Initializing    
2024-10-12T19:27:42.951235Z  INFO loading memory image
2024-10-12T19:27:42.951569Z  INFO starting execution
2024-10-12T19:27:42.951574Z  INFO clk = 0 global_clk = 0 pc = 0x201d9c    
stdout: value: athexp_test2; as_bytes: 6174686578705f7465737432; hash: bd62654f3ffc34f6214542df5cd19b9e73cd017f837a01f67efc9106e3be6e30
stdout: value: athexp_test2; as_bytes: 6174686578705f7465737432; hash: e0609f2e9cd03f757397afa94575d8a40fa2d5e2c88afe164522e492496bb2bd
stdout: value: athexp_test2; as_bytes: 6174686578705f7465737432; hash: b7119b933731767cbc785d3a35c142853b4e4feab32f14f2a5043c52eee007a8
2024-10-12T19:27:42.953248Z  INFO Execution finished    
2024-10-12T19:27:42.953251Z  INFO finished execution clk = 86412 global_clk = 21603 pc = 0x0
    Finished executing in 0.00s
    Finished received 0 bytes output
@lrettig lrettig added bug Something isn't working guest issues involving guest code labels Oct 12, 2024
lrettig added a commit that referenced this issue Oct 12, 2024
For now working around #149
@lrettig
Copy link
Contributor Author

lrettig commented Oct 13, 2024

@poszu suggested that it's likely a memory issue and I agree. I looked for any memory issues that have been fixed in the upstream SP1 and didn't find any obvious ones, but I also noticed that the SP1 core runtime was rewritten in succinctlabs/sp1#1036.

I narrowed it down to an issue with this data structure; the second time the hash function is called, the buf isn't correctly initialized to zeroes, which causes problems in this method.

@poszu
Copy link
Collaborator

poszu commented Oct 14, 2024

I created a smaller test to reproduce it: https://github.com/athenavm/athena/blob/debug/corrupted-stack-init/tests/hasher/src/main.rs

After attaching GDB, I can see that parts of the buf array are not properly initialized to zeros the second time:

Breakpoint 1, hasher_test::main () at tests/hasher/src/main.rs:13
13	    println!("{buf:?}");
x /20wx buf
0x2002d0:	0x03020100	0x07060504	0x0b0a0908	0x0f0e0d0c
0x2002e0:	0x13121110	0x17161514	0x1b1a1918	0x1f1e1d1c
0x2002f0:	0x23222120	0x27262524	0x2b2a2928	0x2f2e2d2c
0x200300:	0x33323130	0x37363534	0x3b3a3938	0x3f3e3d3c
0x200310:	0x00000000	0x00000000	0x00000000	0x00000000
Breakpoint 7, hasher_test::main () at tests/hasher/src/main.rs:16
16	  println!("{buf:?}");
x /20wx buf
0x2002d0:	0x00000000	0x00000000	0x00000000	0x00000000
0x2002e0:	0x00000000	0x00000000	0x00000000	0x1f1e1d1c
0x2002f0:	0x00000000	0x27262524	0x00000000	0x2f2e2d2c
0x200300:	0x00000000	0x37363534	0x00000000	0x3f3e3d3c
0x200310:	0x00000000	0x00000000	0x00000000	0x00000000

@poszu
Copy link
Collaborator

poszu commented Oct 14, 2024

@lrettig The issue is most likely in memset-rv32e.s, although I have not yet found the bug. I replaced its implementation with a chat-gpt generated one and it works both in my simple test and with the blake3 hasher test of yours: https://github.com/athenavm/athena/blob/debug/corrupted-stack-init/vm/entrypoint/src/memset-rv32e.s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working guest issues involving guest code
Projects
None yet
2 participants