Skip to content

Commit

Permalink
Implement limbs_guarantee type with gate value and circuit modulus
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianGCalderon committed Feb 5, 2025
1 parent b6d780c commit 678f8f7
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 7 deletions.
53 changes: 50 additions & 3 deletions src/libfuncs/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,13 @@ fn build_get_output<'ctx, 'this>(
llvm::r#type::array(build_u384_struct_type(context), n_gates as u32),
0,
)?;
let modulus_struct = entry.extract_value(
context,
location,
outputs,
build_u384_struct_type(context),
1,
)?;
let output_struct = entry.extract_value(
context,
location,
Expand All @@ -829,9 +836,24 @@ fn build_get_output<'ctx, 'this>(
output_idx,
)?;

let guarantee_type_id = &info.branch_signatures()[0].vars[1].ty;
let guarantee_type = registry.build_type(context, helper, metadata, guarantee_type_id)?;
let guarantee = entry.append_op_result(llvm::undef(guarantee_type, location))?;
let guarantee = {
let guarantee_type_id = &info.branch_signatures()[0].vars[1].ty;

let u96_type = IntegerType::new(context, 96).into();
let output_array = struct_to_array(context, entry, location, output_struct, u96_type, 4)?;
let modulus_array = struct_to_array(context, entry, location, modulus_struct, u96_type, 4)?;

build_struct_value(
context,
registry,
entry,
location,
helper,
metadata,
guarantee_type_id,
&[output_array, modulus_array],
)?
};

entry.append_operation(helper.br(0, &[output_struct, guarantee], location));

Expand Down Expand Up @@ -925,6 +947,31 @@ fn u384_integer_to_struct<'a>(
)
}

fn struct_to_array<'ctx>(
context: &'ctx Context,
block: &'ctx Block<'ctx>,
location: Location<'ctx>,
r#struct: Value<'ctx, 'ctx>,
element_type: Type<'ctx>,
length: u32,
) -> Result<Value<'ctx, 'ctx>> {
let mut values = Vec::with_capacity(length as usize);

for i in 0..length {
let value = block.extract_value(context, location, r#struct, element_type, i as usize)?;

values.push(value);
}

let array_type = llvm::r#type::array(element_type, length);
block.insert_values(
context,
location,
block.append_op_result(llvm::undef(array_type, location))?,
&values,
)
}

/// The extended euclidean algorithm calculates the greatest common divisor (gcd) of two integers a and b,
/// as well as the bezout coefficients x and y such that ax+by=gcd(a,b)
/// if gcd(a,b) = 1, then x is the modular multiplicative inverse of a modulo b.
Expand Down
36 changes: 32 additions & 4 deletions src/types/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
};
use cairo_lang_sierra::{
extensions::{
circuit::CircuitTypeConcrete,
circuit::{CircuitTypeConcrete, ConcreteU96LimbsLessThanGuarantee},
core::{CoreLibfunc, CoreType, CoreTypeConcrete},
types::InfoOnlyConcreteType,
},
Expand Down Expand Up @@ -57,10 +57,19 @@ pub fn build<'ctx>(
metadata,
WithSelf::new(selector.self_ty(), info),
),
CircuitTypeConcrete::U96LimbsLessThanGuarantee(info) => {
build_u96_limbs_less_than_guarantee(
context,
module,
registry,
metadata,
WithSelf::new(selector.self_ty(), info),
)
}
// builtins
CircuitTypeConcrete::AddMod(_)
| CircuitTypeConcrete::U96LimbsLessThanGuarantee(_)
| CircuitTypeConcrete::MulMod(_) => Ok(IntegerType::new(context, 64).into()),
CircuitTypeConcrete::AddMod(_) | CircuitTypeConcrete::MulMod(_) => {
Ok(IntegerType::new(context, 64).into())
}
// noops
CircuitTypeConcrete::CircuitDescriptor(_)
| CircuitTypeConcrete::CircuitFailureGuarantee(_)
Expand Down Expand Up @@ -157,6 +166,25 @@ pub fn build_circuit_outputs<'ctx>(
))
}

pub fn build_u96_limbs_less_than_guarantee<'ctx>(
context: &'ctx Context,
_module: &Module<'ctx>,
_registry: &ProgramRegistry<CoreType, CoreLibfunc>,
_metadata: &mut MetadataStorage,
info: WithSelf<ConcreteU96LimbsLessThanGuarantee>,
) -> Result<Type<'ctx>> {
let limbs = info.inner.limb_count;

Ok(llvm::r#type::r#struct(
context,
&[
llvm::r#type::array(IntegerType::new(context, 96).into(), limbs as u32),
llvm::r#type::array(IntegerType::new(context, 96).into(), limbs as u32),
],
false,
))
}

pub const fn is_complex(info: &CircuitTypeConcrete) -> bool {
match *info {
CircuitTypeConcrete::AddMod(_)
Expand Down

0 comments on commit 678f8f7

Please sign in to comment.