|
| 1 | +:stem: latexmath |
| 2 | +[id="cryptography"] |
| 3 | += Cryptography |
| 4 | + |
| 5 | +[id="stark-field"] |
| 6 | +== The STARK field |
| 7 | + |
| 8 | +[NOTE] |
| 9 | +==== |
| 10 | +The `felt252` type in Cairo refers to elements of the STARK field. |
| 11 | +==== |
| 12 | + |
| 13 | +The STARK field is the finite field stem:[$$\mathbb{F}_P$$], where stem:[$$P$$] is a prime number defined by: |
| 14 | + |
| 15 | +[stem] |
| 16 | +++++ |
| 17 | +P = 2^{251} + 17*2^{192} + 1 |
| 18 | +++++ |
| 19 | + |
| 20 | +[id="stark-curve"] |
| 21 | +== The STARK curve |
| 22 | + |
| 23 | +[NOTE] |
| 24 | +==== |
| 25 | +The STARK curve is commonly used in smart contracts but not distinguished by the Starknet protocol. |
| 26 | +==== |
| 27 | + |
| 28 | +The STARK curve is an elliptic curve defined over the xref:#stark-field[STARK field] by: |
| 29 | + |
| 30 | +[stem] |
| 31 | +++++ |
| 32 | +y^2 \equiv x^3 + \alpha \cdot x + \beta \pmod{P} |
| 33 | +++++ |
| 34 | +where: |
| 35 | + |
| 36 | +* stem:[\alpha = 1] |
| 37 | +* stem:[\beta = 3141592653589793238462643383279502884197169399375105820974944592307816406665] |
| 38 | +and the generator point used in the ECDSA scheme is defined by: |
| 39 | +* stem:[G_x = 874739451078007766457464989774322083649278607533249481151382481072868806602] |
| 40 | +* stem:[G_y = 152666792071518830868575557812948353041420400780739481342941381225525861407] |
| 41 | + |
| 42 | +[id="hash_functions"] |
| 43 | +== Hash functions |
| 44 | +There are three hash functions used throughout Starknet's specifications that map inputs to elements in the xref:#stark-field[STARK field]. |
| 45 | + |
| 46 | +[id="starknet_keccak"] |
| 47 | +=== Starknet Keccak |
| 48 | +Starknet Keccak, commonly denoted by stem:[$\text{sn_keccak}$], is defined as the first 250 bits of Ethereum's link:https://github.com/ethereum/eth-hash[keccak256]. |
| 49 | + |
| 50 | +[id="pedersen_hash"] |
| 51 | +=== Pedersen hash |
| 52 | +Pedersen hash is then defined by: |
| 53 | + |
| 54 | +[stem] |
| 55 | +++++ |
| 56 | +h(a,b) = \left[\text{shift_point} + a_{low} \cdot P_0 + a_{high} \cdot P1 + b_{low} \cdot P2 + b_{high} \cdot P3\right]_x |
| 57 | +++++ |
| 58 | + |
| 59 | +where: |
| 60 | + |
| 61 | +* stem:[a_{low}] and stem:[b_{low}] are the 248 low of stem:[a] and stem:[b], respectively |
| 62 | +* stem:[a_{high}] and stem:[b_{high}] are the 4 high bits of stem:[a] and stem:[b], respectively |
| 63 | +* The values of the constants stem:[\text{shift_point}, P_0, P_1, P_2, P_3] can be found in link:https://github.com/starkware-libs/cairo-lang/blob/master/src/starkware/crypto/signature/fast_pedersen_hash.py[fast_pedersen_hash.py^] |
| 64 | +* stem:[[P\]_x] denotes the stem:[x] coordinate of point stem:[$P$] |
| 65 | + |
| 66 | +[id="pedersen_array_hash"] |
| 67 | +==== Array hashing |
| 68 | +Let stem:[$h$] denote the pedersen hash function, then given an array stem:[$a_1,...,a_n$] of stem:[$n$] field elements |
| 69 | +we define stem:[$h(a_1,...,a_n)$] to be: |
| 70 | +[stem] |
| 71 | +++++ |
| 72 | +h(...h(h(0, a_1),a_2),...,a_n),n) |
| 73 | +++++ |
| 74 | + |
| 75 | +[id="poseidon_hash"] |
| 76 | +=== Poseidon hash |
| 77 | + |
| 78 | +[TIP] |
| 79 | +==== |
| 80 | +Poseidon is a family of hash functions designed to be very efficient as algebraic circuits. As such, they can be very useful in ZK-proving systems such as STARKs. |
| 81 | +==== |
| 82 | + |
| 83 | +Starknet's version of Poseidon is based on a three-element state Hades permutation and defined of up to 2 elements by: |
| 84 | + |
| 85 | +[stem] |
| 86 | +++++ |
| 87 | +\text{poseidon}(x) := \left[\text{hades_permutation}(x,0,1)\right]_0 |
| 88 | +++++ |
| 89 | + |
| 90 | +[stem] |
| 91 | +++++ |
| 92 | +\text{poseidon}(x,y) := \left[\text{hades_permutation}(x,y,2)\right]_0 |
| 93 | +++++ |
| 94 | + |
| 95 | +Where latexmath:[[\cdot\]_j] denotes taking the stem:[j]'th coordinate of a tuple. |
| 96 | + |
| 97 | +[id="poseidon_array_hash"] |
| 98 | +==== Array hashing |
| 99 | +Let stem:[$\text{hades}:\mathbb{F}_P^3\rightarrow\mathbb{F}_P^3$] denote the Hades permutation with Starknet's parameters, then given an array stem:[$a_1,...,a_n$] of stem:[$n$] field elements |
| 100 | +we define stem:[$\text{poseidon}(a_1,...,a_n)$] to be the first coordinate of stem:[$H(a_1,...,a_n;0,0,0)$], where: |
| 101 | + |
| 102 | +[stem] |
| 103 | +++++ |
| 104 | +H(a_1,...,a_n;s_1,s_2,s_3)=\begin{cases} |
| 105 | +H\big(a_3,...,a_n;\text{hades}(s_1+a_1, s_2+a_2, s_3)\big), & \text{if } n\ge 2 \\ |
| 106 | +\text{hades}(s_1+a_1,s_2+1,s_3), & \text{if } n=1 \\ |
| 107 | +\text{hades}(s_1+1,s_2,s_3), & \text{if } n=0 \\ |
| 108 | +\end{cases} |
| 109 | +++++ |
| 110 | + |
| 111 | +[TIP] |
| 112 | +==== |
| 113 | +For reference implementations of the above see link:https://github.com/starkware-libs/cairo-lang/blob/12ca9e91bbdc8a423c63280949c7e34382792067/src/starkware/cairo/common/poseidon_hash.py#L46[poseidon_hash.py] and link:https://github.com/starkware-libs/cairo-lang/blob/12ca9e91bbdc8a423c63280949c7e34382792067/src/starkware/cairo/common/builtin_poseidon/poseidon.cairo#L28[poseidon.cairo] in the cairo-lang GitHub repository. |
| 114 | +==== |
| 115 | + |
| 116 | +==== Additional resources |
| 117 | + |
| 118 | +* link:https://github.com/starkware-industries/poseidon/blob/main/poseidon3.txt[Parameters for defining the Poseidon permutation used in Starknet] |
| 119 | +* link:https://github.com/CryptoExperts/poseidon[Implementation in C and assembly by CryptoExperts] |
0 commit comments