Skip to content

Commit e5f160c

Browse files
authored
Merge pull request #14 from iosis-tech/bootloader
chunk_felt_array & starknet signature
2 parents c57b6f3 + 08e74b3 commit e5f160c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1274
-258
lines changed

.cargo/config.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[env]
22
RUST_LOG = "info"
33
CAIRO_PATH = "cairo"
4-
BOOTLOADER_PATH = "bootloader/recursive_with_poseidon/simple_bootloader.cairo"
4+
BOOTLOADER_PATH = "bootloader/starknet/simple_bootloader.cairo"
55
BOOTLOADER_OUT_NAME = "bootloader.json"

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ Cargo.lock
2424
Scarb.lock
2525
.snfoundry_cache/
2626

27-
stone-prover
27+
stone-prover
28+
29+
bootloader*.json

Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ license-file = "LICENSE"
2626
async-process = "2.2.0"
2727
async-stream = "0.3.5"
2828
bincode = "1.3"
29-
cairo-felt = "0.9.1"
3029
cairo-proof-parser = { git = "https://github.com/Okm165/cairo-proof-parser", rev = "97a04bbee07330311b38d6f4cecfed3acb237626" }
30+
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm.git" }
3131
futures = "0.3.30"
3232
futures-core = "0.3.30"
3333
futures-util = "0.3.30"
@@ -61,7 +61,6 @@ tokio = { version = "1.36", features = ["full"] }
6161
tokio-util = "0.7.10"
6262
tracing = "0.1.37"
6363
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
64-
zip-extensions = "0.6.2"
6564

6665
sharp-p2p-common = { path = "crates/common" }
6766
sharp-p2p-compiler = { path = "crates/compiler" }

Makefile.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ script = [
4949
"docker cp -L ${container_id}:/bin/cpu_air_verifier $HOME/.local/bin",
5050
]
5151

52-
[tasks.setup]
52+
[tasks.install]
5353
workspace = false
5454
dependencies = [
5555
"python-requirements-install",

cairo/bootloader/objects.py

+31-6
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,58 @@ def get_program(self) -> StrippedProgram:
3232
return self.cairo_pie.program
3333

3434

35+
@dataclasses.dataclass(frozen=True)
36+
class FieldElementsData:
37+
data_len: int
38+
data: List[int]
39+
40+
def deserialize(self) -> bytes:
41+
FIELD_ELEMENT_CHUNK_SIZE = 31
42+
v = []
43+
for i in range(0, len(self.data) - 1):
44+
data = self.data[i].to_bytes(FIELD_ELEMENT_CHUNK_SIZE, "big")
45+
v.extend([0] * (FIELD_ELEMENT_CHUNK_SIZE - len(data)) + list(data))
46+
47+
data = self.data[-1].to_bytes(FIELD_ELEMENT_CHUNK_SIZE, "big")
48+
data = [0] * (FIELD_ELEMENT_CHUNK_SIZE - len(data)) + list(data)
49+
v.extend(
50+
data[
51+
(
52+
FIELD_ELEMENT_CHUNK_SIZE * len(self.data) - self.data_len
53+
) : FIELD_ELEMENT_CHUNK_SIZE
54+
]
55+
)
56+
return bytes(v)
57+
58+
3559
@dataclasses.dataclass(frozen=True)
3660
class JobData(Task):
3761
reward: int
3862
num_of_steps: int
39-
cairo_pie_compressed: List[int]
40-
registry_address: str
63+
cairo_pie_compressed: FieldElementsData
64+
registry_address: int
4165

4266
def load_task(self) -> "CairoPieTask":
4367
return CairoPieTask(
44-
cairo_pie=CairoPie.deserialize(bytes(self.cairo_pie_compressed)),
68+
cairo_pie=CairoPie.deserialize(self.cairo_pie_compressed.deserialize()),
4569
use_poseidon=True,
4670
)
4771

4872

4973
@dataclasses.dataclass(frozen=True)
5074
class Job(Task):
5175
job_data: JobData
52-
public_key: List[int]
53-
signature: List[int]
76+
public_key: int
77+
signature_r: int
78+
signature_s: int
5479

5580
def load_task(self) -> "CairoPieTask":
5681
return self.job_data.load_task()
5782

5883

5984
@marshmallow_dataclass.dataclass(frozen=True)
6085
class SimpleBootloaderInput(ValidatedMarshmallowDataclass):
61-
public_key: List[int]
86+
public_key: int
6287
job: Job
6388

6489
fact_topologies_path: Optional[str]

cairo/bootloader/recursive_with_poseidon/builtins.py renamed to cairo/bootloader/starknet/builtins.py

+2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
OUTPUT_BUILTIN,
66
PEDERSEN_BUILTIN,
77
RANGE_CHECK_BUILTIN,
8+
ECDSA_BUILTIN,
89
BITWISE_BUILTIN,
10+
EC_OP_BUILTIN,
911
POSEIDON_BUILTIN,
1012
]
1113
)

