Skip to content

Commit

Permalink
Modulo Builtins Setup
Browse files Browse the repository at this point in the history
  • Loading branch information
feltroidprime committed Jan 29, 2024
1 parent 23e5600 commit de57e58
Show file tree
Hide file tree
Showing 18 changed files with 3,431 additions and 5 deletions.
136 changes: 136 additions & 0 deletions tests/cairo_programs/modulo.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
%builtins range_check range_check96 add_mod mul_mod
from starkware.cairo.common.cairo_builtins import ModBuiltin

from starkware.cairo.common.cairo_builtins import PoseidonBuiltin, BitwiseBuiltin, UInt384
from starkware.cairo.common.registers import get_label_location
from starkware.cairo.common.modulo import run_mod_p_circuit
from starkware.cairo.common.memcpy import memcpy
from starkware.cairo.common.alloc import alloc

// Computes the polynomial f(x) = x^8 + 5*x^2 + 1.
func apply_poly{
range_check_ptr, range_check96_ptr: felt*, add_mod_ptr: ModBuiltin*, mul_mod_ptr: ModBuiltin*
}(x: UInt384*, p: UInt384) -> (res: UInt384*) {
// Copy inputs and constants into the values_ptr segment.
memcpy(dst=range_check96_ptr, src=x, len=UInt384.SIZE);
let (constants_ptr) = get_label_location(constants);
memcpy(dst=range_check96_ptr + UInt384.SIZE, src=constants_ptr, len=2 * UInt384.SIZE);
let values_ptr = cast(range_check96_ptr, UInt384*);
let range_check96_ptr = range_check96_ptr + 36;

let (add_mod_offsets_ptr) = get_label_location(add_offsets);
let (mul_mod_offsets_ptr) = get_label_location(mul_offsets);
run_mod_p_circuit(
p=p,
values_ptr=values_ptr,
add_mod_offsets_ptr=add_mod_offsets_ptr,
add_mod_n=2,
mul_mod_offsets_ptr=mul_mod_offsets_ptr,
mul_mod_n=4,
);

return (res=values_ptr + 32);

// values_ptr points to a segment within the range_check96_ptr segment that looks like this:
//
// offset value
// 0 x
// 4 1
// 8 5
// 12 x^2
// 16 x^4
// 20 x^8
// 24 5*x^2
// 28 x^8 + 5*x^2
// 32 x^8 + 5*x^2 + 1

constants:
dw 1;
dw 0;
dw 0;
dw 0;

dw 5;
dw 0;
dw 0;
dw 0;

add_offsets:
dw 20; // x^8
dw 24; // 5*x^2
dw 28; // x^8 + 5*x^2

dw 4; // 1
dw 28; // x^8 + 5*x^2
dw 32; // x^8 + 5*x^2 + 1

// // Placeholders (copies of the first 3 offsets):
dw 20;
dw 24;
dw 28;
dw 20;
dw 24;
dw 28;
dw 20;
dw 24;
dw 28;
dw 20;
dw 24;
dw 28;
dw 20;
dw 24;
dw 28;
dw 20;
dw 24;
dw 28;

mul_offsets:
dw 0; // x
dw 0; // x
dw 12; // x^2

dw 12; // x^2
dw 12; // x^2
dw 16; // x^4

dw 16; // x^4
dw 16; // x^4
dw 20; // x^8

dw 8; // 5
dw 12; // x^2
dw 24; // 5*x^2

// Placeholders (copies of the first 3 offsets):
dw 0;
dw 0;
dw 12;
dw 0;
dw 0;
dw 12;
dw 0;
dw 0;
dw 12;
dw 0;
dw 0;
dw 12;
}

func main{
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
poseidon_ptr: PoseidonBuiltin*,
range_check96_ptr: felt*,
add_mod_ptr: ModBuiltin*,
mul_mod_ptr: ModBuiltin*,
}() {
alloc_locals;

let p = UInt384(d0=0xffff, d1=0xffff, d2=0xffff, d3=0xffff);
let (local inputs: UInt384*) = alloc();
assert inputs[0] = UInt384(d0=0xbbbb, d1=0xaaaa, d2=0x6666, d3=0xffff);

let res: UInt384* = apply_poly(inputs, p);
%{ print("The result: ", hex(ids.res[0].d0), hex(ids.res[0].d1), hex(ids.res[0].d2), hex(ids.res[0].d3)) %}
return ();
}
117 changes: 117 additions & 0 deletions tests/cairo_programs/modulo_trick.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
%builtins range_check bitwise poseidon range_check96 add_mod mul_mod

from starkware.cairo.common.cairo_builtins import (
ModBuiltin,
UInt384,
PoseidonBuiltin,
BitwiseBuiltin,
)
from starkware.cairo.common.registers import get_label_location
from starkware.cairo.common.modulo import run_mod_p_circuit
from starkware.cairo.common.memcpy import memcpy
from starkware.cairo.common.alloc import alloc

