Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  macros.rs

  Sprache: Rust
 

macro_rules! blake2_impl {
    (
        $name:ident, $alg_name:expr, $word:ident, $vec:ident, $bytes:ident,
        $block_size:ident, $R1:expr, $R2:expr, $R3:expr, $R4:expr, $IV:expr,
        $vardoc:expr, $doc:expr,
    ) => {
        #[derive(Clone)]
        #[doc=$vardoc]
        pub struct $name {
            h: [$vec; 2],
            t: u64,
            #[cfg(feature = "reset")]
            h0: [$vec; 2],
        }

        impl $name {
            #[inline(always)]
            fn iv0() -> $vec {
                $vec::new($IV[0], $IV[1], $IV[2], $IV[3])
            }
            #[inline(always)]
            fn iv1() -> $vec {
                $vec::new($IV[4], $IV[5], $IV[6], $IV[7])
            }

            /// Creates a new context with the full set of sequential-mode parameters.
            pub fn new_with_params(
                salt: &[u8],
                persona: &[u8],
                key_size: usize,
                output_size: usize,
            ) -> Self {
                assert!(key_size <= $bytes::to_usize());
                assert!(output_size <= $bytes::to_usize());

                // The number of bytes needed to express two words.
                let length = $bytes::to_usize() / 4;
                assert!(salt.len() <= length);
                assert!(persona.len() <= length);

                // Build a parameter block
                let mut p = [0 as $word; 8];
                p[0] = 0x0101_0000 ^ ((key_size as $word) << 8) ^ (output_size as $word);

                // salt is two words long
                if salt.len() < length {
                    let mut padded_salt =
                        GenericArray::<u8, <$bytes as Div<U4>>::Output>::default();
                    for i in 0..salt.len() {
                        padded_salt[i] = salt[i];
                    }
                    p[4] = $word::from_le_bytes(padded_salt[0..length / 2].try_into().unwrap());
                    p[5] = $word::from_le_bytes(
                        padded_salt[length / 2..padded_salt.len()]
                            .try_into()
                            .unwrap(),
                    );
                } else {
                    p[4] = $word::from_le_bytes(salt[0..salt.len() / 2].try_into().unwrap());
                    p[5] =
                        $word::from_le_bytes(salt[salt.len() / 2..salt.len()].try_into().unwrap());
                }

                // persona is also two words long
                if persona.len() < length {
                    let mut padded_persona =
                        GenericArray::<u8, <$bytes as Div<U4>>::Output>::default();
                    for i in 0..persona.len() {
                        padded_persona[i] = persona[i];
                    }
                    p[6] = $word::from_le_bytes(padded_persona[0..length / 2].try_into().unwrap());
                    p[7] = $word::from_le_bytes(
                        padded_persona[length / 2..padded_persona.len()]
                            .try_into()
                            .unwrap(),
                    );
                } else {
                    p[6] = $word::from_le_bytes(persona[0..length / 2].try_into().unwrap());
                    p[7] = $word::from_le_bytes(
                        persona[length / 2..persona.len()].try_into().unwrap(),
                    );
                }

                let h = [
                    Self::iv0() ^ $vec::new(p[0], p[1], p[2], p[3]),
                    Self::iv1() ^ $vec::new(p[4], p[5], p[6], p[7]),
                ];
                $name {
                    #[cfg(feature = "reset")]
                    h0: h.clone(),
                    h,
                    t: 0,
                }
            }

            fn finalize_with_flag(
                &mut self,
                final_block: &GenericArray<u8, $block_size>,
                flag: $word,
                out: &mut Output<Self>,
            ) {
                self.compress(final_block, !0, flag);
                let buf = [self.h[0].to_le(), self.h[1].to_le()];
                out.copy_from_slice(buf.as_bytes())
            }

            fn compress(&mut self, block: &Block<Self>, f0: $word, f1: $word) {
                use $crate::consts::SIGMA;

                #[cfg_attr(not(feature = "size_opt"), inline(always))]
                fn quarter_round(v: &mut [$vec; 4], rd: u32, rb: u32, m: $vec) {
                    v[0] = v[0].wrapping_add(v[1]).wrapping_add(m.from_le());
                    v[3] = (v[3] ^ v[0]).rotate_right_const(rd);
                    v[2] = v[2].wrapping_add(v[3]);
                    v[1] = (v[1] ^ v[2]).rotate_right_const(rb);
                }

                #[cfg_attr(not(feature = "size_opt"), inline(always))]
                fn shuffle(v: &mut [$vec; 4]) {
                    v[1] = v[1].shuffle_left_1();
                    v[2] = v[2].shuffle_left_2();
                    v[3] = v[3].shuffle_left_3();
                }

                #[cfg_attr(not(feature = "size_opt"), inline(always))]
                fn unshuffle(v: &mut [$vec; 4]) {
                    v[1] = v[1].shuffle_right_1();
                    v[2] = v[2].shuffle_right_2();
                    v[3] = v[3].shuffle_right_3();
                }

                #[cfg_attr(not(feature = "size_opt"), inline(always))]
                fn round(v: &mut [$vec; 4], m: &[$word; 16], s: &[usize; 16]) {
                    quarter_round(v, $R1, $R2, $vec::gather(m, s[0], s[2], s[4], s[6]));
                    quarter_round(v, $R3, $R4, $vec::gather(m, s[1], s[3], s[5], s[7]));

                    shuffle(v);
                    quarter_round(v, $R1, $R2, $vec::gather(m, s[8], s[10], s[12], s[14]));
                    quarter_round(v, $R3, $R4, $vec::gather(m, s[9], s[11], s[13], s[15]));
                    unshuffle(v);
                }

                let mut m: [$word; 16] = Default::default();
                let n = core::mem::size_of::<$word>();
                for (v, chunk) in m.iter_mut().zip(block.chunks_exact(n)) {
                    *v = $word::from_ne_bytes(chunk.try_into().unwrap());
                }
                let h = &mut self.h;

                let t0 = self.t as $word;
                let t1 = match $bytes::to_u8() {
                    64 => 0,
                    32 => (self.t >> 32as $word,
                    _ => unreachable!(),
                };

                let mut v = [
                    h[0],
                    h[1],
                    Self::iv0(),
                    Self::iv1() ^ $vec::new(t0, t1, f0, f1),
                ];

                round(&mut v, &m, &SIGMA[0]);
                round(&mut v, &m, &SIGMA[1]);
                round(&mut v, &m, &SIGMA[2]);
                round(&mut v, &m, &SIGMA[3]);
                round(&mut v, &m, &SIGMA[4]);
                round(&mut v, &m, &SIGMA[5]);
                round(&mut v, &m, &SIGMA[6]);
                round(&mut v, &m, &SIGMA[7]);
                round(&mut v, &m, &SIGMA[8]);
                round(&mut v, &m, &SIGMA[9]);
                if $bytes::to_u8() == 64 {
                    round(&mut v, &m, &SIGMA[0]);
                    round(&mut v, &m, &SIGMA[1]);
                }

                h[0] = h[0] ^ (v[0] ^ v[2]);
                h[1] = h[1] ^ (v[1] ^ v[3]);
            }
        }

        impl HashMarker for $name {}

        impl BlockSizeUser for $name {
            type BlockSize = $block_size;
        }

        impl BufferKindUser for $name {
            type BufferKind = Lazy;
        }

        impl UpdateCore for $name {
            #[inline]
            fn update_blocks(&mut self, blocks: &[Block<Self>]) {
                for block in blocks {
                    self.t += block.len() as u64;
                    self.compress(block, 00);
                }
            }
        }

        impl OutputSizeUser for $name {
            type OutputSize = $bytes;
        }

        impl VariableOutputCore for $name {
            const TRUNC_SIDE: TruncSide = TruncSide::Left;

            #[inline]
            fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
                if output_size > Self::OutputSize::USIZE {
                    return Err(InvalidOutputSize);
                }
                Ok(Self::new_with_params(&[], &[], 0, output_size))
            }

            #[inline]
            fn finalize_variable_core(
                &mut self,
                buffer: &mut Buffer<Self>,
                out: &mut Output<Self>,
            ) {
                self.t += buffer.get_pos() as u64;
                let block = buffer.pad_with_zeros();
                self.finalize_with_flag(block, 0, out);
            }
        }

        #[cfg(feature = "reset")]
        impl Reset for $name {
            fn reset(&mut self) {
                self.h = self.h0;
                self.t = 0;
            }
        }

        impl AlgorithmName for $name {
            #[inline]
            fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
                f.write_str($alg_name)
            }
        }

        impl fmt::Debug for $name {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                f.write_str(concat!(stringify!($name), " { ... }"))
            }
        }
    };
}