cairo/bootloader/recursive_with_poseidon/execute_task.cairo renamed to cairo/bootloader/starknet/execute_task.cairo

+22-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ from builtin_selection.inner_select_builtins import inner_select_builtins
22
from builtin_selection.select_input_builtins import select_input_builtins
33
from builtin_selection.validate_builtins import validate_builtins
44
from common.builtin_poseidon.poseidon import PoseidonBuiltin, poseidon_hash_many
5-
from common.cairo_builtins import HashBuiltin
5+
from common.cairo_builtins import HashBuiltin, EcOpBuiltin
66
from common.hash_chain import hash_chain
7+
from common.bool import TRUE
78
from common.registers import get_ap, get_fp_and_pc
9+
from common.signature import check_ecdsa_signature
810

911
const BOOTLOADER_VERSION = 0;
1012

@@ -28,7 +30,9 @@ struct BuiltinData {
2830
output: felt,
2931
pedersen: felt,
3032
range_check: felt,
33+
ecdsa: felt,
3134
bitwise: felt,
35+
ec_op: felt,
3236
poseidon: felt,
3337
}
3438

@@ -109,6 +113,21 @@ func execute_task{builtin_ptrs: BuiltinData*, self_range_check_ptr}(
109113
use_poseidon=bool(ids.use_poseidon)), 'Computed hash does not match input.'
110114
%}
111115

116+
local public_key: felt;
117+
local signature_r: felt;
118+
local signature_s: felt;
119+
%{
120+
ids.public_key = simple_bootloader_input.job.public_key
121+
ids.signature_r = simple_bootloader_input.job.signature_r
122+
ids.signature_s = simple_bootloader_input.job.signature_s
123+
%}
124+
125+
let ec_op_ptr = cast(input_builtin_ptrs.ec_op, EcOpBuiltin*);
126+
with ec_op_ptr {
127+
let (res) = check_ecdsa_signature(message=hash, public_key=public_key, signature_r=signature_r, signature_s=signature_s);
128+
assert res = TRUE;
129+
}
130+
112131
// Set the program entry point, so the bootloader can later run the program.
113132
local builtin_list: felt* = &program_header.builtin_list;
114133
local n_builtins = program_header.n_builtins;
@@ -127,7 +146,9 @@ func execute_task{builtin_ptrs: BuiltinData*, self_range_check_ptr}(
127146
output=output_ptr + 2,
128147
pedersen=cast(pedersen_ptr, felt),
129148
range_check=input_builtin_ptrs.range_check,
149+
ecdsa=input_builtin_ptrs.ecdsa,
130150
bitwise=input_builtin_ptrs.bitwise,
151+
ec_op=cast(ec_op_ptr, felt),
131152
poseidon=cast(poseidon_ptr, felt),
132153
);
133154

cairo/bootloader/recursive_with_poseidon/run_simple_bootloader.cairo renamed to cairo/bootloader/starknet/run_simple_bootloader.cairo

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from bootloader.recursive_with_poseidon.execute_task import BuiltinData, execute_task
1+
from bootloader.starknet.execute_task import BuiltinData, execute_task
22
from common.cairo_builtins import HashBuiltin, PoseidonBuiltin
33
from common.registers import get_fp_and_pc
44