const P0 = 32324006162389411176778628423;
const P1 = 57042285082623239461879769745;
const P2 = 3486998266802970665;
const P3 = 0;

const N_LIMBS = 4;
const BASE = 2 ** 96;

func main{
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
poseidon_ptr: PoseidonBuiltin*,
range_check96_ptr: felt*,
add_mod_ptr: ModBuiltin*,
mul_mod_ptr: ModBuiltin*,
}() {
alloc_locals;

tempvar p = UInt384(d0=P0, d1=P1, d2=P2, d3=P3);
tempvar z = UInt384(d0=1, d1=1, d2=1, d3=1);
let values_ptr = cast(range_check96_ptr, UInt384*);
let (add_offsets_ptr: felt*) = alloc();
let (mul_offsets_ptr: felt*) = alloc();
assert values_ptr[0] = z;

// Z**2
assert mul_offsets_ptr[0] = 0;
assert mul_offsets_ptr[1] = 0;
assert mul_offsets_ptr[2] = 4;
// Z**3
assert mul_offsets_ptr[3] = 0;
assert mul_offsets_ptr[4] = 4;
assert mul_offsets_ptr[5] = 8;
// Z**4
assert mul_offsets_ptr[6] = 0;
assert mul_offsets_ptr[7] = 8;
assert mul_offsets_ptr[8] = 12;
// Z**5
assert mul_offsets_ptr[9] = 0;
assert mul_offsets_ptr[10] = 12;
assert mul_offsets_ptr[11] = 16;
// Z**6
assert mul_offsets_ptr[12] = 0;
assert mul_offsets_ptr[13] = 16;
assert mul_offsets_ptr[14] = 20;

// Dummy until 24
assert mul_offsets_ptr[15] = 0;
assert mul_offsets_ptr[16] = 0;
assert mul_offsets_ptr[17] = 24;

assert mul_offsets_ptr[18] = 0;
assert mul_offsets_ptr[19] = 0;
assert mul_offsets_ptr[20] = 28;

assert mul_offsets_ptr[21] = 0;
assert mul_offsets_ptr[22] = 0;
assert mul_offsets_ptr[23] = 32;

// assert add_mod_ptr[0] = ModBuiltin(
// p=p, values_ptr=values_ptr, offsets_ptr=add_offsets_ptr, n=3
// );
assert mul_mod_ptr[0] = ModBuiltin(
p=p, values_ptr=values_ptr, offsets_ptr=mul_offsets_ptr, n=8
);

let mul_mod_n = 8;

%{
from starkware.cairo.lang.builtins.modulo.mod_builtin_runner import ModBuiltinRunner
ModBuiltinRunner.fill_memory(memory=memory, add_mod=None, mul_mod=(ids.mul_mod_ptr.address_, builtin_runners['mul_mod_builtin'], ids.mul_mod_n))
%}

let mul_mod_ptr = mul_mod_ptr + ModBuiltin.SIZE;
let range_check96_ptr = range_check96_ptr + mul_mod_n * UInt384.SIZE + 4;

tempvar z2 = [cast(values_ptr + 4, UInt384*)];
tempvar z3 = [cast(values_ptr + 8, UInt384*)];
tempvar z4 = [cast(values_ptr + 12, UInt384*)];
tempvar z5 = [cast(values_ptr + 16, UInt384*)];

%{
from src.hints.fq import bigint_pack, get_p
p = get_p(ids)
print(f'p = {p}')
z = bigint_pack(ids.z, 4, 2**96)
z2 = bigint_pack(ids.z2, 4, 2**96)
z3 = bigint_pack(ids.z3, 4, 2**96)
z4 = bigint_pack(ids.z4, 4, 2**96)
z5 = bigint_pack(ids.z5, 4, 2**96)
print(f'z2 = {z2}')
print(f'z3 = {z3}')
print(f'z4 = {z4}')
print(f'z5 = {z5}')
assert z**2 % p == z2
assert z**3 % p == z3
assert z**4 % p == z4
assert z**5 % p == z5
%}

return ();
}
144 changes: 144 additions & 0 deletions tools/make/cairo/common/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
load("//src/starkware/cairo:vars.bzl", "CAIRO_COMMON_LIB_ADDITIONAL_FILES", "CAIRO_COMMON_LIB_ADDITIONAL_LIBS")
load("//src/starkware/cairo/lang:cairo_rules.bzl", "cairo_library")
load("//bazel_utils/python:defs.bzl", "requirement")