macro_rules! blake2_mac_impl {
    (
        $name:ident, $hash:ty, $max_size:ty, $doc:expr
    ) => {
        #[derive(Clone)]
        #[doc=$doc]
        pub struct $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            core: $hash,
            buffer: LazyBuffer<<$hash as BlockSizeUser>::BlockSize>,
            #[cfg(feature = "reset")]
            key_block: Option<Key<Self>>,
            _out: PhantomData<OutSize>,
        }

        impl<OutSize> $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            /// Create new instance using provided key, salt, and persona.
            ///
            /// Setting key to `None` indicates unkeyed usage.
            ///
            /// # Errors
            ///
            /// If key is `Some`, then its length should not be zero or bigger
            /// than the block size. The salt and persona length should not be
            /// bigger than quarter of block size. If any of those conditions is
            /// false the method will return an error.
            #[inline]
            pub fn new_with_salt_and_personal(
                key: Option<&[u8]>,
                salt: &[u8],
                persona: &[u8],
            ) -> Result<Self, InvalidLength> {
                let kl = key.map_or(0, |k| k.len());
                let bs = <$hash as BlockSizeUser>::BlockSize::USIZE;
                let qbs = bs / 4;
                if key.is_some() && kl == 0 || kl > bs || salt.len() > qbs || persona.len() > qbs {
                    return Err(InvalidLength);
                }
                let buffer = if let Some(k) = key {
                    let mut padded_key = Block::<$hash>::default();
                    padded_key[..kl].copy_from_slice(k);
                    LazyBuffer::new(&padded_key)
                } else {
                    LazyBuffer::default()
                };
                Ok(Self {
                    core: <$hash>::new_with_params(salt, persona, kl, OutSize::USIZE),
                    buffer,
                    #[cfg(feature = "reset")]
                    key_block: key.map(|k| {
                        let mut t = Key::<Self>::default();
                        t[..kl].copy_from_slice(k);
                        t
                    }),
                    _out: PhantomData,
                })
            }
        }

        impl<OutSize> KeySizeUser for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            type KeySize = $max_size;
        }

        impl<OutSize> KeyInit for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            #[inline]
            fn new(key: &Key<Self>) -> Self {
                Self::new_from_slice(key).expect("Key has correct length")
            }

            #[inline]
            fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
                let kl = key.len();
                if kl > <Self as KeySizeUser>::KeySize::USIZE {
                    return Err(InvalidLength);
                }
                let mut padded_key = Block::<$hash>::default();
                padded_key[..kl].copy_from_slice(key);
                Ok(Self {
                    core: <$hash>::new_with_params(&[], &[], key.len(), OutSize::USIZE),
                    buffer: LazyBuffer::new(&padded_key),
                    #[cfg(feature = "reset")]
                    key_block: {
                        let mut t = Key::<Self>::default();
                        t[..kl].copy_from_slice(key);
                        Some(t)
                    },
                    _out: PhantomData,
                })
            }
        }

        impl<OutSize> Update for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            #[inline]
            fn update(&mut self, input: &[u8]) {
                let Self { core, buffer, .. } = self;
                buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
            }
        }

        impl<OutSize> OutputSizeUser for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size> + 'static,
            LeEq<OutSize, $max_size>: NonZero,
        {
            type OutputSize = OutSize;
        }

        impl<OutSize> FixedOutput for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size> + 'static,
            LeEq<OutSize, $max_size>: NonZero,
        {
            #[inline]
            fn finalize_into(mut self, out: &mut Output<Self>) {
                let Self { core, buffer, .. } = &mut self;
                let mut full_res = Default::default();
                core.finalize_variable_core(buffer, &mut full_res);
                out.copy_from_slice(&full_res[..OutSize::USIZE]);
            }
        }

        #[cfg(feature = "reset")]
        impl<OutSize> Reset for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            fn reset(&mut self) {
                self.core.reset();
                self.buffer = if let Some(k) = self.key_block {
                    let kl = k.len();
                    let mut padded_key = Block::<$hash>::default();
                    padded_key[..kl].copy_from_slice(&k);
                    LazyBuffer::new(&padded_key)
                } else {
                    LazyBuffer::default()
                }
            }
        }

        #[cfg(feature = "reset")]
        impl<OutSize> FixedOutputReset for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            #[inline]
            fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
                let Self { core, buffer, .. } = self;
                let mut full_res = Default::default();
                core.finalize_variable_core(buffer, &mut full_res);
                out.copy_from_slice(&full_res[..OutSize::USIZE]);
                self.reset();
            }
        }

        impl<OutSize> MacMarker for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
        }

        impl<OutSize> fmt::Debug for $name<OutSize>
        where
            OutSize: ArrayLength<u8> + IsLessOrEqual<$max_size>,
            LeEq<OutSize, $max_size>: NonZero,
        {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "{}{} {{ ... }}", stringify!($name), OutSize::USIZE)
            }
        }
    };
}

Messung V0.5 in Prozent
C=94 H=100 G=96

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-06-22) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik