This commit is contained in:
lz_db
2025-11-16 12:31:03 +08:00
commit 0fab423a18
1451 changed files with 743213 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
from ...ecdsa.curves import Curve
from ...ecdsa.ellipticcurve import CurveFp, Point
from .signature import (
ALPHA,
BETA,
CONSTANT_POINTS,
EC_ORDER,
FIELD_PRIME,
N_ELEMENT_BITS_HASH,
SHIFT_POINT,
)
from .utils import from_bytes, to_bytes
curve_stark = CurveFp(FIELD_PRIME, ALPHA, BETA)
LOW_PART_BITS = 248
LOW_PART_MASK = 2**248 - 1
HASH_SHIFT_POINT = Point(curve_stark, SHIFT_POINT[0], SHIFT_POINT[1], EC_ORDER)
P_0 = Point(curve_stark, CONSTANT_POINTS[2][0], CONSTANT_POINTS[2][1], EC_ORDER)
P_1 = Point(curve_stark, CONSTANT_POINTS[2 + LOW_PART_BITS][0], CONSTANT_POINTS[2 + LOW_PART_BITS][1], EC_ORDER)
P_2 = Point(curve_stark, CONSTANT_POINTS[2 + N_ELEMENT_BITS_HASH][0], CONSTANT_POINTS[2 + N_ELEMENT_BITS_HASH][1], EC_ORDER)
P_3 = Point(curve_stark, CONSTANT_POINTS[2 + N_ELEMENT_BITS_HASH + LOW_PART_BITS][0], CONSTANT_POINTS[2 + N_ELEMENT_BITS_HASH + LOW_PART_BITS][1], EC_ORDER)
def process_single_element(element: int, p1, p2) -> Point:
assert 0 <= element < FIELD_PRIME, "Element integer value is out of range"
high_nibble = element >> LOW_PART_BITS
low_part = element & LOW_PART_MASK
return low_part * p1 + high_nibble * p2
def pedersen_hash(x: int, y: int) -> int:
"""
Computes the Starkware version of the Pedersen hash of x and y.
The hash is defined by:
shift_point + x_low * P_0 + x_high * P1 + y_low * P2 + y_high * P3
where x_low is the 248 low bits of x, x_high is the 4 high bits of x and similarly for y.
shift_point, P_0, P_1, P_2, P_3 are constant points generated from the digits of pi.
"""
return (
HASH_SHIFT_POINT + process_single_element(x, P_0, P_1) + process_single_element(y, P_2, P_3)
).x()
def pedersen_hash_func(x: bytes, y: bytes) -> bytes:
"""
A variant of 'pedersen_hash', where the elements and their resulting hash are in bytes.
"""
assert len(x) == len(y) == 32, "Unexpected element length."
return to_bytes(pedersen_hash(*(from_bytes(element) for element in (x, y))))

View File

@@ -0,0 +1,78 @@
###############################################################################
# Copyright 2019 StarkWare Industries Ltd. #
# #
# Licensed under the Apache License, Version 2.0 (the "License"). #
# You may not use this file except in compliance with the License. #
# You may obtain a copy of the License at #
# #
# https://www.starkware.co/open-source-license/ #
# #
# Unless required by applicable law or agreed to in writing, #
# software distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions #
# and limitations under the License. #
###############################################################################
from typing import Tuple
from ...sympy.core.intfunc import igcdex
# A type that represents a point (x,y) on an elliptic curve.
ECPoint = Tuple[int, int]
def div_mod(n: int, m: int, p: int) -> int:
"""
Finds a nonnegative integer 0 <= x < p such that (m * x) % p == n
"""
a, b, c = igcdex(m, p)
assert c == 1
return (n * a) % p
def div_ceil(x, y):
assert isinstance(x, int) and isinstance(y, int)
return -((-x) // y)
def ec_add(point1: ECPoint, point2: ECPoint, p: int) -> ECPoint:
"""
Gets two points on an elliptic curve mod p and returns their sum.
Assumes the points are given in affine form (x, y) and have different x coordinates.
"""
assert (point1[0] - point2[0]) % p != 0
m = div_mod(point1[1] - point2[1], point1[0] - point2[0], p)
x = (m * m - point1[0] - point2[0]) % p
y = (m * (point1[0] - x) - point1[1]) % p
return x, y
def ec_neg(point: ECPoint, p: int) -> ECPoint:
"""
Given a point (x,y) return (x, -y)
"""
x, y = point
return (x, (-y) % p)
def ec_double(point: ECPoint, alpha: int, p: int) -> ECPoint:
"""
Doubles a point on an elliptic curve with the equation y^2 = x^3 + alpha*x + beta mod p.
Assumes the point is given in affine form (x, y) and has y != 0.
"""
assert point[1] % p != 0
m = div_mod(3 * point[0] * point[0] + alpha, 2 * point[1], p)
x = (m * m - 2 * point[0]) % p
y = (m * (point[0] - x) - point[1]) % p
return x, y
def ec_mult(m: int, point: ECPoint, alpha: int, p: int) -> ECPoint:
"""
Multiplies by m a point on the elliptic curve with equation y^2 = x^3 + alpha*x + beta mod p.
Assumes the point is given in affine form (x, y) and that 0 < m < order(point).
"""
if m == 1:
return point
if m % 2 == 0:
return ec_mult(m // 2, ec_double(point, alpha, p), alpha, p)
return ec_add(ec_mult(m - 1, point, alpha, p), point, p)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
from typing import (
AsyncGenerator,
Optional,
TypeVar,
)
import sys
if sys.version_info.minor >= 11:
from typing import Literal, ParamSpec
else:
from typing_extensions import Literal, ParamSpec
T = TypeVar("T")
P = ParamSpec("P")
K = TypeVar("K")
V = TypeVar("V")
TAsyncGenerator = TypeVar("TAsyncGenerator", bound=AsyncGenerator)
NumType = TypeVar("NumType", int, float)
HASH_BYTES = 32
# If more shared types start popping up here extract to types.py.
Endianness = Literal["big", "little"]
TComparable = TypeVar("TComparable", bound="Comparable")
def to_bytes(
value: int,
length: Optional[int] = None,
byte_order: Optional[Endianness] = None,
signed: Optional[bool] = None,
) -> bytes:
"""
Converts the given integer to a bytes object of given length and byte order.
The default values are 32B width (which is the hash result width) and 'big', respectively.
"""
if length is None:
length = HASH_BYTES
if byte_order is None:
byte_order = "big"
if signed is None:
signed = False
return int.to_bytes(value, length=length, byteorder=byte_order, signed=signed)
def from_bytes(
value: bytes,
byte_order: Optional[Endianness] = None,
signed: Optional[bool] = None,
) -> int:
"""
Converts the given bytes object (parsed according to the given byte order) to an integer.
Default byte order is 'big'.
"""
if byte_order is None:
byte_order = "big"
if signed is None:
signed = False
return int.from_bytes(value, byteorder=byte_order, signed=signed)