cairo_lang_sierra/extensions/modules/
poseidon.rs

1use super::felt252::Felt252Type;
2use crate::define_libfunc_hierarchy;
3use crate::extensions::lib_func::{
4    DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature, SierraApChange,
5    SignatureSpecializationContext,
6};
7use crate::extensions::{
8    NamedType, NoGenericArgsGenericLibfunc, NoGenericArgsGenericType, OutputVarReferenceInfo,
9    SpecializationError,
10};
11use crate::ids::GenericTypeId;
12
13/// Type representing the Poseidon hash builtin.
14#[derive(Default)]
15pub struct PoseidonType {}
16impl NoGenericArgsGenericType for PoseidonType {
17    const ID: GenericTypeId = GenericTypeId::new_inline("Poseidon");
18    const STORABLE: bool = true;
19    const DUPLICATABLE: bool = false;
20    const DROPPABLE: bool = false;
21    const ZERO_SIZED: bool = false;
22}
23
24define_libfunc_hierarchy! {
25    pub enum PoseidonLibfunc {
26        HadesPermutation(HadesPermutationLibfunc),
27    }, PoseidonConcreteLibfunc
28}
29
30/// Libfunc for computing the Poseidon permutation over 3 felt252s.
31/// Returns the 3 element state after the permutation (and the updated builtin pointer).
32#[derive(Default)]
33pub struct HadesPermutationLibfunc {}
34impl NoGenericArgsGenericLibfunc for HadesPermutationLibfunc {
35    const STR_ID: &'static str = "hades_permutation";
36
37    fn specialize_signature(
38        &self,
39        context: &dyn SignatureSpecializationContext,
40    ) -> Result<LibfuncSignature, SpecializationError> {
41        let poseidon_ty = context.get_concrete_type(PoseidonType::id(), &[])?;
42        let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
43        let deferred_felt252_output_info = OutputVarInfo {
44            ty: felt252_ty.clone(),
45            ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
46        };
47        let felt252_param = ParamSignature::new(felt252_ty);
48        Ok(LibfuncSignature::new_non_branch_ex(
49            vec![
50                ParamSignature::new(poseidon_ty.clone()).with_allow_add_const(),
51                felt252_param.clone(),
52                felt252_param.clone(),
53                felt252_param,
54            ],
55            vec![
56                OutputVarInfo::new_builtin(poseidon_ty, 0),
57                deferred_felt252_output_info.clone(),
58                deferred_felt252_output_info.clone(),
59                deferred_felt252_output_info,
60            ],
61            SierraApChange::Known { new_vars_only: true },
62        ))
63    }
64}