Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:28

0001 //==- BLAKE3.h - BLAKE3 C++ wrapper for LLVM ---------------------*- C++ -*-==//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This is a C++ wrapper of the BLAKE3 C interface.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_SUPPORT_BLAKE3_H
0014 #define LLVM_SUPPORT_BLAKE3_H
0015 
0016 #include "llvm-c/blake3.h"
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/StringRef.h"
0019 
0020 namespace llvm {
0021 
0022 /// The constant \p LLVM_BLAKE3_OUT_LEN provides the default output length,
0023 /// 32 bytes, which is recommended for most callers.
0024 ///
0025 /// Outputs shorter than the default length of 32 bytes (256 bits) provide
0026 /// less security. An N-bit BLAKE3 output is intended to provide N bits of
0027 /// first and second preimage resistance and N/2 bits of collision
0028 /// resistance, for any N up to 256. Longer outputs don't provide any
0029 /// additional security.
0030 ///
0031 /// Shorter BLAKE3 outputs are prefixes of longer ones. Explicitly
0032 /// requesting a short output is equivalent to truncating the default-length
0033 /// output.
0034 template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
0035 using BLAKE3Result = std::array<uint8_t, NumBytes>;
0036 
0037 /// A class that wraps the BLAKE3 algorithm.
0038 class BLAKE3 {
0039 public:
0040   BLAKE3() { init(); }
0041 
0042   /// Reinitialize the internal state
0043   void init() { llvm_blake3_hasher_init(&Hasher); }
0044 
0045   /// Digest more data.
0046   void update(ArrayRef<uint8_t> Data) {
0047     llvm_blake3_hasher_update(&Hasher, Data.data(), Data.size());
0048   }
0049 
0050   /// Digest more data.
0051   void update(StringRef Str) {
0052     llvm_blake3_hasher_update(&Hasher, Str.data(), Str.size());
0053   }
0054 
0055   /// Finalize the hasher and put the result in \p Result.
0056   /// This doesn't modify the hasher itself, and it's possible to finalize again
0057   /// after adding more input.
0058   template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
0059   void final(BLAKE3Result<NumBytes> &Result) {
0060     llvm_blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
0061   }
0062 
0063   /// Finalize the hasher and return an output of any length, given in bytes.
0064   /// This doesn't modify the hasher itself, and it's possible to finalize again
0065   /// after adding more input.
0066   template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
0067   BLAKE3Result<NumBytes> final() {
0068     BLAKE3Result<NumBytes> Result;
0069     llvm_blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
0070     return Result;
0071   }
0072 
0073   /// Return the current output for the digested data since the last call to
0074   /// init().
0075   ///
0076   /// Other hash functions distinguish between \p result() and \p final(), with
0077   /// \p result() allowing more calls into \p update(), but there's no
0078   // difference for the BLAKE3 hash function.
0079   template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
0080   BLAKE3Result<NumBytes> result() {
0081     return final<NumBytes>();
0082   }
0083 
0084   /// Returns a BLAKE3 hash for the given data.
0085   template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
0086   static BLAKE3Result<NumBytes> hash(ArrayRef<uint8_t> Data) {
0087     BLAKE3 Hasher;
0088     Hasher.update(Data);
0089     return Hasher.final<NumBytes>();
0090   }
0091 
0092 private:
0093   llvm_blake3_hasher Hasher;
0094 };
0095 
0096 /// Like \p BLAKE3 but using a class-level template parameter for specifying the
0097 /// hash size of the \p final() and \p result() functions.
0098 ///
0099 /// This is useful for using BLAKE3 as the hasher type for \p HashBuilder with
0100 /// non-default hash sizes.
0101 template <size_t NumBytes> class TruncatedBLAKE3 : public BLAKE3 {
0102 public:
0103   /// Finalize the hasher and put the result in \p Result.
0104   /// This doesn't modify the hasher itself, and it's possible to finalize again
0105   /// after adding more input.
0106   void final(BLAKE3Result<NumBytes> &Result) { return BLAKE3::final(Result); }
0107 
0108   /// Finalize the hasher and return an output of any length, given in bytes.
0109   /// This doesn't modify the hasher itself, and it's possible to finalize again
0110   /// after adding more input.
0111   BLAKE3Result<NumBytes> final() { return BLAKE3::final<NumBytes>(); }
0112 
0113   /// Return the current output for the digested data since the last call to
0114   /// init().
0115   ///
0116   /// Other hash functions distinguish between \p result() and \p final(), with
0117   /// \p result() allowing more calls into \p update(), but there's no
0118   // difference for the BLAKE3 hash function.
0119   BLAKE3Result<NumBytes> result() { return BLAKE3::result<NumBytes>(); }
0120 };
0121 
0122 } // namespace llvm
0123 
0124 #endif