/// <summary> /// Get a Prng instance with default initialization parameters /// </summary> /// /// <param name="PrngType">The Prng enumeration name</param> /// /// <returns>An initialized Prng</returns> /// /// <exception cref="CryptoProcessingException">Thrown if the enumeration name is not supported</exception> public static IRandom GetInstance(Prngs PrngType) { switch (PrngType) { case Prngs.CSPPrng: return(new CSPPrng()); case Prngs.CTRPrng: return(new CTRPrng()); case Prngs.SP20Prng: return(new SP20Prng()); case Prngs.DGCPrng: return(new DGCPrng()); case Prngs.BBSG: return(new BBSG()); case Prngs.CCG: return(new CCG()); case Prngs.MODEXPG: return(new MODEXPG()); case Prngs.QCG1: return(new QCG1()); case Prngs.QCG2: return(new QCG2()); default: throw new CryptoProcessingException("PrngFromName:GetInstance", "The specified PRNG type is unrecognized!"); } }
/// <summary> /// Get the cipher engine /// </summary> /// /// <param name="Prng">The Prng</param> /// /// <returns>An initialized prng</returns> private IRandom GetPrng(Prngs Prng) { switch (Prng) { case Prngs.CTRPrng: return(new CTRPrng()); case Prngs.SP20Prng: return(new SP20Prng()); case Prngs.DGCPrng: return(new DGCPrng()); case Prngs.CSPPrng: return(new CSPPrng()); case Prngs.BBSG: return(new BBSG()); case Prngs.CCG: return(new CCG()); case Prngs.MODEXPG: return(new MODEXPG()); case Prngs.QCG1: return(new QCG1()); case Prngs.QCG2: return(new QCG2()); default: throw new CryptoAsymmetricSignException("RNBWEncrypt:GetPrng", "The Prng type is not supported!", new ArgumentException()); } }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="OId">Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The Ring-LWE family must be <c>3</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="N">The number of coefficients</param> /// <param name="Q">The Q modulus</param> /// <param name="Sigma">The Sigma value</param> /// <param name="MFP">The number of random bytes to prepend to the message</param> /// <param name="Engine">The PRNG engine used to power Random Generation</param> /// <param name="PBDigest">The digest engine used to power a Passphrase Based Prng</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if <c>N</c>, or <c>Q</c>, or the Oid are invalid</exception> public RLWEParameters(byte[] OId, int N, int Q, double Sigma, int MFP = DEFAULT_MFP, Prngs Engine = Prngs.CTRPrng, Digests PBDigest = Digests.SHA512) { if (OId.Length != OID_SIZE) { throw new CryptoAsymmetricException("RLWEParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); } if (OId[0] != (byte)AsymmetricEngines.RingLWE) { throw new CryptoAsymmetricException("RLWEParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.RingLWE, new ArgumentException())); } if (N != 256 && N != 512) { throw new CryptoAsymmetricException("RLWEParameters:Ctor", "N is invalid (only 256 or 512 currently supported)!", new ArgumentOutOfRangeException()); } if (Q != 7681 && Q != 12289) { throw new CryptoAsymmetricException("RLWEParameters:Ctor", "Q is invalid (only 7681 or 12289 currently supported)!", new ArgumentOutOfRangeException()); } if (Sigma != 11.31 && Sigma != 12.18) { throw new CryptoAsymmetricException("RLWEParameters:Ctor", "Sigma is invalid (only 11.31 or 12.18 currently supported)!", new ArgumentOutOfRangeException()); } if (N == 256 && MFP > 16 || N == 512 && MFP > 32) { throw new CryptoAsymmetricException("RLWEParameters:Ctor", "MFP is invalid (forward padding can not be longer than half the maximum message size)!", new ArgumentOutOfRangeException()); } m_Sigma = Sigma; m_N = N; m_Q = Q; Array.Copy(OId, this.OId, Math.Min(OId.Length, OID_SIZE)); m_mFp = MFP; m_rndEngineType = Engine; m_dgtEngineType = PBDigest; }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="N">The number of coefficients</param> /// <param name="Q">The Q modulus</param> /// <param name="Sigma">The Sigma value</param> /// <param name="OId">Three bytes that uniquely identify the parameter set</param> /// <param name="MFP">The number of random bytes to prepend to the message</param> /// <param name="Engine">The PRNG engine used to power SecureRandom</param> /// /// <exception cref="RLWEException">Thrown if <c>N</c> or <c>Q</c> are invalid</exception> public RLWEParameters(int N, int Q, double Sigma, byte[] OId, int MFP = DEFAULT_MFP, Prngs Engine = Prngs.CTRPrng) { if (N != 256 && N != 512) { throw new RLWEException("RLWEParameters:Ctor", "N is invalid (only 256 or 512 currently supported)!", new ArgumentOutOfRangeException()); } if (Q != 7681 && Q != 12289) { throw new RLWEException("RLWEParameters:Ctor", "Q is invalid (only 7681 or 12289 currently supported)!", new ArgumentOutOfRangeException()); } if (Sigma != 11.31 && Sigma != 12.18) { throw new RLWEException("RLWEParameters:Ctor", "Sigma is invalid (only 11.31 or 12.18 currently supported)!", new ArgumentOutOfRangeException()); } if (N == 256 && MFP > 16 || N == 512 && MFP > 32) { throw new RLWEException("RLWEParameters:Ctor", "MFP is invalid (forward padding can not be longer than half the maximum message size)!", new ArgumentOutOfRangeException()); } _Sigma = Sigma; _N = N; _Q = Q; Array.Copy(OId, this.OId, Math.Min(OId.Length, 3)); _mFp = MFP; _rndEngine = Engine; }
/// <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); } }
/// <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; } } }
private void Dispose(bool Disposing) { if (!m_isDisposed && Disposing) { try { m_N = 0; m_Q = 0; m_Sigma = 0; m_mFp = 0; m_rndEngineType = Prngs.CTRPrng; m_dgtEngineType = Digests.SHA512; if (m_oId != null) { Array.Clear(m_oId, 0, m_oId.Length); m_oId = null; } } finally { m_isDisposed = true; } } }
/// <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 Prng /// </summary> /// /// <param name="Prng">Prng type</param> /// /// <returns>Instance of Prng</returns> private IRandom GetPrng(Prngs Prng) { switch (Prng) { case Prngs.CTRPrng: return(new CTRPrng()); case Prngs.DGCPrng: return(new DGCPrng()); case Prngs.CSPRng: return(new CSPRng()); case Prngs.BBSG: return(new BBSG()); case Prngs.CCG: return(new CCG()); case Prngs.MODEXPG: return(new MODEXPG()); case Prngs.QCG1: return(new QCG1()); case Prngs.QCG2: return(new QCG2()); default: throw new NTRUException("NTRUEncrypt:GetPrng", "The prng type is not supported!", new ArgumentException()); } }
/// <summary> /// Constructs a DtmIdentityStruct from a stream /// </summary> /// /// <param name="ParametersStream">Stream containing a serialized DtmParameters</param> /// /// <returns>A populated DtmParameters</returns> public DtmParameters(Stream ParametersStream) { BinaryReader reader = new BinaryReader(ParametersStream); int len; byte[] data; len = reader.ReadInt32(); OId = reader.ReadBytes(len); len = reader.ReadInt32(); AuthPkeId = reader.ReadBytes(len); len = reader.ReadInt32(); PrimaryPkeId = reader.ReadBytes(len); len = reader.ReadInt32(); data = reader.ReadBytes(len); AuthSession = new DtmSessionStruct(data); len = reader.ReadInt32(); data = reader.ReadBytes(len); PrimarySession = new DtmSessionStruct(data); RandomEngine = (Prngs)reader.ReadByte(); MaxAsmKeyAppend = reader.ReadInt32(); MaxAsmKeyPrePend = reader.ReadInt32(); MaxAsmParamsAppend = reader.ReadInt32(); MaxAsmParamsPrePend = reader.ReadInt32(); MaxSymKeyAppend = reader.ReadInt32(); MaxSymKeyPrePend = reader.ReadInt32(); MaxMessageAppend = reader.ReadInt32(); MaxMessagePrePend = reader.ReadInt32(); MaxAsmKeyDelayMS = reader.ReadInt32(); MaxSymKeyDelayMS = reader.ReadInt32(); MaxMessageDelayMS = reader.ReadInt32(); }
/// <summary> /// Get the cipher engine /// </summary> /// /// <param name="Prng">The Prng</param> /// /// <returns>An initialized prng</returns> /// /// <exception cref="CryptoAsymmetricException">Thrown if the prng type is unknown or unsupported</exception> private IRandom GetPrng(Prngs Prng) { switch (Prng) { case Prngs.CTRPrng: return(new CTRPrng()); case Prngs.DGCPrng: return(new DGCPrng()); case Prngs.CSPRng: return(new CSPRng()); case Prngs.BBSG: return(new BBSG()); case Prngs.CCG: return(new CCG()); case Prngs.MODEXPG: return(new MODEXPG()); case Prngs.QCG1: return(new QCG1()); case Prngs.QCG2: return(new QCG2()); default: throw new CryptoAsymmetricException("MPKCKeyGenerator:GetPrng", "The Prng 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 RLWEParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); try { m_oId = reader.ReadBytes(OID_SIZE); m_N = reader.ReadInt32(); m_Q = reader.ReadInt32(); m_Sigma = reader.ReadDouble(); m_mFp = reader.ReadInt32(); m_rndEngineType = (Prngs)reader.ReadInt32(); m_dgtEngineType = (Digests)reader.ReadInt32(); } catch { throw; } } catch (Exception ex) { throw new CryptoAsymmetricException("RLWEParameters:CTor", "The stream could not be read!", ex); } }
/// <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(); }
/// <summary> /// Get the cipher engine /// </summary> /// /// <param name="PrngType">The Prng</param> /// /// <returns>An initialized prng</returns> private IRandom GetPrng(Prngs PrngType) { try { return(PrngFromName.GetInstance(PrngType)); } catch { throw new CryptoAsymmetricSignException("GMSSKeyGenerator:GetPrng", "The Prng type is not supported!", new ArgumentException()); } }
/// <summary> /// Get the cipher engine /// </summary> /// /// <param name="PrngType">The Prng</param> /// /// <returns>An initialized prng</returns> private IRandom GetPrng(Prngs PrngType) { try { return(PrngFromName.GetInstance(PrngType)); } catch { throw new CryptoAsymmetricException("PointchevalCipher:GetPrng", "The Prng type is not supported!", new ArgumentException()); } }
/// <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; m_rndEngineType = _gmssParams.RandomEngine; _msDigestTree = GetDigest(CiphersParams.DigestEngine); // construct randomizer _gmssRand = new GMSSRandom(_msDigestTree); // set mdLength _mdLength = _msDigestTree.DigestSize; // construct Random for initial seed generation m_rndEngine = RngEngine; Initialize(); }
/// <summary> /// Intitialize this class /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The Generalized Merkle Signature Scheme family must be <c>4</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="NumLayers">The number of authentication tree layers</param> /// <param name="HeightOfTrees">The height of the authentication trees of each layer</param> /// <param name="WinternitzParameter">The Winternitz Parameter 'w' of each layer</param> /// <param name="K">The parameter K needed for the authentication path computation</param> /// <param name="Digest">The hash engine type</param> /// <param name="RandomEngine">The random generator type</param> /// /// <exception cref="System.ArgumentException">Thrown if the Vi or Oid settings are invalid</exception> public GMSSParameters(byte[] OId, int NumLayers, int[] HeightOfTrees, int[] WinternitzParameter, int[] K, Digests Digest = Digests.SHA256, Prngs RandomEngine = Prngs.CTRPrng) { if (OId.Length != OID_SIZE) { throw new CryptoAsymmetricException("GMSSParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); } if (OId[0] != (byte)AsymmetricEngines.GMSS) { throw new CryptoAsymmetricException("GMSSParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.GMSS, new ArgumentException())); } m_oId = OId; m_dgtEngineType = Digest; m_rndEngineType = RandomEngine; Initialize(NumLayers, HeightOfTrees, WinternitzParameter, K); }
/// <summary> /// Read a Parameters file from a byte array. /// </summary> /// /// <param name="ParamStream">The byte array containing the params</param> /// /// <returns>An initialized RLWEParameters class</returns> public static RLWEParameters From(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); int n = reader.ReadInt32(); int q = reader.ReadInt32(); double s = reader.ReadDouble(); byte[] oid = reader.ReadBytes(3); int mfp = reader.ReadInt32(); Prngs eng = (Prngs)reader.ReadInt32(); return(new RLWEParameters(n, q, s, oid, mfp, eng)); } catch { throw; } }
/// <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); m_oId = reader.ReadBytes(OID_SIZE); m_cca2Engine = (CCA2Ciphers)reader.ReadInt32(); m_dgtEngineType = (Digests)reader.ReadInt32(); m_rndEngineType = (Prngs)reader.ReadInt32(); m_M = reader.ReadInt32(); m_T = reader.ReadInt32(); m_fieldPoly = reader.ReadInt32(); m_N = 1 << M; } catch (Exception ex) { throw new CryptoAsymmetricException("MPKCParameters:CTor", "The stream could not be read!", ex); } }
/// <summary> /// Reset all struct members /// </summary> public void Reset() { Array.Clear(OId, 0, OId.Length); Array.Clear(AuthPkeId, 0, AuthPkeId.Length); Array.Clear(PrimaryPkeId, 0, PrimaryPkeId.Length); AuthSession.Reset(); PrimarySession.Reset(); RandomEngine = Prngs.CTRPrng; MaxAsmKeyAppend = 0; MaxAsmKeyPrePend = 0; MaxAsmParamsAppend = 0; MaxAsmParamsPrePend = 0; MaxSymKeyAppend = 0; MaxSymKeyPrePend = 0; MaxMessageAppend = 0; MaxMessagePrePend = 0; MaxAsmKeyDelayMS = 0; MaxSymKeyDelayMS = 0; MaxMessageDelayMS = 0; }
/// <summary> /// Read a Parameters file from a byte array. /// </summary> /// /// <param name="ParamStream">The byte array containing the params</param> /// /// <returns>An initialized MPKCParameters class</returns> public static MPKCParameters From(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); McElieceCiphers eng = (McElieceCiphers)reader.ReadInt32(); Digests dgt = (Digests)reader.ReadInt32(); Prngs rnd = (Prngs)reader.ReadInt32(); int m = reader.ReadInt32(); int t = reader.ReadInt32(); int fp = reader.ReadInt32(); byte[] oid = reader.ReadBytes(3); return(new MPKCParameters(m, t, fp, oid, eng, dgt, rnd)); } catch { throw; } }
/// <summary> /// /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The Rainbow family must be <c>4</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="Vi">An array containing the number of vinegar variables per layer</param> /// <param name="Engine">The PRNG engine used to power SecureRandom</param> /// /// <exception cref="System.ArgumentException">Thrown if the Vi or Oid settings are invalid</exception> public RNBWParameters(byte[] OId, int[] Vi, Prngs Engine = Prngs.CTRPrng) { if (OId.Length != OID_SIZE) { throw new CryptoAsymmetricException("RNBWParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); } if (OId[0] != (byte)AsymmetricEngines.Rainbow) { throw new CryptoAsymmetricException("RNBWParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.Rainbow, new ArgumentException())); } m_oId = OId; _VI = Vi; m_rndEngine = Engine; if (!CheckParams()) { throw new CryptoAsymmetricException("RNBWParameters:CTor", "The RNBWParameters Vi setting is invalid!", new ArgumentException()); } }
/// <summary> /// Reconstructs a RNBWParameters from its <c>byte</c> array representation. /// </summary> /// /// <param name="ParamStream">An input stream containing an encoded key</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception> public RNBWParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); int len; byte[] data; m_rndEngine = (Prngs)reader.ReadInt32(); m_oId = reader.ReadBytes(OID_SIZE); len = reader.ReadInt32(); _VI = new int[len]; data = reader.ReadBytes(len * 4); _VI = ArrayUtils.ToArray32(data); } catch (Exception ex) { throw new CryptoAsymmetricException("RNBWParameters:CTor", "The RNBWParameters could not be loaded!", ex); } }
/// <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; m_rndEngineType = _gmssParams.RandomEngine; _msDigestTree = GetDigest(CiphersParams.DigestEngine); // construct randomizer _gmssRand = new GMSSRandom(_msDigestTree); // set mdLength _mdLength = _msDigestTree.DigestSize; // construct Random for initial seed generation m_rndEngine = GetPrng(m_rndEngineType); Initialize(); }
/// <summary> /// The DtmParameters primary constructor /// </summary> /// /// <param name="OId">The DtmParameters Identifier field; must be 16 bytes in length</param> /// <param name="AuthPkeId">The <c>Auth-Phase</c> Asymmetric parameters OId; can be the Asymmetric cipher parameters OId, or a serialized Asymmetric Parameters class</param> /// <param name="PrimaryPkeId">The <c>Primary-Phase</c> Asymmetric parameters OId; can be the Asymmetric cipher parameters OId, or a serialized Asymmetric Parameters class</param> /// <param name="AuthSession">The <c>Auth-Phase</c> Symmetric sessions cipher parameters; contains a complete description of the Symmetric cipher</param> /// <param name="PrimarySession">The <c>Primary-Phase</c> Symmetric sessions cipher parameters; contains a complete description of the Symmetric cipher</param> /// <param name="RandomEngine">(Optional) The Prng used to pad messages, defaults to CTRPrng</param> /// <param name="MaxAsmKeyAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Asymmetric Public key before encryption</param> /// <param name="MaxAsmKeyPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Asymmetric Public key before encryption</param> /// <param name="MaxAsmParamsAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Client Identity before encryption</param> /// <param name="MaxAsmParamsPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Asymmetric Client Identity before encryption</param> /// <param name="MaxSymKeyAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Symmetric key before encryption</param> /// <param name="MaxSymKeyPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Symmetric key before encryption</param> /// <param name="MaxMessageAppend">(Optional) The maximum number of pseudo-random bytes to append to a <c>Post-Exchange</c> message before encryption</param> /// <param name="MaxMessagePrePend">(Optional) The maximum number of pseudo-random bytes to prepend to a <c>Post-Exchange</c> message before encryption</param> /// <param name="MaxAsmKeyDelayMS">(Optional) The maximum delay time before sending the <c>Primary-Phase</c> Asymmetric key; the minimum time is 1 half max, a value of <c>0</c> has no delay</param> /// <param name="MaxSymKeyDelayMS">(Optional) The maximum delay time before sending the <c>Primary-Phase</c> Symmetric key; the minimum time is 1 half max, a value of <c>0</c> has no delay</param> /// <param name="MaxMessageDelayMS">(Optional) The maximum delay time before sending message traffic; the minimum time is <c>0</c>, a value of <c>0</c> has no delay</param> public DtmParameters(byte[] OId, byte[] AuthPkeId, byte[] PrimaryPkeId, DtmSessionStruct AuthSession, DtmSessionStruct PrimarySession, Prngs RandomEngine = Prngs.CTRPrng, int MaxAsmKeyAppend = 0, int MaxAsmKeyPrePend = 0, int MaxAsmParamsAppend = 0, int MaxAsmParamsPrePend = 0, int MaxSymKeyAppend = 0, int MaxSymKeyPrePend = 0, int MaxMessageAppend = 0, int MaxMessagePrePend = 0, int MaxAsmKeyDelayMS = 0, int MaxSymKeyDelayMS = 0, int MaxMessageDelayMS = 0) { this.OId = OId; this.AuthPkeId = AuthPkeId; this.PrimaryPkeId = PrimaryPkeId; this.AuthSession = AuthSession; this.PrimarySession = PrimarySession; this.RandomEngine = RandomEngine; this.MaxAsmKeyAppend = MaxAsmKeyAppend; this.MaxAsmKeyPrePend = MaxAsmKeyPrePend; this.MaxAsmParamsAppend = MaxAsmParamsAppend; this.MaxAsmParamsPrePend = MaxAsmParamsPrePend; this.MaxSymKeyAppend = MaxSymKeyAppend; this.MaxSymKeyPrePend = MaxSymKeyPrePend; this.MaxMessageAppend = MaxMessageAppend; this.MaxMessagePrePend = MaxMessagePrePend; this.MaxAsmKeyDelayMS = MaxAsmKeyDelayMS; this.MaxSymKeyDelayMS = MaxSymKeyDelayMS; this.MaxMessageDelayMS = MaxMessageDelayMS; }
/// <summary> /// Constructs a parameter set that uses ternary private keys (i.e. <c>PolyType=SIMPLE</c>) /// </summary> /// /// <param name="N">The ring dimension; the number of polynomial coefficients</param> /// <param name="Q">The big Q Modulus</param> /// <param name="Df">Number of ones in the private polynomial <c>f</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 Df, 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; _DF = Df; _Db = Db; _Dm0 = Dm0; _maxM1 = MaxM1; _cBits = CBits; _minIGFHashCalls = MinIGFHashCalls; _minMGFHashCalls = MinMGFHashCalls; _hashSeed = HashSeed; _sparseMode = Sparse; _fastFp = FastFp; _polyType = TernaryPolynomialType.SIMPLE; _messageDigest = Digest; _randomEngine = Random; this.OId = OId; Initialize(); }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { _N = 0; _Q = 0; _Sigma = 0; _mFp = 0; _rndEngine = 0; if (_oId != null) { Array.Clear(_oId, 0, _oId.Length); _oId = null; } } finally { _isDisposed = true; } } }
/// <summary> /// Reconstructs a GMSSParameters from its <c>byte</c> array representation. /// </summary> /// /// <param name="ParamStream">An input stream containing an encoded key</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception> public GMSSParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); int len; m_oId = reader.ReadBytes(OID_SIZE); m_dgtEngineType = (Digests)reader.ReadByte(); m_rndEngineType = (Prngs)reader.ReadByte(); _numLayers = reader.ReadInt32(); len = reader.ReadInt32(); _heightOfTrees = ArrayUtils.ToArray32(reader.ReadBytes(len)); len = reader.ReadInt32(); _winternitzParameter = ArrayUtils.ToArray32(reader.ReadBytes(len)); len = reader.ReadInt32(); m_K = ArrayUtils.ToArray32(reader.ReadBytes(len)); } catch (Exception ex) { throw new CryptoAsymmetricException("GMSSParameters:CTor", "The GMSSParameters could not be loaded!", ex); } }
private void Dispose(bool Disposing) { if (!m_isDisposed && Disposing) { try { m_dgtEngineType = Digests.SHA256; m_rndEngineType = Prngs.CTRPrng; _numLayers = 0; if (m_oId != null) { Array.Clear(m_oId, 0, m_oId.Length); m_oId = null; } if (_heightOfTrees != null) { Array.Clear(_heightOfTrees, 0, _heightOfTrees.Length); _heightOfTrees = null; } if (_winternitzParameter != null) { Array.Clear(_winternitzParameter, 0, _winternitzParameter.Length); _winternitzParameter = null; } if (m_K != null) { Array.Clear(m_K, 0, m_K.Length); m_K = null; } } finally { m_isDisposed = true; } } }
/// <summary> /// /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The Rainbow family must be <c>4</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="Vi">An array containing the number of vinegar variables per layer</param> /// <param name="Engine">The PRNG engine used to power SecureRandom</param> /// /// <exception cref="System.ArgumentException">Thrown if the Vi or Oid settings are invalid</exception> public RNBWParameters(byte[] OId, int[] Vi, Prngs Engine = Prngs.CTRPrng) { if (OId.Length != OID_SIZE) throw new CryptoAsymmetricException("RNBWParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); if (OId[0] != (byte)AsymmetricEngines.Rainbow) throw new CryptoAsymmetricException("RNBWParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.Rainbow, new ArgumentException())); _oId = OId; _VI = Vi; _rndEngine = Engine; if (!CheckParams()) throw new CryptoAsymmetricException("RNBWParameters:CTor", "The RNBWParameters Vi setting is invalid!", new ArgumentException()); }
/// <summary> /// Reconstructs a RNBWParameters from its <c>byte</c> array representation. /// </summary> /// /// <param name="ParamStream">An input stream containing an encoded key</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception> public RNBWParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); int len; byte[] data; _rndEngine = (Prngs)reader.ReadInt32(); _oId = reader.ReadBytes(OID_SIZE); len = reader.ReadInt32(); _VI = new int[len]; data = reader.ReadBytes(len * 4); _VI = ArrayUtils.ToArray32(data); } catch (Exception ex) { throw new CryptoAsymmetricException("RNBWParameters:CTor", "The RNBWParameters could not be loaded!", ex); } }
/// <summary> /// Create a key file using a <see cref="PackageKey"/> structure; containing the cipher description and operating ids and flags. /// </summary> /// /// <param name="Package">The <see cref="PackageKey">Key Header</see> containing the cipher description and operating ids and flags</param> /// <param name="SeedEngine">The <see cref="Prngs">Random Generator</see> used to create the stage I seed material during key generation.</param> /// <param name="DigestEngine">The <see cref="Digests">Digest Engine</see> used in the stage II phase of key generation.</param> /// /// <exception cref="CryptoProcessingException">Thrown if a key file exists at the path specified, the path is read only, the CipherDescription or KeyAuthority structures are invalid, or /// number of SubKeys specified is either less than 1 or more than the maximum allowed (100,000)</exception> public void Create(PackageKey Package, Prngs SeedEngine = Prngs.CSPRng, Digests DigestEngine = Digests.SHA512) { // if you are getting exceptions.. read the docs! if (File.Exists(_keyPath)) throw new CryptoProcessingException("PackageFactory:Create", "The key file exists! Can not overwrite an existing key file, choose a different path.", new FileLoadException()); if (!DirectoryTools.IsWritable(Path.GetDirectoryName(_keyPath))) throw new CryptoProcessingException("PackageFactory:Create", "The selected directory is read only! Choose a different path.", new UnauthorizedAccessException()); if (!CipherDescription.IsValid(Package.Description)) throw new CryptoProcessingException("PackageFactory:Create", "The key package cipher settings are invalid!", new FormatException()); if (!KeyAuthority.IsValid(Package.Authority)) throw new CryptoProcessingException("PackageFactory:Create", "The key package key authority settings are invalid!", new FormatException()); if (Package.SubKeyCount < 1) throw new CryptoProcessingException("PackageFactory:Create", "The key package must contain at least 1 key!", new ArgumentOutOfRangeException()); if (Package.SubKeyCount > SUBKEY_MAX) throw new CryptoProcessingException("PackageFactory:Create", String.Format("The key package can not contain more than {0} keys!", SUBKEY_MAX), new ArgumentOutOfRangeException()); // get the size of a subkey set int subKeySize = Package.Description.KeySize; if (Package.Description.IvSize > 0) subKeySize += Package.Description.IvSize; if (Package.Description.MacSize > 0) subKeySize += Package.Description.MacSize; if (subKeySize < 0) throw new CryptoProcessingException("PackageFactory:Create", "The key package cipher settings are invalid!", new Exception()); try { // store the auth struct and policy _keyOwner = Package.Authority; this.KeyPolicy = Package.KeyPolicy; // get the serialized header byte[] header = Package.ToBytes(); // size key buffer byte[] buffer = new byte[subKeySize * Package.SubKeyCount]; // generate the keying material using (KeyGenerator keyGen = new KeyGenerator(SeedEngine, DigestEngine)) keyGen.GetBytes(buffer); using (BinaryWriter keyWriter = new BinaryWriter(new FileStream(_keyPath, FileMode.Create, FileAccess.Write))) { // pre-set the size to avoid fragmentation keyWriter.BaseStream.SetLength(PackageKey.GetHeaderSize(Package) + (subKeySize * Package.SubKeyCount)); if (IsEncrypted(Package.KeyPolicy)) { // add policy flags, only part of key not encrypted keyWriter.Write(Package.KeyPolicy); // get salt, return depends on auth flag settings byte[] salt = GetSalt(); // create a buffer for encrypted data int hdrLen = header.Length - PackageKey.GetPolicyOffset(); byte[] data = new byte[buffer.Length + hdrLen]; // copy header and key material Buffer.BlockCopy(header, PackageKey.GetPolicyOffset(), data, 0, hdrLen); Buffer.BlockCopy(buffer, 0, data, hdrLen, buffer.Length); // encrypt the key and header TransformBuffer(data, salt); // write to file keyWriter.Write(data); // don't wait for gc Array.Clear(salt, 0, salt.Length); Array.Clear(data, 0, data.Length); } else { // write the keypackage header keyWriter.Write(header, 0, header.Length); // write the keying material keyWriter.Write(buffer, 0, buffer.Length); } } // cleanup Array.Clear(header, 0, header.Length); Array.Clear(buffer, 0, buffer.Length); } catch { throw; } }
/// <summary> /// Get the Prng instance /// </summary> /// /// <param name="Prng">The Prngs enumeration member</param> /// /// <returns>The Prng instance</returns> private IRandom GetPrng(Prngs Prng) { switch (Prng) { case Prngs.CTRPrng: return new CTRPrng(); case Prngs.DGCPrng: return new DGCPrng(); case Prngs.CSPRng: return new CSPRng(); case Prngs.BBSG: return new BBSG(); case Prngs.CCG: return new CCG(); case Prngs.MODEXPG: return new MODEXPG(); case Prngs.QCG1: return new QCG1(); case Prngs.QCG2: return new QCG2(); default: throw new CryptoProcessingException("DtmKex:GetPrng", "The Prng type is unknown!", new ArgumentException()); } }
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; } } }
/// <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> /// 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(); }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { _N = 0; _Q = 0; _Sigma = 0; _mFp = 0; _rndEngineType = Prngs.CTRPrng; _dgtEngineType = Digests.SHA512; if (_oId != null) { Array.Clear(_oId, 0, _oId.Length); _oId = null; } } finally { _isDisposed = true; } } }
/// <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> /// Constructs a DtmIdentity from a stream /// </summary> /// /// <param name="ParametersStream">Stream containing a serialized DtmParameters</param> /// /// <returns>A populated DtmParameters</returns> public DtmParameters(Stream ParametersStream) { BinaryReader reader = new BinaryReader(ParametersStream); int len; byte[] data; len = reader.ReadInt32(); OId = reader.ReadBytes(len); len = reader.ReadInt32(); AuthPkeId = reader.ReadBytes(len); len = reader.ReadInt32(); PrimaryPkeId = reader.ReadBytes(len); len = reader.ReadInt32(); data = reader.ReadBytes(len); AuthSession = new DtmSession(data); len = reader.ReadInt32(); data = reader.ReadBytes(len); PrimarySession = new DtmSession(data); RandomEngine = (Prngs)reader.ReadByte(); MaxAsmKeyAppend = reader.ReadInt32(); MaxAsmKeyPrePend = reader.ReadInt32(); MaxAsmParamsAppend = reader.ReadInt32(); MaxAsmParamsPrePend = reader.ReadInt32(); MaxSymKeyAppend = reader.ReadInt32(); MaxSymKeyPrePend = reader.ReadInt32(); MaxMessageAppend = reader.ReadInt32(); MaxMessagePrePend = reader.ReadInt32(); MaxAsmKeyDelayMS = reader.ReadInt32(); MaxSymKeyDelayMS = reader.ReadInt32(); MaxMessageDelayMS = reader.ReadInt32(); }
/// <summary> /// The DtmParameters primary constructor /// </summary> /// /// <param name="OId">The DtmParameters Identifier field; must be 16 bytes in length</param> /// <param name="AuthPkeId">The <c>Auth-Phase</c> Asymmetric parameters OId; can be the Asymmetric cipher parameters OId, or a serialized Asymmetric Parameters class</param> /// <param name="PrimaryPkeId">The <c>Primary-Phase</c> Asymmetric parameters OId; can be the Asymmetric cipher parameters OId, or a serialized Asymmetric Parameters class</param> /// <param name="AuthSession">The <c>Auth-Phase</c> Symmetric sessions cipher parameters; contains a complete description of the Symmetric cipher</param> /// <param name="PrimarySession">The <c>Primary-Phase</c> Symmetric sessions cipher parameters; contains a complete description of the Symmetric cipher</param> /// <param name="RandomEngine">(Optional) The Prng used to pad messages, defaults to CTRPrng</param> /// <param name="MaxAsmKeyAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Asymmetric Public key before encryption</param> /// <param name="MaxAsmKeyPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Asymmetric Public key before encryption</param> /// <param name="MaxAsmParamsAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Client Identity before encryption</param> /// <param name="MaxAsmParamsPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Asymmetric Client Identity before encryption</param> /// <param name="MaxSymKeyAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Symmetric key before encryption</param> /// <param name="MaxSymKeyPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Symmetric key before encryption</param> /// <param name="MaxMessageAppend">(Optional) The maximum number of pseudo-random bytes to append to a <c>Post-Exchange</c> message before encryption</param> /// <param name="MaxMessagePrePend">(Optional) The maximum number of pseudo-random bytes to prepend to a <c>Post-Exchange</c> message before encryption</param> /// <param name="MaxAsmKeyDelayMS">(Optional) The maximum delay time before sending the <c>Primary-Phase</c> Asymmetric key; the minimum time is 1 half max, a value of <c>0</c> has no delay</param> /// <param name="MaxSymKeyDelayMS">(Optional) The maximum delay time before sending the <c>Primary-Phase</c> Symmetric key; the minimum time is 1 half max, a value of <c>0</c> has no delay</param> /// <param name="MaxMessageDelayMS">(Optional) The maximum delay time before sending message traffic; the minimum time is <c>0</c>, a value of <c>0</c> has no delay</param> public DtmParameters(byte[] OId, byte[] AuthPkeId, byte[] PrimaryPkeId, DtmSession AuthSession, DtmSession PrimarySession, Prngs RandomEngine = Prngs.CTRPrng, int MaxAsmKeyAppend = 0, int MaxAsmKeyPrePend = 0, int MaxAsmParamsAppend = 0, int MaxAsmParamsPrePend = 0, int MaxSymKeyAppend = 0, int MaxSymKeyPrePend = 0, int MaxMessageAppend = 0, int MaxMessagePrePend = 0, int MaxAsmKeyDelayMS = 0, int MaxSymKeyDelayMS = 0, int MaxMessageDelayMS = 0) { this.OId = OId; this.AuthPkeId = AuthPkeId; this.PrimaryPkeId = PrimaryPkeId; this.AuthSession = AuthSession; this.PrimarySession = PrimarySession; this.RandomEngine = RandomEngine; this.MaxAsmKeyAppend = MaxAsmKeyAppend; this.MaxAsmKeyPrePend = MaxAsmKeyPrePend; this.MaxAsmParamsAppend = MaxAsmParamsAppend; this.MaxAsmParamsPrePend = MaxAsmParamsPrePend; this.MaxSymKeyAppend = MaxSymKeyAppend; this.MaxSymKeyPrePend = MaxSymKeyPrePend; this.MaxMessageAppend = MaxMessageAppend; this.MaxMessagePrePend = MaxMessagePrePend; this.MaxAsmKeyDelayMS = MaxAsmKeyDelayMS; this.MaxSymKeyDelayMS = MaxSymKeyDelayMS; this.MaxMessageDelayMS = MaxMessageDelayMS; }
/// <summary> /// Get the cipher engine /// </summary> /// /// <param name="Prng">The Prng</param> /// /// <returns>An initialized prng</returns> private IRandom GetPrng(Prngs Prng) { switch (Prng) { case Prngs.CTRPrng: return new CTRPrng(); case Prngs.DGCPrng: return new DGCPrng(); case Prngs.CSPRng: return new CSPRng(); case Prngs.BBSG: return new BBSG(); case Prngs.CCG: return new CCG(); case Prngs.MODEXPG: return new MODEXPG(); case Prngs.QCG1: return new QCG1(); case Prngs.QCG2: return new QCG2(); default: throw new ArgumentException("The Prng type is not supported!"); } }
/// <summary> /// Reconstructs a GMSSParameters from its <c>byte</c> array representation. /// </summary> /// /// <param name="ParamStream">An input stream containing an encoded key</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the Stream is unreadable</exception> public GMSSParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); int len; _oId = reader.ReadBytes(OID_SIZE); _dgtEngineType = (Digests)reader.ReadByte(); _rndEngineType = (Prngs)reader.ReadByte(); _numLayers = reader.ReadInt32(); len = reader.ReadInt32(); _heightOfTrees = ArrayUtils.ToArray32(reader.ReadBytes(len)); len = reader.ReadInt32(); _winternitzParameter = ArrayUtils.ToArray32(reader.ReadBytes(len)); len = reader.ReadInt32(); _K = ArrayUtils.ToArray32(reader.ReadBytes(len)); } catch (Exception ex) { throw new CryptoAsymmetricException("GMSSParameters:CTor", "The GMSSParameters could not be loaded!", ex); } }
/// <summary> /// Intitialize this class /// </summary> /// /// <param name="OId">OId - Unique identifier; <c>Family</c>, <c>Set</c>, <c>SubSet</c>, and <c>Designator</c>. The Generalized Merkle Signature Scheme family must be <c>4</c> corresponding with the <see cref="AsymmetricEngines"/> enumeration.</param> /// <param name="NumLayers">The number of authentication tree layers</param> /// <param name="HeightOfTrees">The height of the authentication trees of each layer</param> /// <param name="WinternitzParameter">The Winternitz Parameter 'w' of each layer</param> /// <param name="K">The parameter K needed for the authentication path computation</param> /// <param name="Digest">The hash engine type</param> /// <param name="RandomEngine">The random generator type</param> /// /// <exception cref="System.ArgumentException">Thrown if the Vi or Oid settings are invalid</exception> public GMSSParameters(byte[] OId, int NumLayers, int[] HeightOfTrees, int[] WinternitzParameter, int[] K, Digests Digest = Digests.SHA256, Prngs RandomEngine = Prngs.CTRPrng) { if (OId.Length != OID_SIZE) throw new CryptoAsymmetricException("GMSSParameters:Ctor", string.Format("The OId is invalid, the OId length must be {0} bytes!", OID_SIZE, new ArgumentException())); if (OId[0] != (byte)AsymmetricEngines.GMSS) throw new CryptoAsymmetricException("GMSSParameters:Ctor", string.Format("The OId is invalid, first byte must be family designator ({0})!", AsymmetricEngines.GMSS, new ArgumentException())); _oId = OId; _dgtEngineType = Digest; _rndEngineType = RandomEngine; Initialize(NumLayers, HeightOfTrees, WinternitzParameter, K); }
/// <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 RLWEParameters(Stream ParamStream) { try { BinaryReader reader = new BinaryReader(ParamStream); try { _oId = reader.ReadBytes(OID_SIZE); _N = reader.ReadInt32(); _Q = reader.ReadInt32(); _Sigma = reader.ReadDouble(); _mFp = reader.ReadInt32(); _rndEngineType = (Prngs)reader.ReadInt32(); _dgtEngineType = (Digests)reader.ReadInt32(); } catch { throw; } } catch (Exception ex) { throw new CryptoAsymmetricException("RLWEParameters:CTor", "The stream could not be read!", ex); } }
/// <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> /// 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> /// 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> /// 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; }
/// <summary> /// Create a volume key file using automatic key material generation. /// <para>The Key, and IV sets are generated automatically using the cipher description contained in the <see cref="CipherDescription"/>. /// This overload creates keying material using the seed and digest engines specified with the <see cref="KeyGenerator"/> class</para> /// </summary> /// /// <param name="Key">The <see cref="VolumeKey">VolumeKey</see> containing the cipher and key implementation details</param> /// <param name="SeedEngine">The <see cref="Prngs">Random Generator</see> used to create the stage I seed material during key generation.</param> /// <param name="HashEngine">The <see cref="Digests">Digest Engine</see> used in the stage II phase of key generation.</param> /// /// <exception cref="System.IO.FileLoadException">A key file exists at the path specified</exception> /// <exception cref="System.UnauthorizedAccessException">The key file path is read only</exception> public void Create(VolumeKey Key, Prngs SeedEngine = Prngs.CSPRng, Digests HashEngine = Digests.SHA512) { int ksize = Key.Count * (Key.Description.KeySize + Key.Description.IvSize); byte[] kdata; using (KeyGenerator keyGen = new KeyGenerator(SeedEngine, HashEngine)) kdata = keyGen.GetBytes(ksize); if (_keyStream == null) _keyStream = new FileStream(_keyPath, FileMode.Create, FileAccess.Write); byte[] hdr = Key.ToBytes(); _keyStream.Write(hdr, 0, hdr.Length); _keyStream.Write(kdata, 0, kdata.Length); }
/// <summary> /// Get the Prng /// </summary> /// /// <param name="Prng">Prng type</param> /// /// <returns>Instance of Prng</returns> private IRandom GetPrng(Prngs Prng) { switch (Prng) { case Prngs.CTRPrng: return new CTRPrng(); case Prngs.DGCPrng: return new DGCPrng(); case Prngs.CSPRng: return new CSPRng(); case Prngs.BBSG: return new BBSG(); case Prngs.CCG: return new CCG(); case Prngs.MODEXPG: return new MODEXPG(); case Prngs.QCG1: return new QCG1(); case Prngs.QCG2: return new QCG2(); default: throw new CryptoAsymmetricException("NTRUKeyGenerator:GetDigest", "The Prng type is not supported!", new ArgumentException()); } }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { _rndEngine = Prngs.CTRPrng; if (_oId != null) { Array.Clear(_oId, 0, _oId.Length); _oId = null; } if (_VI != null) { Array.Clear(_VI, 0, _VI.Length); _VI = null; } } finally { _isDisposed = true; } } }
/// <summary> /// Get the cipher engine /// </summary> /// /// <param name="Prng">The Prng</param> /// /// <returns>An initialized prng</returns> private IRandom GetPrng(Prngs Prng) { switch (Prng) { case Prngs.CTRPrng: return new CTRPrng(); case Prngs.SP20Prng: return new SP20Prng(); case Prngs.DGCPrng: return new DGCPrng(); case Prngs.CSPRng: return new CSPRng(); case Prngs.BBSG: return new BBSG(); case Prngs.CCG: return new CCG(); case Prngs.MODEXPG: return new MODEXPG(); case Prngs.QCG1: return new QCG1(); case Prngs.QCG2: return new QCG2(); default: throw new CryptoAsymmetricSignException("RNBWEncrypt:GetPrng", "The Prng type is not supported!", new ArgumentException()); } }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { _dgtEngineType = Digests.SHA256; _rndEngineType = Prngs.CTRPrng; _numLayers = 0; if (_oId != null) { Array.Clear(_oId, 0, _oId.Length); _oId = null; } if (_heightOfTrees != null) { Array.Clear(_heightOfTrees, 0, _heightOfTrees.Length); _heightOfTrees = null; } if (_winternitzParameter != null) { Array.Clear(_winternitzParameter, 0, _winternitzParameter.Length); _winternitzParameter = null; } if (_K != null) { Array.Clear(_K, 0, _K.Length); _K = null; } } finally { _isDisposed = true; } } }