@@ -14,7 +14,9 @@ func run_simple_bootloader{
1414
output_ptr: felt*,
1515
pedersen_ptr: HashBuiltin*,
1616
range_check_ptr,
17+
ecdsa_ptr,
1718
bitwise_ptr,
19+
ec_op_ptr,
1820
poseidon_ptr: PoseidonBuiltin*,
1921
}() {
2022
alloc_locals;
@@ -41,7 +43,9 @@ func run_simple_bootloader{
4143
output=cast(output_ptr, felt),
4244
pedersen=cast(pedersen_ptr, felt),
4345
range_check=task_range_check_ptr,
46+
ecdsa=ecdsa_ptr,
4447
bitwise=bitwise_ptr,
48+
ec_op=ec_op_ptr,
4549
poseidon=cast(poseidon_ptr, felt),
4650
);
4751

@@ -50,15 +54,19 @@ func run_simple_bootloader{
5054
output='output',
5155
pedersen='pedersen',
5256
range_check='range_check',
57+
ecdsa='ecdsa',
5358
bitwise='bitwise',
59+
ec_op='ec_op',
5460
poseidon='poseidon',
5561
);
5662

5763
local builtin_instance_sizes: BuiltinData = BuiltinData(
5864
output=1,
5965
pedersen=3,
6066
range_check=1,
67+
ecdsa=2,
6168
bitwise=5,
69+
ec_op=7,
6270
poseidon=6,
6371
);
6472

@@ -83,7 +91,9 @@ func run_simple_bootloader{
8391
let output_ptr = cast(builtin_ptrs.output, felt*);
8492
let pedersen_ptr = cast(builtin_ptrs.pedersen, HashBuiltin*);
8593
let range_check_ptr = builtin_ptrs.range_check;
94+
let ecdsa_ptr = builtin_ptrs.ecdsa;
8695
let bitwise_ptr = builtin_ptrs.bitwise;
96+
let ec_op_ptr = builtin_ptrs.ec_op;
8797
let poseidon_ptr = cast(builtin_ptrs.poseidon, PoseidonBuiltin*);
8898

8999
// 'execute_tasks' runs untrusted code and uses the range_check builtin to verify that

cairo/bootloader/recursive_with_poseidon/simple_bootloader.cairo renamed to cairo/bootloader/starknet/simple_bootloader.cairo

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
%builtins output pedersen range_check bitwise poseidon
1+
%builtins output pedersen range_check ecdsa bitwise ec_op poseidon
22

3-
from bootloader.recursive_with_poseidon.run_simple_bootloader import (
3+
from bootloader.starknet.run_simple_bootloader import (
44
run_simple_bootloader,
55
)
66
from common.cairo_builtins import HashBuiltin, PoseidonBuiltin
@@ -10,7 +10,9 @@ func main{
1010
output_ptr: felt*,
1111
pedersen_ptr: HashBuiltin*,
1212
range_check_ptr,
13+
ecdsa_ptr,
1314
bitwise_ptr,
15+
ec_op_ptr,
1416
poseidon_ptr: PoseidonBuiltin*,
1517
}() {
1618
%{

cairo/common/bool.cairo

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Represents boolean values in Cairo.
2+
const FALSE = 0;
3+
const TRUE = 1;

cairo/common/cairo_builtins.cairo

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from starkware.cairo.common.ec_point import EcPoint
2-
from starkware.cairo.common.keccak_state import KeccakBuiltinState
3-
from starkware.cairo.common.poseidon_state import PoseidonBuiltinState
1+
from common.ec_point import EcPoint
2+
from common.keccak_state import KeccakBuiltinState
3+
from common.poseidon_state import PoseidonBuiltinState
44

55
// Specifies the hash builtin memory structure.
66
struct HashBuiltin {

0 commit comments

Comments
 (0)