Class Blake3

java.lang.Object
org.apache.commons.codec.digest.Blake3

public final class Blake3 extends Object
Implements the Blake3 algorithm providing a hash function with extensible output (XOF), a keyed hash function (MAC, PRF), and a key derivation function (KDF). Blake3 has a 128-bit security level and a default output length of 256 bits (32 bytes) which can extended up to 264 bytes.

Hashing

Hash mode calculates the same output hash given the same input bytes and can be used as both a message digest and and extensible output function.


      Blake3 hasher = Blake3.initHash();
      hasher.update("Hello, world!".getBytes(StandardCharsets.UTF_8));
      byte[] hash = new byte[32];
      hasher.doFinalize(hash);
 

Keyed Hashing

Keyed hashes take a 32-byte secret key and calculates a message authentication code on some input bytes. These also work as pseudo-random functions (PRFs) with extensible output similar to the extensible hash output. Note that Blake3 keyed hashes have the same performance as plain hashes; the key is used in initialization in place of a standard initialization vector used for plain hashing.


      SecureRandom random = SecureRandom.getInstanceStrong();
      byte[] key = new byte[32];
      random.nextBytes(key);
      Blake3 hasher = Blake3.initKeyedHash(key);
      hasher.update("Hello, Alice!".getBytes(StandardCharsets.UTF_8));
      byte[] mac = new byte[32];
      hasher.doFinalize(mac);
 

Key Derivation

A specific hash mode for deriving session keys and other derived keys in a unique key derivation context identified by some sequence of bytes. These context strings should be unique but do not need to be kept secret. Additional input data is hashed for key material which can be finalized to derive subkeys.


      String context = "org.apache.commons.codec.digest.Blake3Example";
      byte[] sharedSecret = ...;
      byte[] senderId = ...;
      byte[] recipientId = ...;
      Blake3 kdf = Blake3.initKeyDerivationFunction(context.getBytes(StandardCharsets.UTF_8));
      kdf.update(sharedSecret);
      kdf.update(senderId);
      kdf.update(recipientId);
      byte[] txKey = new byte[32];
      byte[] rxKey = new byte[32];
      kdf.doFinalize(txKey);
      kdf.doFinalize(rxKey);
 

Adapted from the ISC-licensed O(1) Cryptography library by Matt Sicker and ported from the reference public domain implementation by Jack O'Connor.

