/// <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> /// 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 MPKCPrivateKey)) { return(false); } MPKCPrivateKey key = (MPKCPrivateKey)Obj; if (!N.Equals(key.N)) { return(false); } if (!K.Equals(key.K)) { return(false); } if (!GF.Equals(key.GF)) { return(false); } if (!GP.Equals(key.GP)) { return(false); } if (!P1.Equals(key.P1)) { return(false); } if (!H.Equals(key.H)) { return(false); } if (QInv.Length != key.QInv.Length) { return(false); } for (int i = 0; i < QInv.Length; i++) { if (!QInv[i].Equals(key.QInv[i])) { return(false); } } return(true); }
/// <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> /// 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); }