/// <summary> /// Generate an encryption Key pair /// </summary> /// /// <returns>A McElieceKeyPair containing public and private keys</returns> public IAsymmetricKeyPair GenerateKeyPair() { // finite field GF(2^m) GF2mField field = new GF2mField(_M, _fieldPoly); // irreducible Goppa polynomial PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, _T, PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, _rngEngine); PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp); // matrix for computing square roots in (GF(2^m))^t PolynomialGF2mSmallM[] qInv = ring.SquareRootMatrix; // generate canonical check matrix GF2Matrix h = GoppaCode.CreateCanonicalCheckMatrix(field, gp); // compute short systematic form of check matrix GoppaCode.MaMaPe mmp = GoppaCode.ComputeSystematicForm(h, _rngEngine); GF2Matrix shortH = mmp.SecondMatrix; Permutation p = mmp.Permutation; // compute short systematic form of generator matrix GF2Matrix shortG = (GF2Matrix)shortH.ComputeTranspose(); // obtain number of rows of G (= dimension of the code) int k = shortG.RowCount; // generate keys IAsymmetricKey pubKey = new MPKCPublicKey(_N, _T, shortG); IAsymmetricKey privKey = new MPKCPrivateKey(_N, k, field, gp, p, h, qInv); // return key pair return(new MPKCKeyPair(pubKey, privKey)); }
/// <summary> /// Read a Public key from a stream /// </summary> /// /// <param name="KeyStream">The stream containing the key</param> /// /// <returns>An initialized MPKCPublicKey class</returns> /// /// <exception cref="MPKCException">Thrown if the stream can not be read</exception> public static MPKCPublicKey From(Stream KeyStream) { try { BinaryReader reader = new BinaryReader(KeyStream); int n = reader.ReadInt32(); int t = reader.ReadInt32(); byte[] encG = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); MPKCPublicKey pubKey = new MPKCPublicKey(t, n, encG); return(pubKey); } catch (Exception ex) { throw new MPKCException("MPKCPublicKey:Ctor", ex.Message, ex); } }
/// <summary> /// Initialize the cipher. /// <para>Requires a <see cref="MPKCPublicKey"/> for encryption, or a <see cref="MPKCPrivateKey"/> for decryption</para> /// </summary> /// /// <param name="Encryption">When true cipher is for encryption, if false, decryption</param> /// <param name="KeyPair">The <see cref="IAsymmetricKeyPair"/> containing the McEliece public or private key</param> /// /// <exception cref="MPKCException">Thrown if the cipher is not initialized or the key is invalid</exception> public void Initialize(bool Encryption, IAsymmetricKeyPair KeyPair) { if (!(KeyPair is MPKCKeyPair)) { throw new MPKCException("MPKCEncrypt:Initialize", "Not a valid McEliece key pair!", new InvalidOperationException()); } // init implementation engine _encEngine.Initialize(Encryption, KeyPair); // get the sizes if (Encryption) { if (KeyPair.PublicKey == null) { throw new MPKCException("MPKCEncrypt:Initialize", "Encryption requires a public key!", new InvalidOperationException()); } if (!(KeyPair.PublicKey is MPKCPublicKey)) { throw new MPKCException("MPKCEncrypt:Initialize", "The public key is invalid!", new ArgumentException()); } MPKCPublicKey pub = (MPKCPublicKey)KeyPair.PublicKey; _maxCipherText = pub.N >> 3; _maxPlainText = pub.K >> 3; } else { if (KeyPair.PrivateKey == null) { throw new MPKCException("MPKCEncrypt:Initialize", "Decryption requires a private key!", new InvalidOperationException()); } if (!(KeyPair.PrivateKey is MPKCPrivateKey)) { throw new MPKCException("MPKCEncrypt:Initialize", "The private key is invalid!", new ArgumentException()); } MPKCPrivateKey pri = (MPKCPrivateKey)KeyPair.PrivateKey; _maxPlainText = pri.K >> 3; _maxCipherText = pri.N >> 3; } _isInitialized = true; }
/// <summary> /// Decides whether the given object <c>other</c> is the same as this field /// </summary> /// /// <param name="Obj">The object for comparison</param> /// /// <returns>Returns <c>(this == other)</c></returns> public override bool Equals(Object Obj) { if (Obj == null || !(Obj is MPKCPublicKey)) { return(false); } MPKCPublicKey key = (MPKCPublicKey)Obj; if (N != key.N) { return(false); } if (T != key.T) { return(false); } if (!G.Equals(key.G)) { return(false); } return(true); }
/// <summary> /// Read a Public key from a stream /// </summary> /// /// <param name="KeyStream">The stream containing the key</param> /// /// <returns>An initialized MPKCPublicKey class</returns> /// /// <exception cref="MPKCException">Thrown if the stream can not be read</exception> public static MPKCPublicKey From(Stream KeyStream) { try { BinaryReader reader = new BinaryReader(KeyStream); int n = reader.ReadInt32(); int t = reader.ReadInt32(); byte[] encG = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); MPKCPublicKey pubKey = new MPKCPublicKey(t, n, encG); return pubKey; } catch (Exception ex) { throw new MPKCException("MPKCPublicKey:Ctor", ex.Message, ex); } }
/// <summary> /// Generate an encryption Key pair /// </summary> /// /// <returns>A McElieceKeyPair containing public and private keys</returns> public IAsymmetricKeyPair GenerateKeyPair() { // finite field GF(2^m) GF2mField field = new GF2mField(_M, _fieldPoly); // irreducible Goppa polynomial PolynomialGF2mSmallM gp = new PolynomialGF2mSmallM(field, _T, PolynomialGF2mSmallM.RANDOM_IRREDUCIBLE_POLYNOMIAL, _rngEngine); PolynomialRingGF2m ring = new PolynomialRingGF2m(field, gp); // matrix for computing square roots in (GF(2^m))^t PolynomialGF2mSmallM[] qInv = ring.SquareRootMatrix; // generate canonical check matrix GF2Matrix h = GoppaCode.CreateCanonicalCheckMatrix(field, gp); // compute short systematic form of check matrix GoppaCode.MaMaPe mmp = GoppaCode.ComputeSystematicForm(h, _rngEngine); GF2Matrix shortH = mmp.SecondMatrix; Permutation p = mmp.Permutation; // compute short systematic form of generator matrix GF2Matrix shortG = (GF2Matrix)shortH.ComputeTranspose(); // obtain number of rows of G (= dimension of the code) int k = shortG.RowCount; // generate keys IAsymmetricKey pubKey = new MPKCPublicKey(_N, _T, shortG); IAsymmetricKey privKey = new MPKCPrivateKey(_N, k, field, gp, p, h, qInv); // return key pair return new MPKCKeyPair(pubKey, privKey); }