// derives a subkey from ctx and srcKey. ctx should be hardcoded, // globally unique, and application-specific. A good format for ctx strings is: // // [application] [commit timestamp] [purpose] // // e.g.: // // example.com 2019-12-25 16:18:03 session tokens v1 // // The purpose of these requirements is to ensure that an attacker cannot trick // two different applications into using the same context string. internal unsafe PBKDFBlake3NotBuiltIn(byte[] srcKey, byte[] ctx) { if (srcKey == null) { throw new ArgumentNullException(nameof(srcKey)); } if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } _srcKey = ArrayUtils.Clone(srcKey); var ivWords = ArrayUtils.Clone(Blake3.IV); // construct the derivation Hasher and get the derivationIV var derivationIv = new Blake3(derivationIVLen, ivWords, flagDeriveKeyContext) .ComputeBytes(ctx).GetBytes(); fixed(byte *srcPtr = derivationIv) { fixed(uint *destPtr = ivWords) { Converters.le32_copy(srcPtr, 0, destPtr, 0, Blake3.KeyLengthInBytes); } } _xof = new Blake3XOF(32, ivWords, flagDeriveKeyMaterial); }
// derives a subkey from ctx and srcKey. ctx should be hardcoded, // globally unique, and application-specific. A good format for ctx strings is: // // [application] [commit timestamp] [purpose] // // e.g.: // // example.com 2019-12-25 16:18:03 session tokens v1 // // The purpose of these requirements is to ensure that an attacker cannot trick // two different applications into using the same context string. internal unsafe PBKDF_Blake3NotBuiltInAdapter(byte[] srcKey, byte[] ctx) { if (srcKey == null) { throw new ArgumentNullHashLibException(nameof(srcKey)); } if (ctx == null) { throw new ArgumentNullHashLibException(nameof(ctx)); } SrcKey = srcKey.DeepCopy(); UInt32[] ivWords = Blake3.IV.DeepCopy(); // construct the derivation Hasher and get the derivationIV var derivationIv = new Blake3(derivationIVLen, ivWords, flagDeriveKeyContext) .ComputeBytes(ctx).GetBytes(); fixed(byte *srcPtr = derivationIv) { fixed(UInt32 *destPtr = ivWords) { Converters.le32_copy((IntPtr)srcPtr, 0, (IntPtr)destPtr, 0, Blake3.KeyLengthInBytes); } } Xof = new Blake3XOF(32, ivWords, flagDeriveKeyMaterial); } // end cctr
} // end function CreateBlake2XB public static IHash CreateBlake3XOF(byte[] a_Key, UInt64 a_XofSizeInBits) { IXOF Xof = (Blake3XOF.CreateBlake3XOF(32, a_Key) as IXOF); Xof.XOFSizeInBits = a_XofSizeInBits; return(Xof as IHash); } // end function CreateBlake3XOF
} // end function CreateBlake2XS public static IHash CreateBlake2XB(IBlake2XBConfig a_Blake2XBConfig, UInt64 a_XofSizeInBits) { IXOF Xof = (new Blake2XB(a_Blake2XBConfig) as IXOF); Xof.XOFSizeInBits = a_XofSizeInBits; return(Xof as IHash); } // end function CreateBlake2XB
} // end function CreateCShake_128 public static IHash CreateCShake_256(byte[] AN, byte[] AS, UInt64 a_XofSizeInBits) { IXOF Xof = (new CShake_256(AN, AS) as IXOF); Xof.XOFSizeInBits = a_XofSizeInBits; return(Xof as IHash); } // end function CreateCShake_256
} // end function CreateShake_128 public static IHash CreateShake_256(UInt64 a_XofSizeInBits) { IXOF Xof = (new Shake_256() as IXOF); Xof.XOFSizeInBits = a_XofSizeInBits; return(Xof as IHash); } // end function CreateShake_256
public void TestXofShouldRaiseExceptionOnWriteAfterRead() { byte[] LKey = Converters.ConvertHexStringToBytes(RawKeyInHex); byte[] LCustomization = Converters.ConvertStringToBytes(CustomizationMessage, Encoding.UTF8); byte[] LData = Converters.ConvertHexStringToBytes(TestConstants.ZeroToThreeInHex); IXOF Hash = HashFactory.XOF.CreateKMAC128XOF(LKey, LCustomization, OutputSizeInBits) as IXOF; Assert.ThrowsException <InvalidOperationHashLibException>(() => CallShouldRaiseException(Hash)); }
protected void DoComputeKMACXOF(IXOF xofInstance, byte[] data) { var result = new byte[xofInstance.XofSizeInBits >> 3]; xofInstance.Initialize(); xofInstance.TransformBytes(data); xofInstance.DoOutput(result, 0, (ulong)result.Length); ActualString = Converters.ConvertBytesToHexString(result); AssertAreEqual(ExpectedString, ActualString); }
protected static unsafe void CallShouldRaiseException(IXOF XofInstance) { byte[] Output = new byte[XofInstance.XOFSizeInBits >> 3]; fixed(byte *bPtr = TestConstants.Bytesabcde) { IntPtr abcdePtr = (IntPtr)bPtr; XofInstance.Initialize(); XofInstance.TransformUntyped(abcdePtr, TestConstants.Bytesabcde.Length); XofInstance.DoOutput(ref Output, 0, (UInt64)Output.Length); // this call below should raise exception since we have already read from the Xof XofInstance.TransformUntyped(abcdePtr, TestConstants.Bytesabcde.Length); } // } //
public void TestXofShouldRaiseExceptionOnWriteAfterRead() { IXOF Hash = hash as IXOF; Assert.ThrowsException <InvalidOperationHashLibException>(() => CallShouldRaiseException(Hash)); }