cairo_lang_sierra/extensions/modules/
poseidon.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use super::felt252::Felt252Type;
use crate::define_libfunc_hierarchy;
use crate::extensions::lib_func::{
    DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature, SierraApChange,
    SignatureSpecializationContext,
};
use crate::extensions::{
    NamedType, NoGenericArgsGenericLibfunc, NoGenericArgsGenericType, OutputVarReferenceInfo,
    SpecializationError,
};
use crate::ids::GenericTypeId;

/// Type representing the Poseidon hash builtin.
#[derive(Default)]
pub struct PoseidonType {}
impl NoGenericArgsGenericType for PoseidonType {
    const ID: GenericTypeId = GenericTypeId::new_inline("Poseidon");
    const STORABLE: bool = true;
    const DUPLICATABLE: bool = false;
    const DROPPABLE: bool = false;
    const ZERO_SIZED: bool = false;
}

define_libfunc_hierarchy! {
    pub enum PoseidonLibfunc {
        HadesPermutation(HadesPermutationLibfunc),
    }, PoseidonConcreteLibfunc
}

/// Libfunc for computing the Poseidon permutation over 3 felt252s.
/// Returns the 3 element state after the permutation (and the updated builtin pointer).
#[derive(Default)]
pub struct HadesPermutationLibfunc {}
impl NoGenericArgsGenericLibfunc for HadesPermutationLibfunc {
    const STR_ID: &'static str = "hades_permutation";

    fn specialize_signature(
        &self,
        context: &dyn SignatureSpecializationContext,
    ) -> Result<LibfuncSignature, SpecializationError> {
        let poseidon_ty = context.get_concrete_type(PoseidonType::id(), &[])?;
        let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
        let deferred_felt252_output_info = OutputVarInfo {
            ty: felt252_ty.clone(),
            ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
        };
        let felt252_param = ParamSignature::new(felt252_ty);
        Ok(LibfuncSignature::new_non_branch_ex(
            vec![
                ParamSignature::new(poseidon_ty.clone()).with_allow_add_const(),
                felt252_param.clone(),
                felt252_param.clone(),
                felt252_param,
            ],
            vec![
                OutputVarInfo::new_builtin(poseidon_ty, 0),
                deferred_felt252_output_info.clone(),
                deferred_felt252_output_info.clone(),
                deferred_felt252_output_info,
            ],
            SierraApChange::Known { new_vars_only: true },
        ))
    }
}