diff --git a/Cargo.lock b/Cargo.lock
index 5d85d56b667e9f5da2b4f6ff6ce5dea0d144d816..a4a7b4dc8711c03b0f1e7dc35b92bc1b08a9dd42 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3903,6 +3903,21 @@ dependencies = [
  "sp-std",
 ]
 
+[[package]]
+name = "pallet-certification"
+version = "3.0.0"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "serde",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
 [[package]]
 name = "pallet-grandpa"
 version = "3.1.0"
diff --git a/Cargo.toml b/Cargo.toml
index 287482311f04353e58b55a3cd937d3fbf0cede43..615b817ae92db66717f200a3d79befeb33d2ae79 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,7 @@
 [workspace]
 members = [
     'node',
+    'pallets/certification',
     'pallets/identity',
     'pallets/ud-accounts-storage',
     'pallets/universal-dividend',
diff --git a/pallets/strong-certs/Cargo.toml b/pallets/certification/Cargo.toml
similarity index 95%
rename from pallets/strong-certs/Cargo.toml
rename to pallets/certification/Cargo.toml
index 507fe8d40c5d7742b9ef131943952390c0b56d0d..cc07b102da453d464a28a9e2bfed83d68e77e290 100644
--- a/pallets/strong-certs/Cargo.toml
+++ b/pallets/certification/Cargo.toml
@@ -1,10 +1,10 @@
 [package]
 authors = ['librelois <c@elo.tf>']
-description = 'FRAME pallet strong certifications.'
+description = 'FRAME pallet certification.'
 edition = '2018'
 homepage = 'https://substrate.dev'
 license = 'AGPL-3.0'
-name = 'pallet-strong-certs'
+name = 'pallet-certification'
 readme = 'README.md'
 repository = 'https://git.duniter.org/nodes/rust/lc-core-substrate' 
 version = '3.0.0'
diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7287287cb3cfed3a3026d293c40999d7df82232b
--- /dev/null
+++ b/pallets/certification/src/lib.rs
@@ -0,0 +1,223 @@
+// Copyright 2021 Axiom-Team
+//
+// This file is part of Substrate-Libre-Currency.
+//
+// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License.
+//
+// Substrate-Libre-Currency is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub use pallet::*;
+
+use codec::Codec;
+use sp_runtime::traits::{AtLeast32BitUnsigned, Zero};
+use sp_std::collections::btree_map::BTreeMap;
+use sp_std::collections::btree_set::BTreeSet;
+use sp_std::fmt::Debug;
+
+pub mod pallet {
+    use super::*;
+    use frame_support::pallet_prelude::*;
+    //use frame_system::pallet_prelude::*;
+
+    /// Configure the pallet by specifying the parameters and types on which it depends.
+    pub trait Config<I: Instance = DefaultInstance>: frame_system::Config {
+        /// Duration after which a certification is renewable
+        type ChainabilityPeriod: Get<Self::BlockNumber>;
+        /// The overarching event type.
+        type Event: From<Event<Self, I>> + Into<<Self as frame_system::Config>::Event>;
+        /// A short identity index.
+        type IdtyIndex: Parameter
+            + Member
+            + AtLeast32BitUnsigned
+            + Codec
+            + Default
+            + Copy
+            + MaybeSerializeDeserialize
+            + Debug
+            + MaxEncodedLen;
+        /// Maximum number of active certifications by issuer
+        type MaxByIssuer: Get<u32>;
+        /// Minimum duration between two certifications issued by the same issuer
+        type SignPeriod: Get<Self::BlockNumber>;
+        /// Duration of validity of a certification
+        type ValidityPeriod: Get<Self::BlockNumber>;
+    }
+
+    frame_support::decl_event! {
+        pub enum Event<T, I=DefaultInstance> where
+            <T as frame_system::Config>::Hash,
+            <T as frame_system::Config>::AccountId,
+        {
+            /// A motion (given hash) has been proposed (by given account) with a threshold (given
+            /// `MemberCount`).
+            /// \[account, proposal_hash\]
+            Proposed(AccountId, Hash),
+        }
+    }
+
+    frame_support::decl_error! {
+        pub enum Error for Module<T: Config<I>, I: Instance> {
+            /// Account is not a member
+            NotMember,
+        }
+    }
+
+    // STORAGE //
+
+    // A value placed in storage that represents the current version of the Balances storage.
+    // This value is used by the `on_runtime_upgrade` logic to determine whether we run
+    // storage migration logic. This should match directly with the semantic versions of the Rust crate.
+    #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug)]
+    pub enum Releases {
+        V1_0_0,
+    }
+    impl Default for Releases {
+        fn default() -> Self {
+            Releases::V1_0_0
+        }
+    }
+
+    #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug)]
+    pub struct CertValue<T: Config<I>, I: Instance> {
+        receiver: T::IdtyIndex,
+        chainable_on: T::BlockNumber,
+        removable_on: T::BlockNumber,
+    }
+
+    #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, RuntimeDebug)]
+    pub struct CertsByIssuer<T: Config<I>, I: Instance> {
+        certs: Vec<CertValue<T, I>>,
+        next_issuable_on: T::BlockNumber,
+    }
+
+    frame_support::decl_storage! {
+        trait Store for Module<T: Config<I>, I: Instance=DefaultInstance> as Certification {
+            /// Storage version of the pallet.
+            StorageVersion get(fn storage_version): Releases;
+            /// Certifications by issuer
+            pub StorageCertsByIssuer get(fn certs_by_issuer):
+            map hasher(twox_64_concat) T::IdtyIndex => CertsByIssuer<T, I> = CertsByIssuer {
+                certs: vec![],
+                next_issuable_on: T::BlockNumber::zero(),
+            };
+            /// Certifications by receiver
+            pub StorageCertsByReceiver get(fn certs_by_receiver):
+            map hasher(twox_64_concat) T::IdtyIndex => Vec<T::IdtyIndex>;
+            /// Certifications removable on
+            pub StorageCertsRemovableOn get(fn certs_removable_on):
+            map hasher(twox_64_concat) T::BlockNumber => Vec<(T::IdtyIndex, T::IdtyIndex)>;
+        }
+        add_extra_genesis {
+            config(phantom): sp_std::marker::PhantomData<I>;
+            config(certs_by_issuer): BTreeMap<T::IdtyIndex, BTreeSet<T::IdtyIndex>>;
+            build(|config| {
+                let mut certs_by_receiver = BTreeMap::<T::IdtyIndex, Vec<T::IdtyIndex>>::new();
+                for (issuer, receivers) in &config.certs_by_issuer {
+                    assert!(!receivers.contains(issuer), "Identity cannot tcertify it-self.");
+                    assert!(!receivers.len() <= T::MaxByIssuer::get() as usize, "Identity n°{:?} exceed MaxByIssuer.", issuer);
+                    for receiver in receivers {
+                        certs_by_receiver.entry(*receiver).or_default().push(*issuer);
+                    }
+                }
+
+                <StorageVersion<I>>::put(Releases::V1_0_0);
+                let mut all_couples = Vec::new();
+                for (issuer, receivers) in &config.certs_by_issuer {
+                    let mut certs = Vec::with_capacity(receivers.len());
+                    for receiver in receivers {
+                        all_couples.push((*issuer, *receiver));
+                        certs.push(CertValue {
+                            receiver: *receiver,
+                            chainable_on: T::ChainabilityPeriod::get(),
+                            removable_on: T::ValidityPeriod::get(),
+                        });
+                        let received_certs = certs_by_receiver.remove(receiver).unwrap_or_default();
+                        <StorageCertsByReceiver<T, I>>::insert(receiver, received_certs);
+
+                    }
+                    <StorageCertsByIssuer<T, I>>::insert(issuer, CertsByIssuer {
+                        certs,
+                        next_issuable_on: T::SignPeriod::get(),
+                    });
+                }
+                <StorageCertsRemovableOn<T, I>>::insert(T::ValidityPeriod::get(), all_couples);
+            });
+        }
+    }
+
+    // CALLS //
+
+    frame_support::decl_module! {
+        pub struct Module<T: Config<I>, I: Instance=DefaultInstance> for enum Call where origin: <T as frame_system::Config>::Origin {
+            type Error = Error<T, I>;
+
+            fn deposit_event() = default;
+
+            fn on_initialize(n: T::BlockNumber) -> Weight {
+                Self::prune_certifications(n)
+            }
+        }
+    }
+
+    // INTERNAL FUNCTIONS //
+
+    impl<T: Config<I>, I: Instance> Module<T, I> {
+        fn prune_certifications(block_number: T::BlockNumber) -> Weight {
+            let mut total_weight: Weight = 0;
+
+            use frame_support::storage::generator::StorageMap as _;
+            if let Some(certs) = StorageCertsRemovableOn::<T, I>::from_query_to_optional_value(
+                StorageCertsRemovableOn::<T, I>::take(block_number),
+            ) {
+                for (issuer, receiver) in certs {
+                    total_weight += Self::remove_cert_inner(issuer, receiver, Some(block_number));
+                }
+            }
+
+            total_weight
+        }
+        fn remove_cert_inner(
+            issuer: T::IdtyIndex,
+            receiver: T::IdtyIndex,
+            block_number_opt: Option<T::BlockNumber>,
+        ) -> Weight {
+            if let Ok(mut certs_by_issuer) = <StorageCertsByIssuer<T, I>>::try_get(issuer) {
+                if let Ok(index) = certs_by_issuer.certs.binary_search_by(
+                    |CertValue {
+                         receiver: receiver_,
+                         ..
+                     }| receiver.cmp(&receiver_),
+                ) {
+                    if let Some(cert_val) = certs_by_issuer.certs.get(index) {
+                        if Some(cert_val.removable_on) == block_number_opt
+                            || block_number_opt.is_none()
+                        {
+                            certs_by_issuer.certs.remove(index);
+                            <StorageCertsByIssuer<T, I>>::insert(issuer, certs_by_issuer);
+                            if let Ok(mut certs_by_receiver) =
+                                <StorageCertsByReceiver<T, I>>::try_get(receiver)
+                            {
+                                if let Ok(index) = certs_by_receiver
+                                    .binary_search_by(|issuer_| issuer.cmp(&issuer_))
+                                {
+                                    certs_by_receiver.remove(index);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            0
+        }
+    }
+}
diff --git a/pallets/strong-certs/src/lib.rs b/pallets/strong-certs/src/lib.rs
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000