Skip to content

Commit

Permalink
chore: refactor random index generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Al-Kindi-0 committed Dec 3, 2024
1 parent d231540 commit 1ba8cf7
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 146 deletions.
136 changes: 0 additions & 136 deletions stdlib/asm/crypto/dsa/rpo_stark/random_coin.masm
Original file line number Diff line number Diff line change
Expand Up @@ -254,139 +254,3 @@ export.generate_z_zN
exec.constants::z_ptr mem_storew
dropw
end

# INDEX GENERATION
# =============================================================================================

#! Generate a list of `num_queries` number of random indices in the range
#! [0, lde_size] and store it in memory starting from `query_ptr`.
#! The list is stored as `(r, depth, y, y)` where `depth` is `log(lde_domain_size)`.
#!`depth` is needed when computing the deep queries.
#!
#! Input: [query_ptr, num_queries, ...]
#! Output: [...]
#!
#! Cycles: 282 + q * 250 + r * 29 where q = num_queries / 8 and r = num_queries % 8
#!
#! NOTE: This procedure is called first, and right after the PoW check, thus the first element
#! in the rate portion of the state is discarded.
#! NOTE: The cycle count can be estimated, using the fact that r < 8, via the more compact formula
#! 485 + 31 * num_queries
export.generate_list_indices
# push the depth
exec.constants::initial_lde_domain_log_size
# push the mask
exec.constants::initial_lde_domain_size sub.1
#=> [mask, depth, query_ptr, num_queries] where depth = log(lde_size)

# Get address holding the integers (this will later hold the FRI queries)
movup.2
#=> [query_ptr, mask, depth, num_queries]

# Load the first half of the rate portion of the state of the random coin. We discard the first
# element as it is used for PoW and use the remaining the 3.
exec.get_rate_1
exec.random_coin::generate_three_integers
#=> [R, query_ptr, mask, depth, num_queries]

# Load the second half of the rate portion of the state of the random coin.
exec.constants::r2_ptr mem_loadw
exec.random_coin::generate_four_integers
#=> [R2, query_ptr, mask, depth, num_queries, ...]

# Squeeze
exec.constants::c_ptr mem_loadw
exec.get_rate_1
exec.get_rate_2
hperm

# Save the new state
exec.constants::r2_ptr mem_storew
dropw
# => [R1, C]
exec.constants::r1_ptr mem_storew
swapw
# => [C, R1]
exec.constants::c_ptr mem_storew
dropw
#=> [R1, query_ptr, mask, depth, num_queries, ...]


# Use `num_queries` to iterate.

## Subtract the 7 elements we have already generated above.
movup.7
push.7 sub

## Divide by 8 to get the number of iterations
u32assert u32divmod.8
#=> [remainder, quotient, X, query_ptr, mask, depth, ...]


## Save remainder for later use
movdn.8
#=> [quotient, X, query_ptr, mask, depth, remainder, ...]

## Use `quotient` to iterate
dup movdn.8
#=> [quotient, X, query_ptr, mask, depth, quotient, remainder, ...]

push.0 neq
while.true
exec.random_coin::generate_four_integers
exec.constants::r2_ptr mem_loadw
exec.random_coin::generate_four_integers
#=> [R2, query_ptr, mask, depth, num_remaining_iterations, remainder, ...]

# Squeeze
exec.constants::c_ptr mem_loadw
exec.get_rate_1
exec.get_rate_2
hperm

# Save the new state
exec.constants::r2_ptr mem_storew
dropw
# => [R1, C]
exec.constants::r1_ptr mem_storew
swapw
# => [C, R1]
exec.constants::c_ptr mem_storew
dropw
#=> [R1, query_ptr, mask, depth, num_remaining_iterations, remainder, ...]

movup.7 sub.1 dup movdn.8
push.0 neq
end
#=> [R1, query_ptr, mask, depth, num_remaining_iterations, remainder, ...]

## Use remainder