cairo_library(
name = "cairo_common_cairo_lib",
srcs = [
"alloc.cairo",
"bitwise.cairo",
"modulo.cairo",
"bool.cairo",
"cairo_builtins.cairo",
"default_dict.cairo",
"dict.cairo",
"dict_access.cairo",
"ec.cairo",
"ec_point.cairo",
"find_element.cairo",
"hash.cairo",
"hash_chain.cairo",
"hash_state.cairo",
"hash_state_poseidon.cairo",
"invoke.cairo",
"keccak.cairo",
"keccak_state.cairo",
"math.cairo",
"math_cmp.cairo",
"memcpy.cairo",
"memset.cairo",
"merkle_multi_update.cairo",
"merkle_update.cairo",
"patricia.cairo",
"patricia_utils.cairo",
"patricia_with_poseidon.cairo",
"patricia_with_sponge.cairo",
"poseidon_state.cairo",
"pow.cairo",
"registers.cairo",
"segments.cairo",
"serialize.cairo",
"set.cairo",
"signature.cairo",
"small_merkle_tree.cairo",
"sponge_as_hash.cairo",
"squash_dict.cairo",
"uint256.cairo",
"usort.cairo",
"//src/starkware/cairo/common/builtin_keccak:keccak.cairo",
"//src/starkware/cairo/common/builtin_poseidon:poseidon.cairo",
"//src/starkware/cairo/common/cairo_blake2s:blake2s.cairo",
"//src/starkware/cairo/common/cairo_blake2s:packed_blake2s.cairo",
"//src/starkware/cairo/common/cairo_keccak:keccak.cairo",
"//src/starkware/cairo/common/cairo_keccak:packed_keccak.cairo",
"//src/starkware/cairo/common/keccak_utils:keccak_utils.cairo",
] + CAIRO_COMMON_LIB_ADDITIONAL_FILES,
deps = [
"//src/starkware/cairo/common/cairo_secp:cairo_secp256k1",
"//src/starkware/cairo/common/secp256r1:cairo_secp256r1",
],
)

py_library(
name = "poseidon_utils_lib",
srcs = [
"poseidon_hash.py",
"poseidon_utils.py",
],
visibility = ["//visibility:public"],
deps = [
"//src/starkware/cairo/lang:cairo_constants_lib",
"//src/starkware/python:starkware_python_utils_lib",
requirement("numpy"),
],
)

py_library(
name = "cairo_common_lib",
srcs = [
"dict.py",
"hash_chain.py",
"hash_state.py",
"math_utils.py",
"patricia_utils.py",
"small_merkle_tree.py",
"structs.py",
"//src/starkware/cairo/common/cairo_blake2s:blake2s_utils.py",
"//src/starkware/cairo/common/cairo_keccak:keccak_utils.py",
"//src/starkware/cairo/common/cairo_secp:secp256r1_utils.py",
"//src/starkware/cairo/common/cairo_secp:secp_utils.py",
"//src/starkware/cairo/common/cairo_sha256:sha256_utils.py",
"//src/starkware/cairo/common/keccak_utils:keccak_utils.py",
],
data = [
":cairo_common_cairo_lib",
],
visibility = ["//visibility:public"],
deps = [
"poseidon_utils_lib",
"//src/starkware/cairo/lang:cairo_constants_lib",
"//src/starkware/cairo/lang/vm:cairo_vm_crypto_lib",
"//src/starkware/python:starkware_merkle_tree_lib",
"//src/starkware/python:starkware_python_utils_lib",
] + CAIRO_COMMON_LIB_ADDITIONAL_LIBS,
)

package(default_visibility = ["//visibility:public"])

exports_files(glob([
"*.cairo",
"*.py",
]))

py_library(
name = "cairo_common_validate_utils_lib",
srcs = [
"validate_utils.py",
],
visibility = ["//visibility:public"],
deps = [
"//src/starkware/cairo/lang/builtins:cairo_run_builtins_lib",
"//src/starkware/cairo/lang/vm:cairo_run_lib",
"//src/starkware/cairo/lang/vm:cairo_vm_lib",
"//src/starkware/python:starkware_python_utils_lib",
],
)

py_library(
name = "cairo_function_runner_lib",
srcs = [
"cairo_function_runner.py",
],
visibility = ["//visibility:public"],
deps = [
":cairo_common_lib",
"//src/starkware/cairo/lang/builtins:cairo_run_builtins_lib",
"//src/starkware/cairo/lang/compiler:cairo_compile_lib",
"//src/starkware/cairo/lang/tracer:cairo_tracer_lib",
"//src/starkware/cairo/lang/vm:cairo_relocatable_lib",
"//src/starkware/cairo/lang/vm:cairo_run_lib",
"//src/starkware/cairo/lang/vm:cairo_vm_crypto_lib",
"//src/starkware/cairo/lang/vm:cairo_vm_lib",
"//src/starkware/python:starkware_python_utils_lib",
],
)
Loading

0 comments on commit de57e58

Please sign in to comment.