diff --git a/Cargo.lock b/Cargo.lock index ce71b932..1ecb8f44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,6 +158,22 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -839,10 +855,12 @@ dependencies = [ "interpreter", "itertools", "log", + "num", "plonky2", "rand", "regex", "rocksdb", + "secp256k1 0.28.1", "serde", "serde_derive", "serde_json", @@ -1149,6 +1167,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-conservative" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2" + [[package]] name = "hex-literal" version = "0.3.4" @@ -2370,7 +2394,17 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" dependencies = [ - "secp256k1-sys", + "secp256k1-sys 0.8.1", +] + +[[package]] +name = "secp256k1" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f622567e3b4b38154fb8190bcf6b160d7a4301d70595a49195b48c116007a27" +dependencies = [ + "bitcoin_hashes", + "secp256k1-sys 0.9.2", ] [[package]] @@ -2382,6 +2416,15 @@ dependencies = [ "cc", ] +[[package]] +name = "secp256k1-sys" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +dependencies = [ + "cc", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -3106,7 +3149,7 @@ dependencies = [ "pin-project", "reqwest", "rlp", - "secp256k1", + "secp256k1 0.27.0", "serde", "serde_json", "soketto", @@ -3345,6 +3388,7 @@ dependencies = [ name = "zk-vm" version = "0.1.0" dependencies = [ + "bincode", "core", "env_logger 0.6.2", "executor", diff --git a/assembler/src/asm.rs b/assembler/src/asm.rs index c956d5b0..caad63dc 100644 --- a/assembler/src/asm.rs +++ b/assembler/src/asm.rs @@ -162,11 +162,16 @@ fn split_ola_asm_pieces( | OlaOpcode::TSTORE | OlaOpcode::SCCALL | OlaOpcode::SLOAD - | OlaOpcode::SSTORE => { + | OlaOpcode::SSTORE + | OlaOpcode::SIGCHECK => { if ops.len() != 2 { return Err(format!("invalid operand size: {}", asm_line)); } - if opcode == OlaOpcode::MOV || opcode == OlaOpcode::NOT || opcode == OlaOpcode::MLOAD { + if opcode == OlaOpcode::MOV + || opcode == OlaOpcode::NOT + || opcode == OlaOpcode::MLOAD + || opcode == OlaOpcode::SIGCHECK + { let dst = ops.get(0).unwrap(); let op1 = ops.get(1).unwrap(); Ok((opcode, None, Some(op1.clone()), Some(dst.clone()))) diff --git a/assembler/src/test_data_generator.rs b/assembler/src/test_data_generator.rs index 36c9cfd4..1ba3b424 100644 --- a/assembler/src/test_data_generator.rs +++ b/assembler/src/test_data_generator.rs @@ -238,6 +238,16 @@ mod tests { ); } + #[test] + fn generate_hash() { + generate_from_file("hash_asm.json".to_string(), "hash.json".to_string()); + } + + #[test] + fn generate_ecdsa() { + generate_from_file("ecdsa_asm.json".to_string(), "ecdsa.json".to_string()); + } + fn generate_from_file(input_file_name: String, output_file_name: String) { let _ = fs::create_dir_all("test_data/bin/sccall"); let input_path = format!("test_data/asm/{}", input_file_name); diff --git a/assembler/test_data/asm/ecdsa_asm.json b/assembler/test_data/asm/ecdsa_asm.json new file mode 100644 index 00000000..2a170998 --- /dev/null +++ b/assembler/test_data/asm/ecdsa_asm.json @@ -0,0 +1,97 @@ +{ + "program": "heap_malloc:\n.LBL17_0:\n mov r3 18446744060824649731\n mload r0 [r3]\n add r2 r0 r1\n mov r1 18446744060824649731\n mstore [r1] r2\n ret\nvector_new:\n.LBL18_0:\n mov r4 18446744060824649731\n mload r0 [r4]\n add r2 r1 1\n add r3 r0 r2\n mov r2 18446744060824649731\n mstore [r2] r3\n mstore [r0] r1\n ret\nsplit_field:\n.LBL19_0:\n mov r6 r1\n mov r1 r6\n.PROPHET19_0:\n mov r0 psp\n mload r0 [r0]\n mov r7 r0\n range r7\n mov r1 r6\n.PROPHET19_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n range r1\n mul r4 r7 4294967296\n add r5 r4 r1\n eq r4 r6 r5\n assert r4\n mstore [r2] r7\n mstore [r3] r1\n ret\nmemcpy:\n.LBL20_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL20_1\n.LBL20_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL20_2\n jmp .LBL20_3\n.LBL20_2:\n mload r6 [r1,r4]\n mstore [r2,r4] r6\n add r5 r4 1\n mstore [r9,-1] r5\n jmp .LBL20_1\n.LBL20_3:\n add r9 r9 -1\n ret\nmemcmp_eq:\n.LBL21_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL21_1\n.LBL21_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL21_2\n mov r0 1\n jmp .LBL21_3\n.LBL21_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n eq r4 r6 r7\n cjmp r4 .LBL21_1\n mov r0 0\n jmp .LBL21_3\n.LBL21_3:\n add r9 r9 -1\n ret\nmemcmp_ne:\n.LBL22_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL22_1\n.LBL22_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL22_2\n mov r0 0\n jmp .LBL22_3\n.LBL22_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n eq r4 r6 r7\n cjmp r4 .LBL22_1\n mov r0 1\n jmp .LBL22_3\n.LBL22_3:\n add r9 r9 -1\n ret\nmemcmp_ugt:\n.LBL23_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL23_1\n.LBL23_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL23_2\n mov r0 0\n jmp .LBL23_3\n.LBL23_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r7 r6\n cjmp r4 .LBL23_1\n mov r0 1\n jmp .LBL23_3\n.LBL23_3:\n add r9 r9 -1\n ret\nmemcmp_uge:\n.LBL24_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL24_1\n.LBL24_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL24_2\n mov r0 1\n jmp .LBL24_3\n.LBL24_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r6 r7\n cjmp r4 .LBL24_1\n mov r0 0\n jmp .LBL24_3\n.LBL24_3:\n add r9 r9 -1\n ret\nmemcmp_ult:\n.LBL25_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL25_1\n.LBL25_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL25_2\n mov r0 0\n jmp .LBL25_3\n.LBL25_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r6 r7\n cjmp r4 .LBL25_1\n mov r0 1\n jmp .LBL25_3\n.LBL25_3:\n add r9 r9 -1\n ret\nmemcmp_ule:\n.LBL26_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL26_1\n.LBL26_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL26_2\n mov r0 1\n jmp .LBL26_3\n.LBL26_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r7 r6\n cjmp r4 .LBL26_1\n mov r0 0\n jmp .LBL26_3\n.LBL26_3:\n add r9 r9 -1\n ret\nfield_memcmp_ugt:\n.LBL27_0:\n add r9 r9 20\n mstore [r9,-2] r9\n mstore [r9,-8] r1\n mov r1 r2\n mstore [r9,-13] r1\n mov r1 r3\n mstore [r9,-10] r1\n mov r1 0\n mstore [r9,-7] r1\n jmp .LBL27_1\n.LBL27_1:\n mload r1 [r9,-7]\n mstore [r9,-12] r1\n mload r1 [r9,-10]\n mload r2 [r9,-12]\n gte r1 r1 r2\n mload r2 [r9,-10]\n mload r3 [r9,-12]\n neq r2 r3 r2\n and r1 r1 r2\n cjmp r1 .LBL27_2\n mov r0 0\n jmp .LBL27_4\n.LBL27_2:\n mload r1 [r9,-8]\n mload r2 [r9,-12]\n mload r1 [r1,r2]\n mload r2 [r9,-12]\n mload r3 [r9,-13]\n mload r2 [r3,r2]\n mstore [r9,-9] r2\n add r3 r9 -5\n add r2 r9 -6\n call split_field\n mload r1 [r9,-6]\n mstore [r9,-20] r1\n mload r1 [r9,-5]\n mstore [r9,-17] r1\n add r3 r9 -3\n add r2 r9 -4\n mload r1 [r9,-9]\n call split_field\n mload r1 [r9,-4]\n mload r2 [r9,-3]\n mload r3 [r9,-12]\n add r3 r3 1\n mstore [r9,-11] r3\n mload r3 [r9,-11]\n mstore [r9,-7] r3\n mload r3 [r9,-20]\n gte r1 r1 r3\n cjmp r1 .LBL27_3\n mov r0 1\n jmp .LBL27_4\n.LBL27_3:\n mload r1 [r9,-17]\n gte r1 r2 r1\n cjmp r1 .LBL27_1\n mov r0 1\n jmp .LBL27_4\n.LBL27_4:\n add r9 r9 -20\n ret\nfield_memcmp_uge:\n.LBL28_0:\n add r9 r9 20\n mstore [r9,-2] r9\n mstore [r9,-8] r1\n mov r1 r2\n mstore [r9,-13] r1\n mov r1 r3\n mstore [r9,-10] r1\n mov r1 0\n mstore [r9,-7] r1\n jmp .LBL28_1\n.LBL28_1:\n mload r1 [r9,-7]\n mstore [r9,-12] r1\n mload r1 [r9,-10]\n mload r2 [r9,-12]\n gte r1 r1 r2\n mload r2 [r9,-10]\n mload r3 [r9,-12]\n neq r2 r3 r2\n and r1 r1 r2\n cjmp r1 .LBL28_2\n mov r0 1\n jmp .LBL28_4\n.LBL28_2:\n mload r1 [r9,-8]\n mload r2 [r9,-12]\n mload r1 [r1,r2]\n mload r2 [r9,-12]\n mload r3 [r9,-13]\n mload r2 [r3,r2]\n mstore [r9,-9] r2\n add r3 r9 -5\n add r2 r9 -6\n call split_field\n mload r1 [r9,-6]\n mstore [r9,-20] r1\n mload r1 [r9,-5]\n mstore [r9,-17] r1\n add r3 r9 -3\n add r2 r9 -4\n mload r1 [r9,-9]\n call split_field\n mload r1 [r9,-4]\n mload r2 [r9,-3]\n mload r3 [r9,-12]\n add r3 r3 1\n mstore [r9,-11] r3\n mload r3 [r9,-11]\n mstore [r9,-7] r3\n mload r3 [r9,-20]\n gte r1 r3 r1\n cjmp r1 .LBL28_3\n mov r0 0\n jmp .LBL28_4\n.LBL28_3:\n mload r1 [r9,-17]\n gte r1 r1 r2\n cjmp r1 .LBL28_1\n mov r0 0\n jmp .LBL28_4\n.LBL28_4:\n add r9 r9 -20\n ret\nfield_memcmp_ule:\n.LBL29_0:\n add r9 r9 20\n mstore [r9,-2] r9\n mstore [r9,-8] r1\n mov r1 r2\n mstore [r9,-13] r1\n mov r1 r3\n mstore [r9,-10] r1\n mov r1 0\n mstore [r9,-7] r1\n jmp .LBL29_1\n.LBL29_1:\n mload r1 [r9,-7]\n mstore [r9,-12] r1\n mload r1 [r9,-10]\n mload r2 [r9,-12]\n gte r1 r1 r2\n mload r2 [r9,-10]\n mload r3 [r9,-12]\n neq r2 r3 r2\n and r1 r1 r2\n cjmp r1 .LBL29_2\n mov r0 1\n jmp .LBL29_4\n.LBL29_2:\n mload r1 [r9,-8]\n mload r2 [r9,-12]\n mload r1 [r1,r2]\n mload r2 [r9,-12]\n mload r3 [r9,-13]\n mload r2 [r3,r2]\n mstore [r9,-9] r2\n add r3 r9 -5\n add r2 r9 -6\n call split_field\n mload r1 [r9,-6]\n mstore [r9,-20] r1\n mload r1 [r9,-5]\n mstore [r9,-17] r1\n add r3 r9 -3\n add r2 r9 -4\n mload r1 [r9,-9]\n call split_field\n mload r1 [r9,-4]\n mload r2 [r9,-3]\n mload r3 [r9,-12]\n add r3 r3 1\n mstore [r9,-11] r3\n mload r3 [r9,-11]\n mstore [r9,-7] r3\n mload r3 [r9,-20]\n gte r1 r1 r3\n cjmp r1 .LBL29_3\n mov r0 0\n jmp .LBL29_4\n.LBL29_3:\n mload r1 [r9,-17]\n gte r1 r2 r1\n cjmp r1 .LBL29_1\n mov r0 0\n jmp .LBL29_4\n.LBL29_4:\n add r9 r9 -20\n ret\nfield_memcmp_ult:\n.LBL30_0:\n add r9 r9 20\n mstore [r9,-2] r9\n mstore [r9,-8] r1\n mov r1 r2\n mstore [r9,-13] r1\n mov r1 r3\n mstore [r9,-10] r1\n mov r1 0\n mstore [r9,-7] r1\n jmp .LBL30_1\n.LBL30_1:\n mload r1 [r9,-7]\n mstore [r9,-12] r1\n mload r1 [r9,-10]\n mload r2 [r9,-12]\n gte r1 r1 r2\n mload r2 [r9,-10]\n mload r3 [r9,-12]\n neq r2 r3 r2\n and r1 r1 r2\n cjmp r1 .LBL30_2\n mov r0 0\n jmp .LBL30_4\n.LBL30_2:\n mload r1 [r9,-8]\n mload r2 [r9,-12]\n mload r1 [r1,r2]\n mload r2 [r9,-12]\n mload r3 [r9,-13]\n mload r2 [r3,r2]\n mstore [r9,-9] r2\n add r3 r9 -5\n add r2 r9 -6\n call split_field\n mload r1 [r9,-6]\n mstore [r9,-20] r1\n mload r1 [r9,-5]\n mstore [r9,-17] r1\n add r3 r9 -3\n add r2 r9 -4\n mload r1 [r9,-9]\n call split_field\n mload r1 [r9,-4]\n mload r2 [r9,-3]\n mload r3 [r9,-12]\n add r3 r3 1\n mstore [r9,-11] r3\n mload r3 [r9,-11]\n mstore [r9,-7] r3\n mload r3 [r9,-20]\n gte r1 r3 r1\n cjmp r1 .LBL30_3\n mov r0 1\n jmp .LBL30_4\n.LBL30_3:\n mload r1 [r9,-17]\n gte r1 r1 r2\n cjmp r1 .LBL30_1\n mov r0 1\n jmp .LBL30_4\n.LBL30_4:\n add r9 r9 -20\n ret\nu32_div_mod:\n.LBL31_0:\n add r9 r9 5\n mstore [r9,-3] r1\n mov r1 r2\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mov r2 r1\n mload r1 [r9,-3]\n.PROPHET31_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mstore [r9,-5] r1\n mload r1 [r9,-5]\n range r1\n mload r1 [r9,-5]\n add r5 r1 1\n not r7 r5\n add r7 r7 1\n mload r1 [r9,-4]\n add r6 r1 r7\n range r6\n mload r1 [r9,-4]\n mov r2 r1\n mload r1 [r9,-3]\n.PROPHET31_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n range r3\n mload r2 [r9,-4]\n mul r2 r1 r2\n mstore [r9,-1] r2\n mload r2 [r9,-1]\n mload r5 [r9,-5]\n add r2 r2 r5\n mstore [r9,-2] r2\n mload r2 [r9,-2]\n mload r5 [r9,-3]\n eq r2 r2 r5\n assert r2\n mstore [r3] r1\n mload r1 [r9,-5]\n mstore [r4] r1\n add r9 r9 -5\n ret\nu32_power:\n.LBL32_0:\n mov r0 1\n mov r3 0\n jmp .LBL32_1\n.LBL32_1:\n add r5 r3 1\n mul r4 r0 r1\n gte r3 r2 r5\n cjmp r3 .LBL32_1\n mov r0 r4\n mov r3 r5\n jmp .LBL32_2\n.LBL32_2:\n range r0\n ret\ncheck_ecdsa:\n.LBL33_0:\n add r9 r9 12\n mstore [r9,-2] r9\n mov r5 r1\n mstore [r9,-3] r5\n mov r5 r2\n mstore [r9,-4] r5\n mov r5 r3\n mstore [r9,-5] r5\n mov r1 20\n call heap_malloc\n mov r5 r0\n mstore [r9,-8] r5\n mov r3 4\n mload r2 [r9,-8]\n mload r1 [r9,-3]\n call memcpy\n mov r3 8\n mload r5 [r9,-8]\n add r5 r5 4\n mstore [r9,-9] r5\n mload r2 [r9,-9]\n mload r5 [r9,-4]\n add r1 r5 1\n call memcpy\n mov r3 8\n mload r5 [r9,-9]\n add r2 r5 8\n mload r5 [r9,-5]\n add r1 r5 1\n call memcpy\n mload r5 [r9,-8]\n sigcheck r0 r5\n add r9 r9 -12\n ret\ncheck_ecdsa_test:\n.LBL34_0:\n add r9 r9 5\n mstore [r9,-2] r9\n mov r1 4\n call heap_malloc\n mov r5 r0\n mov r6 8100099710329060113\n mstore [r5] r6\n mov r6 1691964059337354474\n mstore [r5,+1] r6\n mov r6 2619454573477891356\n mstore [r5,+2] r6\n mov r6 14789418598207764286\n mstore [r5,+3] r6\n mstore [r9,-4] r5\n mov r1 8\n call vector_new\n mov r5 r0\n mstore [r9,-5] r5\n mload r5 [r9,-5]\n add r5 r5 1\n mov r6 16082862629786954522\n mstore [r5] r6\n mov r6 18230050229933857031\n mstore [r5,+1] r6\n mov r6 5147452894439374020\n mstore [r5,+2] r6\n mov r6 7123102033214096931\n mstore [r5,+3] r6\n mov r6 18146431795413334852\n mstore [r5,+4] r6\n mov r6 14267346997562947978\n mstore [r5,+5] r6\n mov r6 16850228878206657517\n mstore [r5,+6] r6\n mov r6 11850760313150838435\n mstore [r5,+7] r6\n mov r1 8\n call vector_new\n mov r3 r0\n add r5 r3 1\n mov r6 3136689052219066478\n mstore [r5] r6\n mov r6 13835160098228565381\n mstore [r5,+1] r6\n mov r6 16653245190936664457\n mstore [r5,+2] r6\n mov r6 8159748729834307751\n mstore [r5,+3] r6\n mov r6 9003827909761961299\n mstore [r5,+4] r6\n mov r6 15903809184042520377\n mstore [r5,+5] r6\n mov r6 8474226046933642703\n mstore [r5,+6] r6\n mov r6 14159585317199163842\n mstore [r5,+7] r6\n mload r1 [r9,-4]\n mload r2 [r9,-5]\n call check_ecdsa\n mov r5 r0\n mstore [r9,-3] r5\n mload r5 [r9,-3]\n assert r5\n add r9 r9 -5\n ret\nfunction_dispatch:\n.LBL35_0:\n add r9 r9 2\n mstore [r9,-2] r9\n mov r2 r3\n eq r8 r1 370402988\n cjmp r8 .LBL35_2\n jmp .LBL35_1\n.LBL35_1:\n ret\n.LBL35_2:\n call check_ecdsa_test\n mov r1 1\n call heap_malloc\n mov r1 r0\n mov r2 0\n mstore [r1] r2\n tstore r1 1\n add r9 r9 -2\n ret\nmain:\n.LBL36_0:\n add r9 r9 8\n mstore [r9,-2] r9\n mov r1 13\n call heap_malloc\n mov r5 r0\n mov r6 1\n tload r5 r6 13\n mload r5 [r5]\n mstore [r9,-4] r5\n mov r1 14\n call heap_malloc\n mov r5 r0\n mov r6 1\n tload r5 r6 14\n mload r5 [r5]\n mstore [r9,-6] r5\n mload r5 [r9,-6]\n add r5 r5 14\n mstore [r9,-3] r5\n mload r1 [r9,-3]\n call heap_malloc\n mov r3 r0\n mov r5 1\n mload r6 [r9,-3]\n tload r3 r5 r6\n mload r2 [r9,-6]\n mload r1 [r9,-4]\n call function_dispatch\n add r9 r9 -8\n end\n", + "prophets": [ + { + "label": ".PROPHET19_0", + "code": "%{\n function split_hi(felt in) -> felt {\n return in / 4294967296;\n }\n entry() {\n cid.out = split_hi(cid.in);\n }\n%}", + "inputs": [ + { + "name": "cid.in", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.out", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET19_1", + "code": "%{\n function split_lo(felt in) -> felt {\n return in % 4294967296;\n }\n entry() {\n cid.out = split_lo(cid.in);\n }\n%}", + "inputs": [ + { + "name": "cid.in", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.out", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET31_0", + "code": "%{\n function mod(felt x, felt y) -> felt {\n return x % y;\n }\n entry() {\n cid.r = mod(cid.x, cid.y);\n }\n%}", + "inputs": [ + { + "name": "cid.x", + "length": 1, + "is_ref": false, + "is_input_output": false + }, + { + "name": "cid.y", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.r", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET31_1", + "code": "%{\n function div(felt x, felt y) -> felt {\n return x / y;\n }\n entry() {\n cid.q = div(cid.x, cid.y);\n }\n%}", + "inputs": [ + { + "name": "cid.x", + "length": 1, + "is_ref": false, + "is_input_output": false + }, + { + "name": "cid.y", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.q", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + } + ] +} diff --git a/assembler/test_data/asm/hash_asm.json b/assembler/test_data/asm/hash_asm.json new file mode 100644 index 00000000..dd06bd6a --- /dev/null +++ b/assembler/test_data/asm/hash_asm.json @@ -0,0 +1,97 @@ +{ + "program": "heap_malloc:\n.LBL17_0:\n mov r3 18446744060824649731\n mload r0 [r3]\n add r2 r0 r1\n mov r1 18446744060824649731\n mstore [r1] r2\n ret\nvector_new:\n.LBL18_0:\n mov r4 18446744060824649731\n mload r0 [r4]\n add r2 r1 1\n add r3 r0 r2\n mov r2 18446744060824649731\n mstore [r2] r3\n mstore [r0] r1\n ret\nsplit_field:\n.LBL19_0:\n mov r6 r1\n mov r1 r6\n.PROPHET19_0:\n mov r0 psp\n mload r0 [r0]\n mov r7 r0\n range r7\n mov r1 r6\n.PROPHET19_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n range r1\n mul r4 r7 4294967296\n add r5 r4 r1\n eq r4 r6 r5\n assert r4\n mstore [r2] r7\n mstore [r3] r1\n ret\nmemcpy:\n.LBL20_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL20_1\n.LBL20_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL20_2\n jmp .LBL20_3\n.LBL20_2:\n mload r6 [r1,r4]\n mstore [r2,r4] r6\n add r5 r4 1\n mstore [r9,-1] r5\n jmp .LBL20_1\n.LBL20_3:\n add r9 r9 -1\n ret\nmemcmp_eq:\n.LBL21_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL21_1\n.LBL21_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL21_2\n mov r0 1\n jmp .LBL21_3\n.LBL21_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n eq r4 r6 r7\n cjmp r4 .LBL21_1\n mov r0 0\n jmp .LBL21_3\n.LBL21_3:\n add r9 r9 -1\n ret\nmemcmp_ne:\n.LBL22_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL22_1\n.LBL22_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL22_2\n mov r0 1\n jmp .LBL22_3\n.LBL22_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n eq r4 r6 r7\n cjmp r4 .LBL22_3\n mov r0 0\n jmp .LBL22_1\n.LBL22_3:\n add r9 r9 -1\n ret\nmemcmp_ugt:\n.LBL23_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL23_1\n.LBL23_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL23_2\n mov r0 1\n jmp .LBL23_3\n.LBL23_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r7 r6\n cjmp r4 .LBL23_3\n mov r0 0\n jmp .LBL23_1\n.LBL23_3:\n add r9 r9 -1\n ret\nmemcmp_uge:\n.LBL24_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL24_1\n.LBL24_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL24_2\n mov r0 1\n jmp .LBL24_3\n.LBL24_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r6 r7\n cjmp r4 .LBL24_1\n mov r0 0\n jmp .LBL24_3\n.LBL24_3:\n add r9 r9 -1\n ret\nmemcmp_ult:\n.LBL25_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL25_1\n.LBL25_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL25_2\n mov r0 1\n jmp .LBL25_3\n.LBL25_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r6 r7\n cjmp r4 .LBL25_3\n mov r0 0\n jmp .LBL25_1\n.LBL25_3:\n add r9 r9 -1\n ret\nmemcmp_ule:\n.LBL26_0:\n add r9 r9 1\n mov r4 0\n mstore [r9,-1] r4\n jmp .LBL26_1\n.LBL26_1:\n mload r4 [r9,-1]\n gte r5 r3 r4\n neq r6 r4 r3\n and r5 r5 r6\n cjmp r5 .LBL26_2\n mov r0 1\n jmp .LBL26_3\n.LBL26_2:\n mload r6 [r1,r4]\n mload r7 [r2,r4]\n add r5 r4 1\n mstore [r9,-1] r5\n gte r4 r7 r6\n cjmp r4 .LBL26_1\n mov r0 0\n jmp .LBL26_3\n.LBL26_3:\n add r9 r9 -1\n ret\nfield_memcmp_ugt:\n.LBL27_0:\n add r9 r9 14\n mstore [r9,-2] r9\n mov r6 0\n mstore [r9,-7] r6\n jmp .LBL27_1\n.LBL27_1:\n mload r6 [r9,-7]\n mstore [r9,-11] r6\n mload r6 [r9,-11]\n gte r6 r3 r6\n mload r7 [r9,-11]\n neq r3 r7 r3\n and r6 r6 r3\n cjmp r6 .LBL27_2\n mov r0 1\n jmp .LBL27_4\n.LBL27_2:\n mload r3 [r9,-11]\n mload r1 [r1,r3]\n mload r3 [r9,-11]\n mload r2 [r2,r3]\n mstore [r9,-8] r2\n mov r3 r4\n mov r2 r5\n call split_field\n mload r3 [r9,-12]\n mload r2 [r9,-10]\n mload r1 [r9,-8]\n call split_field\n mload r1 [r9,-6]\n mload r2 [r9,-4]\n mload r3 [r9,-5]\n mload r4 [r9,-3]\n mload r5 [r9,-11]\n add r5 r5 1\n mstore [r9,-9] r5\n mload r5 [r9,-9]\n mstore [r9,-7] r5\n gte r1 r2 r1\n cjmp r1 .LBL27_4\n mov r0 0\n jmp .LBL27_3\n.LBL27_3:\n gte r1 r4 r3\n cjmp r1 .LBL27_4\n mov r0 0\n jmp .LBL27_3\n.LBL27_4:\n add r9 r9 -14\n ret\nfield_memcmp_uge:\n.LBL28_0:\n add r9 r9 26\n mstore [r9,-2] r9\n mstore [r9,-8] r1\n mov r1 r2\n mstore [r9,-15] r1\n mov r1 r3\n mstore [r9,-10] r1\n mov r1 0\n mstore [r9,-7] r1\n jmp .LBL28_1\n.LBL28_1:\n mload r1 [r9,-7]\n mstore [r9,-14] r1\n mload r1 [r9,-10]\n mload r2 [r9,-14]\n gte r1 r1 r2\n mload r2 [r9,-10]\n mload r3 [r9,-14]\n neq r2 r3 r2\n and r1 r1 r2\n cjmp r1 .LBL28_2\n mov r0 1\n jmp .LBL28_4\n.LBL28_2:\n mload r1 [r9,-8]\n mload r2 [r9,-14]\n mload r1 [r1,r2]\n mload r2 [r9,-14]\n mload r3 [r9,-15]\n mload r2 [r3,r2]\n mstore [r9,-9] r2\n mload r3 [r9,-17]\n mload r2 [r9,-13]\n call split_field\n mload r3 [r9,-16]\n mload r2 [r9,-12]\n mload r1 [r9,-9]\n call split_field\n mload r1 [r9,-6]\n mload r2 [r9,-4]\n mload r3 [r9,-5]\n mload r4 [r9,-3]\n mload r5 [r9,-14]\n add r5 r5 1\n mstore [r9,-11] r5\n mload r5 [r9,-11]\n mstore [r9,-7] r5\n gte r1 r1 r2\n cjmp r1 .LBL28_3\n mov r0 0\n jmp .LBL28_4\n.LBL28_3:\n gte r1 r3 r4\n cjmp r1 .LBL28_1\n mov r0 0\n jmp .LBL28_4\n.LBL28_4:\n add r9 r9 -26\n ret\nfield_memcmp_ule:\n.LBL29_0:\n add r9 r9 14\n mstore [r9,-2] r9\n mov r6 0\n mstore [r9,-7] r6\n jmp .LBL29_1\n.LBL29_1:\n mload r6 [r9,-7]\n mstore [r9,-11] r6\n mload r6 [r9,-11]\n gte r6 r3 r6\n mload r7 [r9,-11]\n neq r3 r7 r3\n and r6 r6 r3\n cjmp r6 .LBL29_2\n mov r0 1\n jmp .LBL29_4\n.LBL29_2:\n mload r3 [r9,-11]\n mload r1 [r1,r3]\n mload r3 [r9,-11]\n mload r2 [r2,r3]\n mstore [r9,-8] r2\n mov r3 r4\n mov r2 r5\n call split_field\n mload r3 [r9,-12]\n mload r2 [r9,-10]\n mload r1 [r9,-8]\n call split_field\n mload r1 [r9,-6]\n mload r2 [r9,-4]\n mload r3 [r9,-5]\n mload r4 [r9,-3]\n mload r5 [r9,-11]\n add r5 r5 1\n mstore [r9,-9] r5\n mload r5 [r9,-9]\n mstore [r9,-7] r5\n gte r1 r2 r1\n cjmp r1 .LBL29_3\n mov r0 0\n jmp .LBL29_4\n.LBL29_3:\n gte r1 r4 r3\n cjmp r1 .LBL29_3\n mov r0 0\n jmp .LBL29_4\n.LBL29_4:\n add r9 r9 -14\n ret\nfield_memcmp_ult:\n.LBL30_0:\n add r9 r9 14\n mstore [r9,-2] r9\n mov r6 0\n mstore [r9,-7] r6\n jmp .LBL30_1\n.LBL30_1:\n mload r6 [r9,-7]\n mstore [r9,-11] r6\n mload r6 [r9,-11]\n gte r6 r3 r6\n mload r7 [r9,-11]\n neq r3 r7 r3\n and r6 r6 r3\n cjmp r6 .LBL30_2\n mov r0 1\n jmp .LBL30_4\n.LBL30_2:\n mload r3 [r9,-11]\n mload r1 [r1,r3]\n mload r3 [r9,-11]\n mload r2 [r2,r3]\n mstore [r9,-8] r2\n mov r3 r4\n mov r2 r5\n call split_field\n mload r3 [r9,-12]\n mload r2 [r9,-10]\n mload r1 [r9,-8]\n call split_field\n mload r1 [r9,-6]\n mload r2 [r9,-4]\n mload r3 [r9,-5]\n mload r4 [r9,-3]\n mload r5 [r9,-11]\n add r5 r5 1\n mstore [r9,-9] r5\n mload r5 [r9,-9]\n mstore [r9,-7] r5\n gte r1 r1 r2\n cjmp r1 .LBL30_4\n mov r0 0\n jmp .LBL30_3\n.LBL30_3:\n gte r1 r3 r4\n cjmp r1 .LBL30_4\n mov r0 0\n jmp .LBL30_3\n.LBL30_4:\n add r9 r9 -14\n ret\nu32_div_mod:\n.LBL31_0:\n add r9 r9 5\n mstore [r9,-3] r1\n mov r1 r2\n mstore [r9,-4] r1\n mload r1 [r9,-4]\n mov r2 r1\n mload r1 [r9,-3]\n.PROPHET31_0:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n mstore [r9,-5] r1\n mload r1 [r9,-5]\n range r1\n mload r1 [r9,-5]\n add r5 r1 1\n not r7 r5\n add r7 r7 1\n mload r1 [r9,-4]\n add r6 r1 r7\n range r6\n mload r1 [r9,-4]\n mov r2 r1\n mload r1 [r9,-3]\n.PROPHET31_1:\n mov r0 psp\n mload r0 [r0]\n mov r1 r0\n range r3\n mload r2 [r9,-4]\n mul r2 r1 r2\n mstore [r9,-1] r2\n mload r2 [r9,-1]\n mload r5 [r9,-5]\n add r2 r2 r5\n mstore [r9,-2] r2\n mload r2 [r9,-2]\n mload r5 [r9,-3]\n eq r2 r2 r5\n assert r2\n mstore [r3] r1\n mload r1 [r9,-5]\n mstore [r4] r1\n add r9 r9 -5\n ret\nu32_power:\n.LBL32_0:\n mov r0 1\n mov r3 0\n jmp .LBL32_1\n.LBL32_1:\n add r5 r3 1\n mul r4 r0 r1\n gte r3 r2 r5\n cjmp r3 .LBL32_1\n mov r0 r4\n mov r3 r5\n jmp .LBL32_2\n.LBL32_2:\n range r0\n ret\nhash_compare:\n.LBL33_0:\n add r9 r9 9\n mstore [r9,-2] r9\n mov r1 10\n call vector_new\n mov r5 r0\n mstore [r9,-6] r5\n mload r5 [r9,-6]\n add r5 r5 1\n mov r6 104\n mstore [r5] r6\n mov r6 101\n mstore [r5,+1] r6\n mov r6 108\n mstore [r5,+2] r6\n mov r6 108\n mstore [r5,+3] r6\n mov r6 111\n mstore [r5,+4] r6\n mov r6 119\n mstore [r5,+5] r6\n mov r6 111\n mstore [r5,+6] r6\n mov r6 114\n mstore [r5,+7] r6\n mov r6 108\n mstore [r5,+8] r6\n mov r6 100\n mstore [r5,+9] r6\n mload r5 [r9,-6]\n mload r5 [r5]\n mstore [r9,-7] r5\n mov r1 4\n call heap_malloc\n mov r5 r0\n mload r6 [r9,-6]\n add r6 r6 1\n mload r7 [r9,-7]\n poseidon r5 r6 r7\n mstore [r9,-5] r5\n mload r5 [r9,-6]\n mload r5 [r5]\n mstore [r9,-9] r5\n mov r1 4\n call heap_malloc\n mov r5 r0\n mload r6 [r9,-6]\n add r6 r6 1\n mload r7 [r9,-9]\n poseidon r5 r6 r7\n mstore [r9,-4] r5\n mov r1 4\n call heap_malloc\n mov r5 r0\n mov r6 1006966343754\n mstore [r5] r6\n mov r6 107395124437206779\n mstore [r5,+1] r6\n mov r6 10878087049651741602\n mstore [r5,+2] r6\n mov r6 1885151562297713155\n mstore [r5,+3] r6\n mstore [r9,-3] r5\n mload r1 [r9,-5]\n mload r2 [r9,-3]\n mov r3 4\n call field_memcmp_ugt\n mov r5 r0\n assert r5\n add r9 r9 -9\n ret\nfunction_dispatch:\n.LBL34_0:\n add r9 r9 2\n mstore [r9,-2] r9\n mov r2 r3\n eq r8 r1 2051797338\n cjmp r8 .LBL34_2\n jmp .LBL34_1\n.LBL34_1:\n ret\n.LBL34_2:\n call hash_compare\n mov r1 1\n call heap_malloc\n mov r1 r0\n mov r2 0\n mstore [r1] r2\n tstore r1 1\n add r9 r9 -2\n ret\nmain:\n.LBL35_0:\n add r9 r9 8\n mstore [r9,-2] r9\n mov r1 13\n call heap_malloc\n mov r5 r0\n mov r6 1\n tload r5 r6 13\n mload r5 [r5]\n mstore [r9,-4] r5\n mov r1 14\n call heap_malloc\n mov r5 r0\n mov r6 1\n tload r5 r6 14\n mload r5 [r5]\n mstore [r9,-6] r5\n mload r5 [r9,-6]\n add r5 r5 14\n mstore [r9,-3] r5\n mload r1 [r9,-3]\n call heap_malloc\n mov r3 r0\n mov r5 1\n mload r6 [r9,-3]\n tload r3 r5 r6\n mload r2 [r9,-6]\n mload r1 [r9,-4]\n call function_dispatch\n add r9 r9 -8\n end\n", + "prophets": [ + { + "label": ".PROPHET19_0", + "code": "%{\n function split_hi(felt in) -> felt {\n return in / 4294967296;\n }\n entry() {\n cid.out = split_hi(cid.in);\n }\n%}", + "inputs": [ + { + "name": "cid.in", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.out", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET19_1", + "code": "%{\n function split_lo(felt in) -> felt {\n return in % 4294967296;\n }\n entry() {\n cid.out = split_lo(cid.in);\n }\n%}", + "inputs": [ + { + "name": "cid.in", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.out", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET31_0", + "code": "%{\n function mod(felt x, felt y) -> felt {\n return x % y;\n }\n entry() {\n cid.r = mod(cid.x, cid.y);\n }\n%}", + "inputs": [ + { + "name": "cid.x", + "length": 1, + "is_ref": false, + "is_input_output": false + }, + { + "name": "cid.y", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.r", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + }, + { + "label": ".PROPHET31_1", + "code": "%{\n function div(felt x, felt y) -> felt {\n return x / y;\n }\n entry() {\n cid.q = div(cid.x, cid.y);\n }\n%}", + "inputs": [ + { + "name": "cid.x", + "length": 1, + "is_ref": false, + "is_input_output": false + }, + { + "name": "cid.y", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ], + "outputs": [ + { + "name": "cid.q", + "length": 1, + "is_ref": false, + "is_input_output": false + } + ] + } + ] +} diff --git a/core/src/program/binary_program.rs b/core/src/program/binary_program.rs index 0f4e0ff7..b81156ae 100644 --- a/core/src/program/binary_program.rs +++ b/core/src/program/binary_program.rs @@ -339,7 +339,11 @@ impl BinaryInstruction { ) } - OlaOpcode::MOV | OlaOpcode::NOT | OlaOpcode::MLOAD | OlaOpcode::TSTORE => { + OlaOpcode::MOV + | OlaOpcode::NOT + | OlaOpcode::MLOAD + | OlaOpcode::TSTORE + | OlaOpcode::SIGCHECK => { format!( "{} {} {}", self.opcode.token(), diff --git a/core/src/program/instruction.rs b/core/src/program/instruction.rs index 0d2ca9cb..d1cb2fcb 100644 --- a/core/src/program/instruction.rs +++ b/core/src/program/instruction.rs @@ -53,6 +53,7 @@ pub enum Opcode { TLOAD = 9, TSTORE = 8, SCCALL = 7, + SIGCHECK = 6, } impl fmt::Display for Opcode { @@ -83,6 +84,7 @@ impl fmt::Display for Opcode { Opcode::TLOAD => write!(f, "tload"), Opcode::TSTORE => write!(f, "tstore"), Opcode::SCCALL => write!(f, "sccall"), + Opcode::SIGCHECK => write!(f, "sigcheck"), } } } diff --git a/core/src/state/state_storage.rs b/core/src/state/state_storage.rs index 42201050..1c5af0fd 100644 --- a/core/src/state/state_storage.rs +++ b/core/src/state/state_storage.rs @@ -132,9 +132,7 @@ impl StateStorage { } pub fn get_contract_map(&self, contract_addr: &TreeValue) -> Result, StateError> { - let cf = self - .db - .cf_sequencer_handle(SequencerColumnFamily::State); + let cf = self.db.cf_sequencer_handle(SequencerColumnFamily::State); let addr_key = get_prog_hash_cf_key_from_contract_addr(contract_addr); let res = self.db.get_cf(cf, addr_key); diff --git a/core/src/storage/db.rs b/core/src/storage/db.rs index 10ce9db3..efe22b61 100644 --- a/core/src/storage/db.rs +++ b/core/src/storage/db.rs @@ -24,7 +24,6 @@ pub struct RocksDB { #[derive(Debug)] pub enum Database { MerkleTree, - StateKeeper, Sequencer, } @@ -126,12 +125,6 @@ impl RocksDB { }); DB::open_cf_descriptors(&options, path, cfs).expect("failed to init rocksdb") } - Database::StateKeeper => { - let cfs = StateKeeperColumnFamily::all().iter().map(|cf| { - ColumnFamilyDescriptor::new(cf.to_string(), Self::rocksdb_options(tune_options)) - }); - DB::open_cf_descriptors(&options, path, cfs).expect("failed to init rocksdb") - } Database::Sequencer => { let cfs = SequencerColumnFamily::all().iter().map(|cf| { ColumnFamilyDescriptor::new(cf.to_string(), Self::rocksdb_options(tune_options)) diff --git a/core/src/vm/error.rs b/core/src/vm/error.rs index 816beb57..427aa781 100644 --- a/core/src/vm/error.rs +++ b/core/src/vm/error.rs @@ -28,4 +28,13 @@ pub enum ProcessorError { #[error("Tload flag is invalid: {0}")] TloadFlagInvalid(u64), + + #[error("Pubkey is invalid: {0}")] + PubKeyInvalid(String), + + #[error("Signature is invalid: {0}")] + SignatureInvalid(String), + + #[error("Message is invalid: {0}")] + MessageInvalid(String), } diff --git a/core/src/vm/opcodes.rs b/core/src/vm/opcodes.rs index bcd20a4e..4c73eb6e 100644 --- a/core/src/vm/opcodes.rs +++ b/core/src/vm/opcodes.rs @@ -30,6 +30,7 @@ pub enum OlaOpcode { TLOAD, TSTORE, SCCALL, + SIGCHECK, } impl Display for OlaOpcode { @@ -68,6 +69,7 @@ impl OlaOpcode { OlaOpcode::TLOAD => "tload".to_string(), OlaOpcode::TSTORE => "tstore".to_string(), OlaOpcode::SCCALL => "sccall".to_string(), + OlaOpcode::SIGCHECK => "sigcheck".to_string(), } } @@ -98,6 +100,7 @@ impl OlaOpcode { OlaOpcode::TLOAD => 9, OlaOpcode::TSTORE => 8, OlaOpcode::SCCALL => 7, + OlaOpcode::SIGCHECK => 6, } } diff --git a/executor/Cargo.toml b/executor/Cargo.toml index 6c2025c8..80caf5ea 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -26,5 +26,7 @@ rand = "0.8" bincode = "1" byteorder = "1.3" tokio = { version = "1", features = ["full"] } +secp256k1 = { version = "0.28.1", default-features = false, features = ["hashes-std", "std", "recovery"] } +num = "0.4.1" [dev-dependencies] diff --git a/executor/src/decode.rs b/executor/src/decode.rs index 66a1a8ce..4b31e155 100644 --- a/executor/src/decode.rs +++ b/executor/src/decode.rs @@ -90,7 +90,7 @@ pub fn decode_raw_instruction( instruction += ®2_name; } } - Opcode::MOV | Opcode::NOT => { + Opcode::MOV | Opcode::NOT | Opcode::SIGCHECK => { instruction += &op_code.to_string(); instruction += " "; let reg0_name = format!("r{}", reg0); diff --git a/executor/src/ecdsa.rs b/executor/src/ecdsa.rs new file mode 100644 index 00000000..5f34e659 --- /dev/null +++ b/executor/src/ecdsa.rs @@ -0,0 +1,38 @@ +use core::types::merkle_tree::{tree_key_to_u8_arr, u8_arr_to_tree_key}; +use core::types::merkle_tree::{TreeKey, TreeValue}; +use core::vm::error::ProcessorError; +use num::{BigUint, Num}; +use secp256k1::{ecdsa, Message, PublicKey, Secp256k1}; +pub fn ecdsa_verify( + x: TreeValue, + y: TreeValue, + r: TreeValue, + s: TreeValue, + msg: TreeValue, +) -> Result { + let secp = Secp256k1::new(); + + let x_arr = tree_key_to_u8_arr(&x); + let y_arr = tree_key_to_u8_arr(&y); + + let mut pub_key_bytes = [0u8; 65]; + pub_key_bytes[0] = 4; + pub_key_bytes[1..33].copy_from_slice(&x_arr); + pub_key_bytes[33..].copy_from_slice(&y_arr); + let pubkey = PublicKey::from_slice(&pub_key_bytes) + .map_err(|e| ProcessorError::PubKeyInvalid(e.to_string()))?; + + let mut signature_bytes = [0u8; 64]; + let r_arr = tree_key_to_u8_arr(&r); + let s_arr = tree_key_to_u8_arr(&s); + + signature_bytes[..32].copy_from_slice(&r_arr); + signature_bytes[32..].copy_from_slice(&s_arr); + let sig = ecdsa::Signature::from_compact(&signature_bytes) + .map_err(|e| ProcessorError::SignatureInvalid(e.to_string()))?; + + let msg_arr = tree_key_to_u8_arr(&msg); + let message = + Message::from_slice(&msg_arr).map_err(|e| ProcessorError::MessageInvalid(e.to_string()))?; + Ok(secp.verify_ecdsa(&message, &sig, &pubkey).is_ok()) +} diff --git a/executor/src/lib.rs b/executor/src/lib.rs index 9d4aad4a..e60635ed 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -39,6 +39,7 @@ use plonky2::field::types::{Field, PrimeField64}; use regex::Regex; use std::collections::{BTreeMap, HashMap}; +use crate::ecdsa::ecdsa_verify; use crate::load_tx::{init_ctx_addr_info, load_ctx_addr_info}; use crate::tape::TapeTree; use crate::trace::{gen_memory_table, gen_tape_table}; @@ -51,6 +52,7 @@ use std::time::Instant; mod decode; +mod ecdsa; pub mod load_tx; pub mod storage; mod tape; @@ -80,7 +82,7 @@ macro_rules! memory_zone_detect { #[macro_export] macro_rules! memory_op { - ($v: expr, $mem_addr: tt, $read_addr: expr, $opcode: expr) => { + ($v: expr, $mem_addr: expr, $read_addr: expr, $opcode: expr) => { let is_rw; let region_prophet; let region_heap; @@ -1513,7 +1515,7 @@ impl Process { fn execute_inst_tload( &mut self, - program: &mut Program, + _program: &mut Program, aux_steps: &mut Vec, ops: &[&str], step: u64, @@ -1791,6 +1793,103 @@ impl Process { } } + fn execute_inst_sigcheck( + &mut self, + program: &mut Program, + aux_steps: &mut Vec, + ops: &[&str], + step: u64, + ctx_regs_status: &Address, + registers_status: &[GoldilocksField; REGISTER_NUM], + ctx_code_regs_status: &Address, + ) -> Result<(), ProcessorError> { + let dst_index = self.get_reg_index(ops[1]); + let op1_value = self.get_index_value(ops[2]); + + self.register_selector.op1 = op1_value.0; + if let ImmediateOrRegName::RegName(op1_index) = op1_value.1 { + self.register_selector.op1_reg_sel[op1_index] = GoldilocksField::from_canonical_u64(1); + } + + self.register_selector.dst_reg_sel[dst_index] = GoldilocksField::from_canonical_u64(1); + + let msg_mem_addr = self.register_selector.op1.to_canonical_u64(); + let mut msg = [GoldilocksField::ZERO; 4]; + for i in 0..4 { + let mut data = GoldilocksField::ZERO; + memory_op!(self, msg_mem_addr + i, data, Opcode::MSTORE); + memory_op!(self, msg_mem_addr + i, data, Opcode::SIGCHECK); + msg[i as usize] = data; + } + + let pk_x_addr = msg_mem_addr + 4; + let mut pk_x = [GoldilocksField::ZERO; 4]; + for i in 0..4 { + let mut data = GoldilocksField::ZERO; + memory_op!(self, pk_x_addr + i, data, Opcode::MSTORE); + memory_op!(self, pk_x_addr + i, data, Opcode::SIGCHECK); + pk_x[i as usize] = data; + } + + let pk_y_addr = pk_x_addr + 4; + let mut pk_y = [GoldilocksField::ZERO; 4]; + for i in 0..4 { + let mut data = GoldilocksField::ZERO; + memory_op!(self, pk_y_addr + i, data, Opcode::MSTORE); + memory_op!(self, pk_y_addr + i, data, Opcode::SIGCHECK); + pk_y[i as usize] = data; + } + + let sig_r_addr = pk_y_addr + 4; + let mut sig_r = [GoldilocksField::ZERO; 4]; + for i in 0..4 { + let mut data = GoldilocksField::ZERO; + memory_op!(self, sig_r_addr + i, data, Opcode::MSTORE); + memory_op!(self, sig_r_addr + i, data, Opcode::SIGCHECK); + sig_r[i as usize] = data; + } + + let sig_s_addr = sig_r_addr + 4; + let mut sig_s = [GoldilocksField::ZERO; 4]; + for i in 0..4 { + let mut data = GoldilocksField::ZERO; + memory_op!(self, sig_s_addr + i, data, Opcode::MSTORE); + memory_op!(self, sig_s_addr + i, data, Opcode::SIGCHECK); + sig_s[i as usize] = data; + } + self.registers[dst_index] = + GoldilocksField::from_canonical_u8(ecdsa_verify(pk_x, pk_y, sig_r, sig_s, msg)? as u8); + + if program.pre_exe_flag { + let ext_cnt = GoldilocksField::ONE; + let filter_tape_looking = GoldilocksField::ZERO; + let mut register_selector_regs: RegisterSelector = Default::default(); + register_selector_regs.op0_reg_sel[0..TREE_VALUE_LEN].clone_from_slice(&sig_r); + register_selector_regs.op0_reg_sel[TREE_VALUE_LEN..TREE_VALUE_LEN * 2] + .clone_from_slice(&sig_s); + register_selector_regs.op1_reg_sel[0..TREE_VALUE_LEN].clone_from_slice(&msg); + register_selector_regs.op1_reg_sel[TREE_VALUE_LEN..TREE_VALUE_LEN * 2] + .clone_from_slice(&pk_x); + register_selector_regs.dst_reg_sel[0..TREE_VALUE_LEN].clone_from_slice(&pk_y); + let ctx_regs_status = ctx_regs_status.clone(); + let ctx_code_regs_status = ctx_code_regs_status.clone(); + let registers_status = registers_status.clone(); + aux_insert!( + self, + aux_steps, + ctx_regs_status, + ctx_code_regs_status, + registers_status, + register_selector_regs, + ext_cnt, + filter_tape_looking + ); + self.register_selector.dst = self.registers[dst_index]; + } + self.pc += step; + Ok(()) + } + pub fn execute( &mut self, program: &mut Program, @@ -1963,6 +2062,15 @@ impl Process { &ctx_code_regs_status, ) } + "sigcheck" => self.execute_inst_sigcheck( + program, + &mut aux_steps, + &ops, + step, + &ctx_regs_status, + ®isters_status, + &ctx_code_regs_status, + )?, _ => panic!("not match opcode:{}", opcode), } diff --git a/executor/src/tests.rs b/executor/src/tests.rs index f57e36ad..0a820242 100644 --- a/executor/src/tests.rs +++ b/executor/src/tests.rs @@ -15,6 +15,7 @@ use core::types::merkle_tree::tree_key_default; use core::types::merkle_tree::{decode_addr, encode_addr}; use core::vm::transaction::init_tx_context_mock; use log::{debug, LevelFilter}; +use num::{BigInt, BigUint, Num}; use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::types::Field; use std::collections::HashMap; @@ -436,6 +437,38 @@ fn global_test() { ); } +#[test] +fn hash_test() { + let call_data = [0, 2051797338]; + + let calldata = call_data + .iter() + .map(|e| GoldilocksField::from_canonical_u64(*e)) + .collect(); + executor_run_test_program( + "../assembler/test_data/bin/hash.json", + "hash_trace.txt", + false, + Some(calldata), + ); +} + +#[test] +fn ecdsa_test() { + let call_data = [0, 370402988]; + + let calldata = call_data + .iter() + .map(|e| GoldilocksField::from_canonical_u64(*e)) + .collect(); + executor_run_test_program( + "../assembler/test_data/bin/ecdsa.json", + "ecdsa_trace.txt", + false, + Some(calldata), + ); +} + #[test] fn gen_storage_table_test() { let mut program: Program = Program::default(); diff --git a/interpreter/src/lexer/mod.rs b/interpreter/src/lexer/mod.rs index f223f057..b786a6bc 100644 --- a/interpreter/src/lexer/mod.rs +++ b/interpreter/src/lexer/mod.rs @@ -78,6 +78,7 @@ impl Lexer { let mut result = String::new(); while self.current_char != None && self.current_char.unwrap().is_alphanumeric() || self.current_char.unwrap() == '.' + || self.current_char.unwrap() == '_' { result.push(self.current_char.unwrap()); self.advance(); diff --git a/zk-vm/Cargo.toml b/zk-vm/Cargo.toml index f2b8feaf..2f1fcf23 100644 --- a/zk-vm/Cargo.toml +++ b/zk-vm/Cargo.toml @@ -6,14 +6,15 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -ola-core = { package = "core", path = "../core", version = "0.1.0"} +ola-core = { package = "core", path = "../core", version = "0.1.0" } executor = { package = "executor", path = "../executor", version = "0.1.0", default-features = false } serde_json = "1" -serde = {version = "1" } -serde_derive = {version = "1"} +serde = { version = "1" } +serde_derive = { version = "1" } env_logger = "0.6" log = "0.4" thiserror = "1.0" -tokio = { version = "1", features = ["full","test-util"] } +tokio = { version = "1", features = ["full", "test-util"] } tempfile = "3" -rand = "0.8.5" \ No newline at end of file +rand = "0.8.5" +bincode = "1.3.3" diff --git a/zk-vm/src/lib.rs b/zk-vm/src/lib.rs index b8a85262..f8b80c12 100644 --- a/zk-vm/src/lib.rs +++ b/zk-vm/src/lib.rs @@ -159,8 +159,12 @@ impl OlaVM { if get_code { let contract = self.get_program(&code_hash)?; - let bin_program: BinaryProgram = - serde_json::from_str(std::str::from_utf8(&contract.to_vec()).unwrap()).unwrap(); + let bin_program: BinaryProgram = match bincode::deserialize(&contract) { + Ok(data) => data, + Err(e) => { + return Err(StateError::GetProgramError(format!("{:?}", e))); + } + }; let instructions = bin_program.bytecode.split("\n"); let code: Vec<_> = instructions