Since:
1.16
See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private static class 
     
    private static class 
     
    private static class 
    Represents the state just prior to either producing an eight word chaining value or any number of output bytes when the ROOT flag is set.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final int
     
    private static final int
     
    private static final int
     
    private static final int
     
    private static final int
     
    private static final int
     
    private static final int
     
    private static final int
     
    private final Blake3.EngineState
     
    private static final int[]
    Standard hash key used for plain hashes; same initialization vector as Blake2s.
    private static final int
     
    private static final int
     
    private static final int
     
    private static final byte[][]
    Pre-permuted for all 7 rounds; the second row (2,6,3,...) indicates the base permutation.
    private static final int
     
    private static final int
     
    private static final int
     
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Blake3(int[] key, int flags)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    private static void
    checkBufferArgs(byte[] buffer, int offset, int length)
     
    private static int[]
    compress(int[] chainingValue, int[] blockWords, int blockLength, long counter, int flags)
     
    doFinalize(byte[] out)
    Finalizes hash output data that depends on the sequence of updated bytes preceding this invocation and any previously finalized bytes.
    doFinalize(byte[] out, int offset, int length)
    Finalizes an arbitrary number of bytes into the provided output array that depends on the sequence of previously updated and finalized bytes.
    byte[]
    doFinalize(int nrBytes)
    Squeezes and returns an arbitrary number of bytes dependent on the sequence of previously absorbed and squeezed bytes.
    private static void
    g(int[] state, int a, int b, int c, int d, int mx, int my)
    The mixing function, G, which mixes either a column or a diagonal.
    static byte[]
    hash(byte[] data)
    Calculates the Blake3 hash of the provided data.
    static Blake3
    Constructs a fresh Blake3 hash function.
    static Blake3
    initKeyDerivationFunction(byte[] kdfContext)
    Constructs a fresh Blake3 key derivation function using the provided key derivation context byte string.
    static Blake3
    initKeyedHash(byte[] key)
    Constructs a fresh Blake3 keyed hash function.
    static byte[]
    keyedHash(byte[] key, byte[] data)
    Calculates the Blake3 keyed hash (MAC) of the provided data.
    private static void
    packInt(int value, byte[] dst, int off, int len)
     
    private static int[]
    parentChainingValue(int[] leftChildCV, int[] rightChildCV, int[] key, int flags)
     
    private static Blake3.Output
    parentOutput(int[] leftChildCV, int[] rightChildCV, int[] key, int flags)
     
    Resets this instance back to its initial state when it was first constructed.
    private static void
    round(int[] state, int[] msg, byte[] schedule)
     
    private static int
    unpackInt(byte[] buf, int off)
     
    private static int[]
    unpackInts(byte[] buf, int nrInts)
     
    update(byte[] in)
    Updates this hash state using the provided bytes.
    update(byte[] in, int offset, int length)
    Updates this hash state using the provided bytes at an offset.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

    • Blake3

      private Blake3(int[] key, int flags)
  • Method Details

    • reset

      public Blake3 reset()
      Resets this instance back to its initial state when it was first constructed.
      Returns:
      this
    • update

      public Blake3 update(byte[] in)
      Updates this hash state using the provided bytes.
      Parameters:
      in - source array to update data from
      Returns:
      this
      Throws:
      NullPointerException - if in is null
    • update

      public Blake3 update(byte[] in, int offset, int length)
      Updates this hash state using the provided bytes at an offset.
      Parameters:
      in - source array to update data from
      offset - where in the array to begin reading bytes
      length - number of bytes to update
      Returns:
      this
      Throws:
      NullPointerException - if in is null
      IndexOutOfBoundsException - if offset or length are negative or if offset + length is greater than the length of the provided array
    • doFinalize

      public Blake3 doFinalize(byte[] out)
      Finalizes hash output data that depends on the sequence of updated bytes preceding this invocation and any previously finalized bytes. Note that this can finalize up to 264 bytes per instance.
      Parameters:
      out - destination array to finalize bytes into
      Returns:
      this
      Throws:
      NullPointerException - if out is null
    • doFinalize

      public Blake3 doFinalize(byte[] out, int offset, int length)
      Finalizes an arbitrary number of bytes into the provided output array that depends on the sequence of previously updated and finalized bytes. Note that this can finalize up to 264 bytes per instance.
      Parameters:
      out - destination array to finalize bytes into
      offset - where in the array to begin writing bytes to
      length - number of bytes to finalize
      Returns:
      this
      Throws:
      NullPointerException - if out is null
      IndexOutOfBoundsException - if offset or length are negative or if offset + length is greater than the length of the provided array
    • doFinalize

      public byte[] doFinalize(int nrBytes)
      Squeezes and returns an arbitrary number of bytes dependent on the sequence of previously absorbed and squeezed bytes.
      Parameters:
      nrBytes - number of bytes to finalize
      Returns:
      requested number of finalized bytes
      Throws:
      IllegalArgumentException - if nrBytes is negative
    • initHash

      public static Blake3 initHash()
      Constructs a fresh Blake3 hash function. The instance returned functions as an arbitrary length message digest.
      Returns:
      fresh Blake3 instance in hashed mode
    • initKeyedHash

      public static Blake3 initKeyedHash(byte[] key)
      Constructs a fresh Blake3 keyed hash function. The instance returned functions as a pseudorandom function (PRF) or as a message authentication code (MAC).
      Parameters:
      key - 32-byte secret key
      Returns:
      fresh Blake3 instance in keyed mode using the provided key
      Throws:
      NullPointerException - if key is null
      IllegalArgumentException - if key is not 32 bytes
    • initKeyDerivationFunction

      public static Blake3 initKeyDerivationFunction(byte[] kdfContext)
      Constructs a fresh Blake3 key derivation function using the provided key derivation context byte string. The instance returned functions as a key-derivation function which can further absorb additional context data before squeezing derived key data.
      Parameters:
      kdfContext - a globally unique key-derivation context byte string to separate key derivation contexts from each other
      Returns:
      fresh Blake3 instance in key derivation mode
      Throws:
      NullPointerException - if kdfContext is null
    • hash

      public static byte[] hash(byte[] data)
      Calculates the Blake3 hash of the provided data.
      Parameters:
      data - source array to absorb data from
      Returns:
      32-byte hash squeezed from the provided data
      Throws:
      NullPointerException - if data is null
    • keyedHash

      public static byte[] keyedHash(byte[] key, byte[] data)
      Calculates the Blake3 keyed hash (MAC) of the provided data.
      Parameters:
      key - 32-byte secret key
      data - source array to absorb data from
      Returns:
      32-byte mac squeezed from the provided data
      Throws:
      NullPointerException - if key or data are null
    • checkBufferArgs

      private static void checkBufferArgs(byte[] buffer, int offset, int length)
    • packInt

      private static void packInt(int value, byte[] dst, int off, int len)
    • unpackInt

      private static int unpackInt(byte[] buf, int off)
    • unpackInts

      private static int[] unpackInts(byte[] buf, int nrInts)
    • g

      private static void g(int[] state, int a, int b, int c, int d, int mx, int my)
      The mixing function, G, which mixes either a column or a diagonal.
    • round

      private static void round(int[] state, int[] msg, byte[] schedule)
    • compress

      private static int[] compress(int[] chainingValue, int[] blockWords, int blockLength, long counter, int flags)
    • parentOutput

      private static Blake3.Output parentOutput(int[] leftChildCV, int[] rightChildCV, int[] key, int flags)
    • parentChainingValue

      private static int[] parentChainingValue(int[] leftChildCV, int[] rightChildCV, int[] key, int flags)