-
Notifications
You must be signed in to change notification settings - Fork 263
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
692 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Computes the keccak hash. | ||
# This function is unsafe (not sound): there is no validity enforcement that the result is indeed | ||
# keccak, but an honest prover will compute the keccak. | ||
# Args: | ||
# data - an array of words representing the input data. Each word in the array is 16 bytes of the | ||
# input data, except the last word, which may be less. | ||
# length - the number of bytes in the input. | ||
func unsafe_keccak(data : felt*, length : felt) -> (low, high): | ||
alloc_locals | ||
local low | ||
local high | ||
%{ | ||
from eth_hash.auto import keccak | ||
data, length = ids.data, ids.length | ||
|
||
if '__keccak_max_size' in globals(): | ||
assert length <= __keccak_max_size, \ | ||
f'unsafe_keccak() can only be used with length<={__keccak_max_size}. ' \ | ||
f'Got: length={length}.' | ||
|
||
keccak_input = bytearray() | ||
for word_i, byte_i in enumerate(range(0, length, 16)): | ||
word = memory[data + word_i] | ||
n_bytes = min(16, length - byte_i) | ||
assert 0 <= word < 2 ** (8 * n_bytes) | ||
keccak_input += word.to_bytes(n_bytes, 'big') | ||
|
||
hashed = keccak(keccak_input) | ||
ids.high = int.from_bytes(hashed[:16], 'big') | ||
ids.low = int.from_bytes(hashed[16:32], 'big') | ||
%} | ||
return (low=low, high=high) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from starkware.cairo.common.math import assert_le | ||
from starkware.cairo.common.registers import get_ap, get_fp_and_pc | ||
|
||
# Returns base ** exp, for 0 <= exp < 2**251. | ||
func pow{range_check_ptr}(base, exp) -> (res): | ||
struct LoopLocals: | ||
member bit : felt | ||
member temp0 : felt | ||
|
||
member res : felt | ||
member base : felt | ||
member exp : felt | ||
end | ||
|
||
if exp == 0: | ||
return (1) | ||
end | ||
|
||
let initial_locs : LoopLocals* = cast(fp - 2, LoopLocals*) | ||
initial_locs.res = 1; ap++ | ||
initial_locs.base = base; ap++ | ||
initial_locs.exp = exp; ap++ | ||
|
||
loop: | ||
let prev_locs : LoopLocals* = cast(ap - LoopLocals.SIZE, LoopLocals*) | ||
let locs : LoopLocals* = cast(ap, LoopLocals*) | ||
locs.base = prev_locs.base * prev_locs.base; ap++ | ||
%{ ids.locs.bit = (ids.prev_locs.exp % PRIME) & 1 %} | ||
jmp odd if locs.bit != 0; ap++ | ||
|
||
even: | ||
locs.exp = prev_locs.exp / 2; ap++ | ||
locs.res = prev_locs.res; ap++ | ||
# exp cannot be 0 here. | ||
static_assert ap + 1 == locs + LoopLocals.SIZE | ||
jmp loop; ap++ | ||
|
||
odd: | ||
locs.temp0 = prev_locs.exp - 1 | ||
locs.exp = locs.temp0 / 2; ap++ | ||
locs.res = prev_locs.res * prev_locs.base; ap++ | ||
static_assert ap + 1 == locs + LoopLocals.SIZE | ||
jmp loop if locs.exp != 0; ap++ | ||
|
||
# Cap the number of steps. | ||
let (__ap__) = get_ap() | ||
let (__fp__, _) = get_fp_and_pc() | ||
let n_steps = (__ap__ - cast(initial_locs, felt)) / LoopLocals.SIZE - 1 | ||
assert_le(n_steps, 251) | ||
return (res=locs.res) | ||
end |
Oops, something went wrong.