### Put the remaining number of queries to generate in the appropriate stack position
movup.8 movdn.7

### Load the second half of the rate portion of the state of the random coin.
padw exec.constants::r2_ptr mem_loadw
#=> [R2, R1, query_ptr, mask, depth, num_queries, ...]

### Iterate over remainder
dup.11 sub.1 swap.12
neq.0
while.true
movup.7
u32split swap # [r0_lo, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...]
dup.10 # [mask, r0_lo, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...]
u32and # [r, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...]
dup.11 swap # [r, depth, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...]
push.0 movdn.3 # [r, depth, r0_hi, 0, R2, r3, r2, r1, ptr, mask, depth, ...]

# Store and update pointer
dup.11 add.1 swap.12 # [ptr, r, depth, r0_hi, 0, R2, r3, r2, r1, ptr + 1, mask, depth, ...]
mem_storew
drop drop drop # [x, R2, r3, r2, r1, ptr + 1, mask, depth, ...]
dup.11 sub.1 swap.12
push.0 neq
end

dropw dropw dropw drop
end
2 changes: 1 addition & 1 deletion stdlib/asm/crypto/dsa/rpo_stark/utils.masm
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ export.load_and_verify_remainder
# Drop pointers
drop drop
#=> [...]
end
end
4 changes: 3 additions & 1 deletion stdlib/asm/crypto/dsa/rpo_stark/verifier.masm
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ export.verify
#
# Cycles: 487 + 31 * num_queries
swap dup.1
exec.random_coin::generate_list_indices
exec.constants::initial_lde_domain_log_size
exec.constants::initial_lde_domain_size
exec.stark_random_coin::generate_list_indices
#=> [query_ptr, ...]

# Compute deep compostion polynomial queries
Expand Down
12 changes: 4 additions & 8 deletions stdlib/asm/crypto/stark/random_coin.masm
Original file line number Diff line number Diff line change
Expand Up @@ -626,27 +626,23 @@ end
#! The list is stored as `(r, depth, y, y)` where `depth` is `log(lde_domain_size)`.
#!`depth` is needed when computing the deep queries.
#!
#! Input: [query_ptr, num_queries, ...]
#! Input: [lde_domain_size, lde_domain_log_size, query_ptr, num_queries, ...]
#! Output: [...]
#!
#! Cycles: 267 + q * 236 + r * 29 where q = num_queries / 8 and r = num_queries % 8
#!
#! NOTE: This procedure is called first, and right after the PoW check, thus the first element
#! in the rate portion of the state is discarded.
#! NOTE: The cycles count can be estimated, using the fact that r < 8, via the more compact formula
#! 470 + 236 * (num_queries / 8)
#! 485 + 31 * num_queries
export.generate_list_indices
# Create mask
padw
exec.constants::lde_size_ptr mem_loadw
movup.2 drop
movup.2 drop
sub.1
#=> [mask, depth, query_ptr, num_queries] where depth = log(lde_size)
#=> [mask, depth, query_ptr, num_queries, ...] where depth = log(lde_size)

# Get address holding the integers (this will later hold the FRI queries)
movup.2
#=> [query_ptr, mask, depth, num_queries]
#=> [query_ptr, mask, depth, num_queries, ...]

# Load the first half of the rate portion of the state of the random coin. We discard the first
# element as it is used for PoW and use the remaining the 3.
Expand Down
5 changes: 5 additions & 0 deletions stdlib/asm/crypto/stark/verifier.masm
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ export.verify
#
# Cycles: 470 + 236 * (num_queries / 8)
swap dup.1
#=> [query_ptr, num_queries, query_ptr, ...]
padw exec.constants::lde_size_ptr mem_loadw
movup.2 drop
movup.2 drop
#=> [lde_domain_size, lde_domain_log_size, query_ptr, num_queries, query_ptr, ...]
exec.random_coin::generate_list_indices
#=> [query_ptr, ...]

Expand Down

0 comments on commit 1ba8cf7

Please sign in to comment.