public async Task <object> HandleResponseAsync(HttpResponseMessage response) { if (!response.IsSuccessStatusCode) { throw new HttpResponseException(response); } blobSizeListener(response.Content.Headers.ContentLength ?? 0); using (Stream outputStream = new NotifyingOutputStream(destinationOutputStream, writtenByteCountListener, true)) { BlobDescriptor receivedBlobDescriptor; using (Stream contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) { receivedBlobDescriptor = await Digests.ComputeDigestAsync(contentStream, outputStream).ConfigureAwait(false); } if (!blobDigest.Equals(receivedBlobDescriptor.GetDigest())) { throw new UnexpectedBlobDigestException( "The pulled BLOB has digest '" + receivedBlobDescriptor.GetDigest() + "', but the request digest was '" + blobDigest + "'"); } } return(null); }
public async Task <DescriptorDigest> HandleSuccessResponseAsync(HttpResponseMessage response) { // Checks if the image digest is as expected. DescriptorDigest expectedDigest = await Digests.ComputeJsonDigestAsync(manifestTemplate).ConfigureAwait(false); if (response.Headers.TryGetValues(RESPONSE_DIGEST_HEADER, out var receivedDigestEnum)) { var receivedDigests = receivedDigestEnum.ToList(); if (receivedDigests.Count == 1) { try { if (expectedDigest.Equals(DescriptorDigest.FromDigest(receivedDigests[0]))) { return(expectedDigest); } } catch (DigestException) { // Invalid digest. } } eventHandlers.Dispatch( LogEvent.Warn(MakeUnexpectedImageDigestWarning(expectedDigest, receivedDigests))); return(expectedDigest); } eventHandlers.Dispatch( LogEvent.Warn(MakeUnexpectedImageDigestWarning(expectedDigest, Array.Empty <string>()))); // The received digest is not as expected. Warns about this. return(expectedDigest); }
/// <summary> /// Builds a parameter set from an encoded input stream /// </summary> /// /// <param name="ParamStream">Stream containing a parameter set</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception> public NTRUParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); _oId = new byte[OID_SIZE]; reader.Read(_oId, 0, _oId.Length); _N = reader.ReadInt32(); _Q = reader.ReadInt32(); _DF = reader.ReadInt32(); _DF1 = reader.ReadInt32(); _DF2 = reader.ReadInt32(); _DF3 = reader.ReadInt32(); _Db = reader.ReadInt32(); _Dm0 = reader.ReadInt32(); _maxM1 = reader.ReadInt32(); _cBits = reader.ReadInt32(); _minIGFHashCalls = reader.ReadInt32(); _minMGFHashCalls = reader.ReadInt32(); _hashSeed = reader.ReadBoolean(); _sparseMode = reader.ReadBoolean(); _fastFp = reader.ReadBoolean(); _polyType = (TernaryPolynomialType)reader.ReadInt32(); _dgtEngineType = (Digests)reader.ReadInt32(); _rndEngineType = (Prngs)reader.ReadInt32(); Initialize(); } catch (Exception ex) { throw new CryptoAsymmetricException("NTRUParameters:CTor", "The stream could not be read!", ex); } }
/// <summary> /// Get the digest engine /// </summary> /// /// <param name="Engine">Engine type</param> /// /// <returns>Instance of digest</returns> private IDigest GetDigest(Digests Engine) { switch (Engine) { case Digests.Blake256: return(new Blake256()); case Digests.Blake512: return(new Blake512()); case Digests.Keccak256: return(new Keccak256()); case Digests.Keccak512: return(new Keccak512()); case Digests.SHA256: return(new SHA256()); case Digests.SHA512: return(new SHA512()); case Digests.Skein256: return(new Skein256()); case Digests.Skein512: return(new Skein512()); default: throw new RLWEException("RLWESign:GetDigest", "The digest type is not unsupported!", new ArgumentException()); } }
/// <summary> /// Constructs a parameter set that uses product-form private keys (i.e. <c>PolyType=PRODUCT</c>). /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The NTRU family must be <c>2</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="N">N number of polynomial coefficients</param> /// <param name="Q">The big Q Modulus</param> /// <param name="Df1">Number of ones in the private polynomial <c>f1</c></param> /// <param name="Df2">Number of ones in the private polynomial <c>f2</c></param> /// <param name="Df3">Number of ones in the private polynomial <c>f3</c></param> /// <param name="Dm0">Minimum acceptable number of -1's, 0's, and 1's in the polynomial <c>m'</c> in the last encryption step</param> /// <param name="MaxM1">Maximum absolute value of mTrin.sumCoeffs() or zero to disable this check. Values greater than zero cause the constant coefficient of the message to always be zero.</param> /// <param name="Db">Number of random bits to prepend to the message; should be a multiple of 8</param> /// <param name="CBits">The number of bits in candidate for deriving an index in IGF-2</param> /// <param name="MinIGFHashCalls">Minimum number of hash calls for the IGF to make</param> /// <param name="MinMGFHashCalls">Minimum number of calls to generate the masking polynomial</param> /// <param name="HashSeed">Whether to hash the seed in the MGF first (true) or use the seed directly (false)</param> /// <param name="Sparse">Whether to treat ternary polynomials as sparsely populated SparseTernaryPolynomial vs DenseTernaryPolynomial</param> /// <param name="FastFp">Whether <c>F=1+p*F</c> for a ternary <c>F</c> (true) or <c>F</c> is ternary (false)</param> /// <param name="Digest">The Message Digest engine to use; default is SHA512</param> /// <param name="Random">The pseudo random generator engine to use; default is CTRPrng</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Oid format is invalid</exception> public NTRUParameters(byte[] OId, int N, int Q, int Df1, int Df2, int Df3, int Dm0, int MaxM1, int Db, int CBits, int MinIGFHashCalls, int MinMGFHashCalls, bool HashSeed, bool Sparse, bool FastFp, Digests Digest = Digests.SHA512, Prngs Random = Prngs.CTRPrng) { if (OId.Length != OID_SIZE) { throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); } if (OId[0] != (byte)AsymmetricEngines.NTRU) { throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.NTRU, new ArgumentException())); } Array.Copy(OId, this.OId, Math.Min(OId.Length, OID_SIZE)); _N = N; _Q = Q; _DF1 = Df1; _DF2 = Df2; _DF3 = Df3; _Db = Db; _Dm0 = Dm0; _maxM1 = MaxM1; _cBits = CBits; _minIGFHashCalls = MinIGFHashCalls; _minMGFHashCalls = MinMGFHashCalls; _hashSeed = HashSeed; _sparseMode = Sparse; _fastFp = FastFp; _polyType = TernaryPolynomialType.PRODUCT; _dgtEngineType = Digest; _rndEngineType = Random; Initialize(); }
private void Dispose(bool Disposing) { if (!m_isDisposed && Disposing) { try { if (m_oId != null) { Array.Clear(m_oId, 0, m_oId.Length); m_oId = null; } m_N = 0; m_M = 0; m_T = 0; m_fieldPoly = 0; m_cca2Engine = CCA2Ciphers.Fujisaki; m_dgtEngineType = Digests.SHA256; m_rndEngineType = Prngs.CTRPrng; } finally { m_isDisposed = true; } } }
/// <summary> /// Get a Digest instance by name /// </summary> /// /// <param name="DigestType">The message digest enumeration name</param> /// /// <returns>An initialized digest</returns> /// /// <exception cref="CryptoProcessingException">Thrown if the enumeration name is not supported</exception> public static IDigest GetInstance(Digests DigestType) { switch (DigestType) { case Digests.Blake256: return new Blake256(); case Digests.Blake512: return new Blake512(); case Digests.Keccak256: return new Keccak256(); case Digests.Keccak512: return new Keccak512(); case Digests.SHA256: return new SHA256(); case Digests.SHA512: return new SHA512(); case Digests.Skein256: return new Skein256(); case Digests.Skein512: return new Skein512(); case Digests.Skein1024: return new Skein1024(); default: throw new CryptoProcessingException("DigestFromName:GetInstance", "The digest is not recognized!"); } }
/// <summary> /// Reads a parameter set from an input stream /// </summary> /// /// <param name="CipherParams">Stream containing a parameter set</param> public NTRUParameters(Stream CipherParams) { try { BinaryReader reader = new BinaryReader(CipherParams); _N = reader.ReadInt32(); _Q = reader.ReadInt32(); _DF = reader.ReadInt32(); _DF1 = reader.ReadInt32(); _DF2 = reader.ReadInt32(); _DF3 = reader.ReadInt32(); _Db = reader.ReadInt32(); _Dm0 = reader.ReadInt32(); _maxM1 = reader.ReadInt32(); _cBits = reader.ReadInt32(); _minIGFHashCalls = reader.ReadInt32(); _minMGFHashCalls = reader.ReadInt32(); _hashSeed = reader.ReadBoolean(); _oId = new byte[3]; reader.Read(_oId, 0, _oId.Length); _sparseMode = reader.ReadBoolean(); _fastFp = reader.ReadBoolean(); _polyType = (TernaryPolynomialType)reader.ReadInt32(); _messageDigest = (Digests)reader.ReadInt32(); _randomEngine = (Prngs)reader.ReadInt32(); Initialize(); } catch (Exception ex) { throw new NTRUException("NTRUParameters:CTor", "The stream could not be read!", ex); } }
private IDigest GetKeyEngine(Digests KeyEngine) { switch (KeyEngine) { case Digests.Blake256: return(new Blake256()); case Digests.Blake512: return(new Blake512()); case Digests.Keccak256: return(new Keccak256()); case Digests.Keccak512: return(new Keccak512()); case Digests.SHA256: return(new SHA256()); case Digests.SHA512: return(new SHA512()); case Digests.Skein256: return(new Skein256()); case Digests.Skein512: return(new Skein512()); case Digests.Skein1024: return(new Skein1024()); default: throw new CryptoSymmetricException("THX:GetKeyEngine", "The digest type is not supported!", new ArgumentException()); } }
public Digests Digests; // [NumPackStreams] public PackInfo() { PackPos = 0; NumPackStreams = 0; Sizes = new ulong[0]; Digests = new Digests(0); }
public async Task <BuildResult> CallAsync() { IReadOnlyList <BlobDescriptor> baseImageDescriptors = await pushBaseImageLayersStep.GetFuture().ConfigureAwait(false); IReadOnlyList <BlobDescriptor> appLayerDescriptors = await pushApplicationLayersStep.GetFuture().ConfigureAwait(false); BlobDescriptor containerConfigurationBlobDescriptor = await pushContainerConfigurationStep.GetFuture().ConfigureAwait(false); ImmutableHashSet <string> targetImageTags = buildConfiguration.GetAllTargetImageTags(); using (var progressEventDispatcher = progressEventDispatcherFactory.Create("pushing image manifest", this.Index)) using (var factory = progressEventDispatcher.NewChildProducer()("[child progress]pushing image manifest", targetImageTags.Count)) using (TimerEventDispatcher ignored = new TimerEventDispatcher(buildConfiguration.GetEventHandlers(), DESCRIPTION)) { RegistryClient registryClient = buildConfiguration .NewTargetImageRegistryClientFactory() .SetAuthorization(await authenticatePushStep.GetFuture().ConfigureAwait(false)) .NewRegistryClient(); // Constructs the image. ImageToJsonTranslator imageToJsonTranslator = new ImageToJsonTranslator(await buildImageStep.GetFuture().ConfigureAwait(false)); // Gets the image manifest to push. IBuildableManifestTemplate manifestTemplate = imageToJsonTranslator.GetManifestTemplate( buildConfiguration.GetTargetFormat(), containerConfigurationBlobDescriptor); // Pushes to all target image tags. IList <Task <DescriptorDigest> > pushAllTagsFutures = new List <Task <DescriptorDigest> >(); var idx = 0; ProgressEventDispatcher.Factory progressEventDispatcherFactory = factory.NewChildProducer(); foreach (string tag in targetImageTags) { idx++; using (progressEventDispatcherFactory.Create("tagging with " + tag, idx)) { buildConfiguration.GetEventHandlers().Dispatch(LogEvent.Info("Tagging with " + tag + "...")); pushAllTagsFutures.Add(registryClient.PushManifestAsync(manifestTemplate, tag)); } } DescriptorDigest imageDigest = await Digests.ComputeJsonDigestAsync(manifestTemplate).ConfigureAwait(false); DescriptorDigest imageId = containerConfigurationBlobDescriptor.GetDigest(); BuildResult result = new BuildResult(imageDigest, imageId); await Task.WhenAll(pushAllTagsFutures).ConfigureAwait(false); return(result); } }
/// <summary> /// Initialize the class and generators /// </summary> /// <param name="SeedEngine">The <see cref="Prngs">Prng</see> that supplies the key and seed material to the hash function</param> /// <param name="HashEngine">The <see cref="Digests">Digest</see> type used to create the pseudo random keying material</param> public KeyGenerator(Prngs SeedEngine, Digests HashEngine) { this.SeedEngine = SeedEngine; this.HashEngine = HashEngine; // initialize the generators Reset(); }
public async Task TestGenerateSelectorAsync() { DescriptorDigest expectedSelector = await Digests.ComputeJsonDigestAsync(ToLayerEntryTemplates(inOrderLayerEntries)).ConfigureAwait(false); Assert.AreEqual( expectedSelector, await GenerateSelectorAsync(outOfOrderLayerEntries).ConfigureAwait(false)); }
/** * * Calulates the keyidentifier using a SHA1 hash over the BIT STRING * from SubjectPublicKeyInfo as defined in RFC2459. * * Example of making a AuthorityKeyIdentifier: * <pre> * SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream( * publicKey.getEncoded()).readObject()); * AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki); * </pre> * **/ public AuthorityKeyIdentifier( SubjectPublicKeyInfo spki) { byte[] bytes = spki.PublicKeyData.GetBytes(); byte[] resBuf = Digests.DoFinal(new Sha1Digest(), bytes, 0, bytes.Length); this.keyidentifier = new DerOctetString(resBuf); }
/// <summary> /// Initialize this class using the message digests enumeration name /// </summary> /// /// <param name="DigestType">The message digest enumeration name</param> public HKDF(Digests DigestType) { IDigest digest = Helper.DigestFromName.GetInstance(DigestType); m_disposeEngine = true; m_kdfMac = new HMAC(digest); m_hashSize = digest.DigestSize; }
public async Task TestGenerateSelector_emptyAsync() { DescriptorDigest expectedSelector = await Digests.ComputeJsonDigestAsync(ImmutableArray.Create <object>()).ConfigureAwait(false); Assert.AreEqual( expectedSelector, await GenerateSelectorAsync(ImmutableArray.Create <LayerEntry>()).ConfigureAwait(false)); }
/// <summary> /// <para>Initializes the class with default generators; SHA-2 512, and RNGCryptoServiceProvider</para> /// </summary> public KeyGenerator() { // default engines SeedEngine = Prngs.CSPRng; HashEngine = Digests.SHA512; // initialize the generators Reset(); }
private void DigestTest(Digests DigestType, string Path, bool Parallel = false) { int hashSize = DigestFromName.GetDigestSize(DigestType); using (StreamReader r = new StreamReader(Path)) { string line; while ((line = r.ReadLine()) != null) { if (line.Contains(DMK_INP)) { byte[] input = new byte[0]; byte[] expect = new byte[hashSize]; byte[] key = new byte[0]; byte[] hash = new byte[hashSize]; int sze = DMK_INP.Length; if (line.Length - sze > 0) { input = HexConverter.Decode(line.Substring(sze, line.Length - sze)); } line = r.ReadLine(); sze = DMK_KEY.Length; if (line.Length - sze > 0) { key = HexConverter.Decode(line.Substring(sze, line.Length - sze)); } line = r.ReadLine(); sze = DMK_HSH.Length; if (line.Length - sze > 0) { expect = HexConverter.Decode(line.Substring(sze, line.Length - sze)); } IDigest dgt = DigestFromName.GetInstance(DigestType, Parallel); if (dgt.Enumeral == Digests.Blake2B512) { ((Blake2B512)dgt).LoadMacKey(new MacParams(key)); } else { ((Blake2S256)dgt).LoadMacKey(new MacParams(key)); } hash = dgt.ComputeHash(input); //16,235 if (Evaluate.AreEqual(hash, expect) == false) { throw new Exception("Blake2: Expected hash is not equal!"); } } } } }
/// <summary> /// Set the default parameters: extension degree /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The McEliece family must be <c>1</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="CCA2Engine">The McEliece CCA2 cipher engine</param> /// <param name="Digest">The digest used by the cipher engine</param> /// <param name="Prng">The prng used by the cipher engine</param> public MPKCParameters(byte[] OId, CCA2Ciphers CCA2Engine = CCA2Ciphers.Fujisaki, Digests Digest = Digests.SHA256, Prngs Prng = Prngs.CTRPrng) : this(OId, DEFAULT_M, DEFAULT_T) { this.Digest = Digest; this.CCA2Engine = CCA2Engine; this.RandomEngine = Prng; }
private IDigest GetKeyEngine(Digests KeyEngine) { switch (KeyEngine) { case Digests.Blake256: return new Blake256(); case Digests.Blake512: return new Blake512(); case Digests.Keccak256: return new Keccak256(); case Digests.Keccak512: return new Keccak512(); case Digests.SHA256: return new SHA256(); case Digests.SHA512: return new SHA512(); case Digests.Skein256: return new Skein256(); case Digests.Skein512: return new Skein512(); case Digests.Skein1024: return new Skein1024(); default: throw new CryptoSymmetricException("RSM:GetKeyEngine", "The digest type is not supported!", new ArgumentException()); } }
/// <summary> /// Builds a parameter set from an encoded input stream /// </summary> /// /// <param name="ParamStream">Stream containing a parameter set</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception> public MPKCParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); _oId = reader.ReadBytes(OID_SIZE); _cca2Engine = (CCA2Ciphers)reader.ReadInt32(); _dgtEngineType = (Digests)reader.ReadInt32(); _rndEngineType = (Prngs)reader.ReadInt32(); _M = reader.ReadInt32(); _T = reader.ReadInt32(); _fieldPoly = reader.ReadInt32(); _N = 1 << M; } catch (Exception ex) { throw new CryptoAsymmetricException("MPKCParameters:CTor", "The stream could not be read!", ex); } }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { if (_oId != null) { Array.Clear(_oId, 0, _oId.Length); _oId = null; } _N = 0; _M = 0; _T = 0; _fieldPoly = 0; _cca2Engine = CCA2Ciphers.Fujisaki; _dgtEngineType = Digests.SHA256; _rndEngineType = Prngs.CTRPrng; } finally { _isDisposed = true; } } }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="CipherParams">The McEliece cipher used to encrypt the hash</param> /// <param name="Digest">The type of digest engine used</param> public MPKCSign(MPKCParameters CipherParams, Digests Digest = Digests.SHA512) { _dgtEngine = GetDigest(CipherParams.Digest); _asyCipher = GetEngine(CipherParams); }
/// <summary> /// Initialize the class /// </summary> /// /// <param name="Rounds">Number of diffusion rounds. The <see cref="LegalRounds"/> property contains available sizes. Default is 32 rounds.</param> /// <param name="KeyEngine">The Key Schedule KDF digest engine; can be any one of the <see cref="Digests">Digest</see> implementations. The default engine is <see cref="SHA512"/>.</param> /// /// <exception cref="CryptoSymmetricException">Thrown if an invalid rounds count is chosen</exception> public SHX(int Rounds = ROUNDS32, Digests KeyEngine = Digests.SHA512) { if (Rounds != 32 && Rounds != 40 && Rounds != 48 && Rounds != 56 && Rounds != 64 && Rounds != 80 && Rounds != 96 && Rounds != 128) throw new CryptoSymmetricException("SHX:CTor", "Invalid rounds size! Sizes supported are 32, 40, 48, 56, 64, 80, 96 and 128.", new ArgumentOutOfRangeException()); // get the kdf digest engine _keyEngine = GetKeyEngine(KeyEngine); // set the hmac key size _ikmSize = _ikmSize == 0 ? _keyEngine.DigestSize : _ikmSize; for (int i = 0; i < _legalKeySizes.Length; i++) _legalKeySizes[i] = (_keyEngine.BlockSize * (i + 1)) + _ikmSize; _dfnRounds = Rounds; }
/// <summary> /// Copy Constructor /// </summary> /// /// <param name="PrivateKey">The GMSSPrivateKey to copy</param> private GMSSPrivateKey(GMSSPrivateKey PrivateKey) { _index = ArrayUtils.Clone(PrivateKey._index); _currentSeeds = GMSSUtil.Clone(PrivateKey._currentSeeds); _nextNextSeeds = GMSSUtil.Clone(PrivateKey._nextNextSeeds); _currentAuthPaths = GMSSUtil.Clone(PrivateKey._currentAuthPaths); _nextAuthPaths = GMSSUtil.Clone(PrivateKey._nextAuthPaths); _keep = GMSSUtil.Clone(PrivateKey._keep); _currentTreehash = PrivateKey._currentTreehash; _nextTreehash = PrivateKey._nextTreehash; _currentStack = PrivateKey._currentStack; _nextStack = PrivateKey._nextStack; _currentRetain = PrivateKey._currentRetain; _nextRetain = PrivateKey._nextRetain; _nextNextLeaf = PrivateKey._nextNextLeaf; //N _upperLeaf = PrivateKey._upperLeaf; //N _upperTreehashLeaf = PrivateKey._upperTreehashLeaf; //N _minTreehash = PrivateKey._minTreehash; //N _nextRoot = GMSSUtil.Clone(PrivateKey._nextRoot); _nextNextRoot = PrivateKey._nextNextRoot; //N _currentRootSig = PrivateKey._currentRootSig; _nextRootSig = PrivateKey._nextRootSig; //N _gmssPS = PrivateKey._gmssPS; _msgDigestType = PrivateKey._msgDigestType; _heightOfTrees = PrivateKey._heightOfTrees; _otsIndex = PrivateKey._otsIndex; _K = PrivateKey._K; _numLayer = PrivateKey._numLayer; _msgDigestTrees = PrivateKey._msgDigestTrees; _mdLength = PrivateKey._mdLength; _gmssRandom = PrivateKey._gmssRandom; _numLeafs = PrivateKey._numLeafs; }
/// <summary> /// /// </summary> /// /// <param name="Index">The tree indices</param> /// <param name="CurrentSeeds">A seed for the generation of private OTS keys for the current subtrees</param> /// <param name="NextNextSeeds">A seed for the generation of private OTS keys for the next subtrees</param> /// <param name="CurrentAuthPaths">Array of current authentication paths</param> /// <param name="NextAuthPaths">Array of next authentication paths</param> /// <param name="Keep">Keep array for the authPath algorithm</param> /// <param name="CurrentTreehash">Treehash for authPath algorithm of current tree</param> /// <param name="NextTreehash">Treehash for authPath algorithm of next tree (TREE+)</param> /// <param name="CurrentStack">Shared stack for authPath algorithm of current tree</param> /// <param name="NextStack">Shared stack for authPath algorithm of next tree (TREE+)</param> /// <param name="CurrentRetain">Retain stack for authPath algorithm of current tree</param> /// <param name="NextRetain">Retain stack for authPath algorithm of next tree (TREE+)</param> /// <param name="NextNextLeaf">Array of upcoming leafs of the tree after next (LEAF++) of each layer</param> /// <param name="UpperLeaf">Needed for precomputation of upper nodes</param> /// <param name="UpperTreehashLeaf">Needed for precomputation of upper treehash nodes</param> /// <param name="MinTreehash">Index of next treehash instance to receive an update</param> /// <param name="NextRoot">The roots of the next trees (ROOT+)</param> /// <param name="NextNextRoot">The roots of the tree after next (ROOT++)</param> /// <param name="CurrentRootSig">Array of signatures of the roots of the current subtrees (SIG)</param> /// <param name="NextRootSig">Array of signatures of the roots of the next subtree (SIG+)</param> /// <param name="ParameterSet">The GMSS Parameterset</param> /// <param name="Digest">The digest type</param> internal GMSSPrivateKey(int[] Index, byte[][] CurrentSeeds, byte[][] NextNextSeeds, byte[][][] CurrentAuthPaths, byte[][][] NextAuthPaths, byte[][][] Keep, Treehash[][] CurrentTreehash, Treehash[][] NextTreehash, List<byte[]>[] CurrentStack, List<byte[]>[] NextStack, List<byte[]>[][] CurrentRetain, List<byte[]>[][] NextRetain, GMSSLeaf[] NextNextLeaf, GMSSLeaf[] UpperLeaf, GMSSLeaf[] UpperTreehashLeaf, int[] MinTreehash, byte[][] NextRoot, GMSSRootCalc[] NextNextRoot, byte[][] CurrentRootSig, GMSSRootSig[] NextRootSig, GMSSParameters ParameterSet, Digests Digest) { _msgDigestType = Digest; // construct message digest _msgDigestTrees = GetDigest(Digest); _mdLength = _msgDigestTrees.DigestSize; // Parameter _gmssPS = ParameterSet; _otsIndex = ParameterSet.WinternitzParameter; _K = ParameterSet.K; _heightOfTrees = ParameterSet.HeightOfTrees; // initialize numLayer _numLayer = _gmssPS.NumLayers; // initialize index if null if (Index == null) { _index = new int[_numLayer]; for (int i = 0; i < _numLayer; i++) _index[i] = 0; } else { _index = Index; } _currentSeeds = CurrentSeeds; _nextNextSeeds = NextNextSeeds; _currentAuthPaths = CurrentAuthPaths; _nextAuthPaths = NextAuthPaths; // initialize keep if null if (Keep == null) { _keep = new byte[_numLayer][][]; for (int i = 0; i < _numLayer; i++) _keep[i] = ArrayUtils.CreateJagged<byte[][]>((int)Math.Floor((decimal)_heightOfTrees[i] / 2), _mdLength); } else { _keep = Keep; } // initialize stack if null if (CurrentStack == null) { _currentStack = new List<byte[]>[_numLayer]; for (int i = 0; i < _numLayer; i++) _currentStack[i] = new List<byte[]>(); } else { _currentStack = CurrentStack; } // initialize nextStack if null if (NextStack == null) { _nextStack = new List<byte[]>[_numLayer - 1]; for (int i = 0; i < _numLayer - 1; i++) _nextStack[i] = new List<byte[]>(); } else { _nextStack = NextStack; } _currentTreehash = CurrentTreehash; _nextTreehash = NextTreehash; _currentRetain = CurrentRetain; _nextRetain = NextRetain; _nextRoot = NextRoot; if (NextNextRoot == null) { NextNextRoot = new GMSSRootCalc[_numLayer - 1]; for (int i = 0; i < _numLayer - 1; i++) NextNextRoot[i] = new GMSSRootCalc(_heightOfTrees[i + 1], _K[i + 1], GetDigest(Digest)); } else { _nextNextRoot = NextNextRoot; } _currentRootSig = CurrentRootSig; // calculate numLeafs _numLeafs = new int[_numLayer]; for (int i = 0; i < _numLayer; i++) _numLeafs[i] = 1 << _heightOfTrees[i]; // construct PRNG _gmssRandom = new GMSSRandom(_msgDigestTrees); if (_numLayer > 1) { // construct the nextNextLeaf (LEAFs++) array for upcoming leafs in // tree after next (TREE++) if (NextNextLeaf == null) { _nextNextLeaf = new GMSSLeaf[_numLayer - 2]; for (int i = 0; i < _numLayer - 2; i++) _nextNextLeaf[i] = new GMSSLeaf(GetDigest(Digest), _otsIndex[i + 1], _numLeafs[i + 2], _nextNextSeeds[i]); } else { _nextNextLeaf = NextNextLeaf; } } else { _nextNextLeaf = new GMSSLeaf[0]; } // construct the upperLeaf array for upcoming leafs in tree over the // actual if (UpperLeaf == null) { _upperLeaf = new GMSSLeaf[_numLayer - 1]; for (int i = 0; i < _numLayer - 1; i++) _upperLeaf[i] = new GMSSLeaf(GetDigest(Digest), _otsIndex[i], _numLeafs[i + 1], _currentSeeds[i]); } else { _upperLeaf = UpperLeaf; } // construct the leafs for upcoming leafs in treehashs in tree over the actual if (UpperTreehashLeaf == null) { _upperTreehashLeaf = new GMSSLeaf[_numLayer - 1]; for (int i = 0; i < _numLayer - 1; i++) _upperTreehashLeaf[i] = new GMSSLeaf(GetDigest(Digest), _otsIndex[i], _numLeafs[i + 1]); } else { _upperTreehashLeaf = UpperTreehashLeaf; } if (MinTreehash == null) { _minTreehash = new int[_numLayer - 1]; for (int i = 0; i < _numLayer - 1; i++) _minTreehash[i] = -1; } else { _minTreehash = MinTreehash; } // construct the nextRootSig (RootSig++) byte[] dummy = new byte[_mdLength]; byte[] OTSseed = new byte[_mdLength]; if (NextRootSig == null) { _nextRootSig = new GMSSRootSig[_numLayer - 1]; for (int i = 0; i < _numLayer - 1; i++) { Array.Copy(CurrentSeeds[i], 0, dummy, 0, _mdLength); _gmssRandom.NextSeed(dummy); OTSseed = _gmssRandom.NextSeed(dummy); _nextRootSig[i] = new GMSSRootSig(GetDigest(Digest), _otsIndex[i], _heightOfTrees[i + 1]); _nextRootSig[i].InitSign(OTSseed, NextRoot[i]); } } else { _nextRootSig = NextRootSig; } }
/// <summary> /// Initialize the class /// </summary> /// /// <param name="DigestEngine">The digest that powers the rng (default is Keccak512)</param> /// <param name="SeedEngine">The Seed engine used to create the salt (default is CSPRsg)</param> /// <param name="BufferSize">The size of the internal state buffer in bytes; must be at least 128 bytes size (default is 1024)</param> /// /// <exception cref="CryptoRandomException">Thrown if the buffer size is too small</exception> public DGCPrng(Digests DigestEngine = Digests.Keccak512, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, int BufferSize = BUFFER_SIZE) { if (BufferSize < 128) throw new CryptoRandomException("DGCPrng:Ctor", "BufferSize must be at least 128 bytes!", new ArgumentException()); _digestType = DigestEngine; _seedType = SeedEngine; _byteBuffer = new byte[BufferSize]; _bufferSize = BufferSize; Reset(); }
/// <summary> /// SessionParams constructor /// </summary> /// /// <param name="EngineType">The Cryptographic <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.BlockCiphers">Engine</see> type</param> /// <param name="KeySize">The cipher Key Size in bytes</param> /// <param name="IvSize">Size of the cipher <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.IVSizes">Initialization Vector</see></param> /// <param name="RoundCount">The number of diffusion <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.RoundCounts">Rounds</see></param> /// <param name="KdfEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest</see> engine used to power the key schedule Key Derivation Function in HX and M series ciphers</param> /// /// <exception cref="System.ArgumentOutOfRangeException">Thrown if an invalid KeyId, MessageKey, or ExtensionKey is used</exception> public DtmSession(BlockCiphers EngineType = BlockCiphers.RDX, int KeySize = 32, IVSizes IvSize = IVSizes.V128, RoundCounts RoundCount = RoundCounts.R14, Digests KdfEngine = Digests.SHA512) { this.EngineType = (byte)EngineType; this.KeySize = (short)KeySize; this.IvSize = (byte)IvSize; this.RoundCount = (byte)RoundCount; this.KdfEngine = (byte)KdfEngine; }
/// <summary> /// Get the digest engine /// </summary> /// /// <param name="Digest">Engine type</param> /// /// <returns>Instance of digest</returns> private IDigest GetDigest(Digests Digest) { switch (Digest) { case Digests.Blake256: return new Blake256(); case Digests.Blake512: return new Blake512(); case Digests.Keccak256: return new Keccak256(); case Digests.Keccak512: return new Keccak512(); case Digests.Keccak1024: return new Keccak1024(); case Digests.SHA256: return new SHA256(); case Digests.SHA512: return new SHA512(); case Digests.Skein256: return new Skein256(); case Digests.Skein512: return new Skein512(); case Digests.Skein1024: return new Skein1024(); default: throw new CryptoAsymmetricException("NTRUKeyGenerator:GetDigest", "The digest type is not supported!", new ArgumentException()); } }
/// <summary> /// Initialize the class /// </summary> /// /// <param name="Rounds">Number of diffusion rounds. The <see cref="LegalRounds"/> property contains available sizes. Default is 18 rounds.</param> /// <param name="Block">Cipher input <see cref="BlockSize"/>. The <see cref="LegalBlockSizes"/> property contains available sizes. Default is 16 bytes.</param> /// <param name="KeyEngine">The Key Schedule KDF digest engine; can be any one of the <see cref="Digests">Digest</see> implementations. The default engine is <see cref="SHA512"/>.</param> /// /// <exception cref="CryptoSymmetricException">Thrown if an invalid block size or invalid rounds count are used</exception> public RSM(int Rounds = ROUNDS18, int Block = BLOCK16, Digests KeyEngine = Digests.SHA512) { if (Block != BLOCK16 && Block != BLOCK32) throw new CryptoSymmetricException("RSM:CTor", "Invalid block size! Supported block sizes are 16 and 32 bytes.", new ArgumentException()); if (Rounds != 10 && Rounds != 18 && Rounds != 26 && Rounds != 34 && Rounds != 42) throw new CryptoSymmetricException("RSM:CTor", "Invalid rounds size! Sizes supported are even numbers between 10, 18, 26, 34 and 42.", new ArgumentException()); // get the kdf digest engine _keyEngine = GetKeyEngine(KeyEngine); // set the hmac key size _ikmSize = _ikmSize == 0 ? _keyEngine.DigestSize : _ikmSize; for (int i = 0; i < _legalKeySizes.Length; i++) _legalKeySizes[i] = (_keyEngine.BlockSize * (i + 1)) + _ikmSize; _dfnRounds = Rounds; _blockSize = Block; }
/// <summary> /// Get the digest engine /// </summary> /// /// <param name="Engine">Engine type</param> /// /// <returns>Instance of digest</returns> private IDigest GetDigest(Digests Engine) { switch (Engine) { case Digests.Blake256: return new Blake256(); case Digests.Blake512: return new Blake512(); case Digests.Keccak256: return new Keccak256(); case Digests.Keccak512: return new Keccak512(); case Digests.Keccak1024: return new Keccak1024(); case Digests.SHA256: return new SHA256(); case Digests.SHA512: return new SHA512(); case Digests.Skein256: return new Skein256(); case Digests.Skein512: return new Skein512(); case Digests.Skein1024: return new Skein1024(); default: throw new ArgumentException("The digest type is not supported!"); } }
/// <summary> /// Constructs a parameter set that uses product-form private keys (i.e. <c>PolyType=PRODUCT</c>). /// </summary> /// /// <param name="N">N number of polynomial coefficients</param> /// <param name="Q">The big Q Modulus</param> /// <param name="Df1">Number of ones in the private polynomial <c>f1</c></param> /// <param name="Df2">Number of ones in the private polynomial <c>f2</c></param> /// <param name="Df3">Number of ones in the private polynomial <c>f3</c></param> /// <param name="Dm0">Minimum acceptable number of -1's, 0's, and 1's in the polynomial <c>m'</c> in the last encryption step</param> /// <param name="MaxM1">Maximum absolute value of mTrin.sumCoeffs() or zero to disable this check. Values greater than zero cause the constant coefficient of the message to always be zero.</param> /// <param name="Db">Number of random bits to prepend to the message; should be a multiple of 8</param> /// <param name="CBits">The number of bits in candidate for deriving an index in IGF-2</param> /// <param name="MinIGFHashCalls">Minimum number of hash calls for the IGF to make</param> /// <param name="MinMGFHashCalls">Minimum number of calls to generate the masking polynomial</param> /// <param name="HashSeed">Whether to hash the seed in the MGF first (true) or use the seed directly (false)</param> /// <param name="OId">Three bytes that uniquely identify the parameter set</param> /// <param name="Sparse">Whether to treat ternary polynomials as sparsely populated SparseTernaryPolynomial vs DenseTernaryPolynomial</param> /// <param name="FastFp">Whether <c>F=1+p*F</c> for a ternary <c>F</c> (true) or <c>F</c> is ternary (false)</param> /// <param name="Digest">The Message Digest engine to use; default is SHA512</param> /// <param name="Random">The pseudo random generator engine to use; default is CTRPrng</param> public NTRUParameters(int N, int Q, int Df1, int Df2, int Df3, int Dm0, int MaxM1, int Db, int CBits, int MinIGFHashCalls, int MinMGFHashCalls, bool HashSeed, byte[] OId, bool Sparse, bool FastFp, Digests Digest = Digests.SHA512, Prngs Random = Prngs.CTRPrng) { _N = N; _Q = Q; _DF1 = Df1; _DF2 = Df2; _DF3 = Df3; _Db = Db; _Dm0 = Dm0; _maxM1 = MaxM1; _cBits = CBits; _minIGFHashCalls = MinIGFHashCalls; _minMGFHashCalls = MinMGFHashCalls; _hashSeed = HashSeed; _sparseMode = Sparse; _fastFp = FastFp; _polyType = TernaryPolynomialType.PRODUCT; _messageDigest = Digest; _randomEngine = Random; this.OId = OId; Initialize(); }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The McEliece family must be <c>1</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="Keysize">The length of a Goppa code</param> /// <param name="CCA2Engine">The McEliece CCA2 cipher engine</param> /// <param name="Digest">The digest used by the cipher engine</param> /// <param name="Prng">The Prng used by the cipher</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the OId is invalid, or <c>keysize < 1</c></exception> public MPKCParameters(byte[] OId, int Keysize, CCA2Ciphers CCA2Engine = CCA2Ciphers.Fujisaki, Digests Digest = Digests.SHA256, Prngs Prng = Prngs.CTRPrng) { if (Keysize < 1) throw new CryptoAsymmetricException("MPKCParameters:Ctor", "The key size must be positive!", new ArgumentException()); if (OId.Length != OID_SIZE) throw new CryptoAsymmetricException("MPKCParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); if (OId[0] != (byte)AsymmetricEngines.McEliece) throw new CryptoAsymmetricException("MPKCParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.McEliece, new ArgumentException())); this.Digest = Digest; this.CCA2Engine = CCA2Engine; this.RandomEngine = Prng; Array.Copy(OId, this.OId, Math.Min(OId.Length, OID_SIZE)); _M = 0; _N = 1; while (_N < Keysize) { _N <<= 1; _M++; } _T = _N >> 1; _T /= _M; _fieldPoly = PolynomialRingGF2.GetIrreduciblePolynomial(_M); }
/// <summary> /// Get the digest engine /// </summary> /// /// <param name="Engine">Engine type</param> /// /// <returns>Instance of digest</returns> /// /// <exception cref="CryptoAsymmetricException">Thrown if the digest is unrecognized or unsupported</c></exception> private IDigest GetDigest(Digests Engine) { switch (Engine) { case Digests.Blake256: return new Blake256(); case Digests.Blake512: return new Blake512(); case Digests.Keccak256: return new Keccak256(); case Digests.Keccak512: return new Keccak512(); case Digests.SHA256: return new SHA256(); case Digests.SHA512: return new SHA512(); case Digests.Skein256: return new Skein256(); case Digests.Skein512: return new Skein512(); default: throw new CryptoAsymmetricException("MPKCSign:GetDigest", "The digest is unrecognized or unsupported!", new ArgumentException()); } }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The McEliece family must be <c>1</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="M">The degree of the finite field GF(2^m)</param> /// <param name="T">The error correction capability of the code</param> /// <param name="FieldPoly">The field polynomial</param> /// <param name="CCA2Engine">The McEliece CCA2 cipher engine</param> /// <param name="Digest">The digest used by the cipher engine</param> /// <param name="Prng">The Prng used by the cipher</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the OId is invalid or; <c>t < 0</c>, <c>t > n</c>, or <c>poly</c> is not an irreducible field polynomial</exception> public MPKCParameters(byte[] OId, int M, int T, int FieldPoly, CCA2Ciphers CCA2Engine = CCA2Ciphers.Fujisaki, Digests Digest = Digests.SHA256, Prngs Prng = Prngs.CTRPrng) { if (OId.Length != OID_SIZE) throw new CryptoAsymmetricException("MPKCParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); if (OId[0] != (byte)AsymmetricEngines.McEliece) throw new CryptoAsymmetricException("MPKCParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.McEliece, new ArgumentException())); if (M < 1) throw new CryptoAsymmetricException("MPKCParameters:Ctor", "M must be positive!", new ArgumentException()); if (M > 32) throw new CryptoAsymmetricException("MPKCParameters:Ctor", "M is too large!", new ArgumentOutOfRangeException()); _M = M; this.Digest = Digest; this.CCA2Engine = CCA2Engine; this.RandomEngine = Prng; Array.Copy(OId, this.OId, Math.Min(OId.Length, OID_SIZE)); _N = 1 << M; _T = T; if (T < 0) throw new CryptoAsymmetricException("MPKCParameters:Ctor", "T must be positive!", new ArgumentException()); if (T > N) throw new CryptoAsymmetricException("MPKCParameters:Ctor", "T must be less than n = 2^m!", new ArgumentOutOfRangeException()); if ((PolynomialRingGF2.Degree(FieldPoly) == M) && (PolynomialRingGF2.IsIrreducible(FieldPoly))) _fieldPoly = FieldPoly; else throw new CryptoAsymmetricException("MPKCParameters:Ctor", "Polynomial is not a field polynomial for GF(2^m)", new InvalidDataException()); }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="CiphersParams">The GMSSParameters instance containing the cipher settings</param> /// /// <exception cref="CryptoAsymmetricSignException">Thrown if a Prng that requires pre-initialization is specified; (wrong constructor)</exception> public GMSSKeyGenerator(GMSSParameters CiphersParams) { if (CiphersParams.RandomEngine == Prngs.PBPrng) throw new CryptoAsymmetricSignException("GMSSKeyGenerator:Ctor", "Passphrase based digest and CTR generators must be pre-initialized, use the other constructor!", new ArgumentException()); _gmssParams = CiphersParams; _msgDigestType = CiphersParams.DigestEngine; _rndEngineType = _gmssParams.RandomEngine; _msDigestTree = GetDigest(CiphersParams.DigestEngine); // construct randomizer _gmssRand = new GMSSRandom(_msDigestTree); // set mdLength _mdLength = _msDigestTree.DigestSize; // construct Random for initial seed generation _rndEngine = GetPrng(_rndEngineType); Initialize(); }
/// <summary> /// Use an initialized prng to generate the key; use this constructor with an Rng that requires pre-initialization, i.e. PBPrng /// </summary> /// /// <param name="CiphersParams">The GMSSParameters instance containing the cipher settings</param> /// <param name="RngEngine">An initialized random generator instance</param> public GMSSKeyGenerator(GMSSParameters CiphersParams, IRandom RngEngine) { _gmssParams = CiphersParams; _msgDigestType = CiphersParams.DigestEngine; _rndEngineType = _gmssParams.RandomEngine; _msDigestTree = GetDigest(CiphersParams.DigestEngine); // construct randomizer _gmssRand = new GMSSRandom(_msDigestTree); // set mdLength _mdLength = _msDigestTree.DigestSize; // construct Random for initial seed generation _rndEngine = RngEngine; Initialize(); }
/// <summary> /// Constructs a parameter set that uses product-form private keys (i.e. <c>PolyType=PRODUCT</c>). /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The NTRU family must be <c>2</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="N">N number of polynomial coefficients</param> /// <param name="Q">The big Q Modulus</param> /// <param name="Df1">Number of ones in the private polynomial <c>f1</c></param> /// <param name="Df2">Number of ones in the private polynomial <c>f2</c></param> /// <param name="Df3">Number of ones in the private polynomial <c>f3</c></param> /// <param name="Dm0">Minimum acceptable number of -1's, 0's, and 1's in the polynomial <c>m'</c> in the last encryption step</param> /// <param name="MaxM1">Maximum absolute value of mTrin.sumCoeffs() or zero to disable this check. Values greater than zero cause the constant coefficient of the message to always be zero.</param> /// <param name="Db">Number of random bits to prepend to the message; should be a multiple of 8</param> /// <param name="CBits">The number of bits in candidate for deriving an index in IGF-2</param> /// <param name="MinIGFHashCalls">Minimum number of hash calls for the IGF to make</param> /// <param name="MinMGFHashCalls">Minimum number of calls to generate the masking polynomial</param> /// <param name="HashSeed">Whether to hash the seed in the MGF first (true) or use the seed directly (false)</param> /// <param name="Sparse">Whether to treat ternary polynomials as sparsely populated SparseTernaryPolynomial vs DenseTernaryPolynomial</param> /// <param name="FastFp">Whether <c>F=1+p*F</c> for a ternary <c>F</c> (true) or <c>F</c> is ternary (false)</param> /// <param name="Digest">The Message Digest engine to use; default is SHA512</param> /// <param name="Random">The pseudo random generator engine to use; default is CTRPrng</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Oid format is invalid</exception> public NTRUParameters(byte[] OId, int N, int Q, int Df1, int Df2, int Df3, int Dm0, int MaxM1, int Db, int CBits, int MinIGFHashCalls, int MinMGFHashCalls, bool HashSeed, bool Sparse, bool FastFp, Digests Digest = Digests.SHA512, Prngs Random = Prngs.CTRPrng) { if (OId.Length != OID_SIZE) throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); if (OId[0] != (byte)AsymmetricEngines.NTRU) throw new CryptoAsymmetricException("NTRUParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.NTRU, new ArgumentException())); Array.Copy(OId, this.OId, Math.Min(OId.Length, OID_SIZE)); _N = N; _Q = Q; _DF1 = Df1; _DF2 = Df2; _DF3 = Df3; _Db = Db; _Dm0 = Dm0; _maxM1 = MaxM1; _cBits = CBits; _minIGFHashCalls = MinIGFHashCalls; _minMGFHashCalls = MinMGFHashCalls; _hashSeed = HashSeed; _sparseMode = Sparse; _fastFp = FastFp; _polyType = TernaryPolynomialType.PRODUCT; _dgtEngineType = Digest; _rndEngineType = Random; Initialize(); }
/// <summary> /// Initialize the class with a Seed; note: the same seed will produce the same random output /// </summary> /// /// <param name="Seed">The Seed bytes used to initialize the digest counter; (min. length is digest blocksize + 8)</param> /// <param name="DigestEngine">The digest that powers the rng (default is Keccak512)</param> /// <param name="BufferSize">The size of the internal state buffer in bytes; must be at least 128 bytes size (default is 1024)</param> /// /// <exception cref="CryptoRandomException">Thrown if the seed is null or buffer size is too small; (min. seed = digest blocksize + 8)</exception> public DGCPrng(byte[] Seed, Digests DigestEngine = Digests.Keccak512, int BufferSize = BUFFER_SIZE) { if (Seed == null) throw new CryptoRandomException("DGCPrng:Ctor", "Seed can not be null!", new ArgumentNullException()); if (GetMinimumSeedSize(DigestEngine) < Seed.Length) throw new CryptoRandomException("DGCPrng:Ctor", String.Format("The state seed is too small! must be at least {0} bytes", GetMinimumSeedSize(DigestEngine)), new ArgumentException()); if (BufferSize < 128) throw new CryptoRandomException("DGCPrng:Ctor", "BufferSize must be at least 128 bytes!", new ArgumentException()); _digestType = DigestEngine; _stateSeed = Seed; _byteBuffer = new byte[BufferSize]; _bufferSize = BufferSize; Reset(); }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { _N = 0; _Q = 0; _DF = 0; _DF1 = 0; _DF2 = 0; _DF3 = 0; _Db = 0; _Dm0 = 0; _maxM1 = 0; _cBits = 0; _minIGFHashCalls = 0; _minMGFHashCalls = 0; _hashSeed = false; _fastFp = false; _sparseMode = false; _dgtEngineType = Digests.SHA512; _rndEngineType = Prngs.CTRPrng; if (_oId != null) { Array.Clear(_oId, 0, _oId.Length); _oId = null; } } finally { _isDisposed = true; } } }
private IDigest GetDigest(Digests RngEngine) { switch (RngEngine) { case Digests.Blake256: return new Blake256(); case Digests.Blake512: return new Blake512(); case Digests.Keccak1024: return new Keccak1024(); case Digests.Keccak256: return new Keccak256(); case Digests.Keccak512: return new Keccak512(); case Digests.SHA256: return new SHA256(); case Digests.SHA512: return new SHA512(); case Digests.Skein1024: return new Skein1024(); case Digests.Skein256: return new Skein256(); case Digests.Skein512: return new Skein512(); default: return new SHA512(); } }
/// <summary> /// Get the digest instance /// </summary> /// /// <param name="Digest">The Digests enumeration member</param> /// /// <returns>The hash digest instance</returns> private IDigest GetDigest(Digests Digest) { switch (Digest) { case Digests.Blake256: return new Blake256(); case Digests.Blake512: return new Blake512(); case Digests.Keccak256: return new Keccak256(); case Digests.Keccak512: return new Keccak512(); case Digests.Keccak1024: return new Keccak1024(); case Digests.SHA256: return new SHA256(); case Digests.SHA512: return new SHA512(); case Digests.Skein256: return new Skein256(); case Digests.Skein512: return new Skein512(); case Digests.Skein1024: return new Skein1024(); default: throw new CryptoProcessingException("DtmKex:GetDigest", "The digest type is unknown!", new ArgumentException()); } }
private int GetMinimumSeedSize(Digests RngEngine) { int ctrLen = 8; switch (RngEngine) { case Digests.Blake256: return ctrLen + 32; case Digests.Blake512: return ctrLen + 64; case Digests.Keccak1024: return ctrLen + 72; case Digests.Keccak256: return ctrLen + 136; case Digests.Keccak512: return ctrLen + 72; case Digests.SHA256: return ctrLen + 64; case Digests.SHA512: return ctrLen + 128; case Digests.Skein1024: return ctrLen + 128; case Digests.Skein256: return ctrLen + 32; case Digests.Skein512: return ctrLen + 64; default: return ctrLen + 128; } }