Example #1
0
        public byte[] Encrypt(byte[] message, PublicKey key)
        {
            var keySize = key.n.ToByteArray().Length;
            var encryptedBlockSize = keySize;
            var sourceBlockSize = keySize - preffix.Length - 2;

            var numberBlocks = message.Length / sourceBlockSize;
            numberBlocks += message.Length % sourceBlockSize != 0 ? 1 : 0;

            var result = new byte[numberBlocks * encryptedBlockSize];
            Parallel.For(0, numberBlocks, (i) =>
            //for (var i = 0; i < numberBlocks; i++)
            {
                var part = new byte[encryptedBlockSize];
                var blockLength = message.Length - i * sourceBlockSize < sourceBlockSize ? message.Length - i * sourceBlockSize : sourceBlockSize;
                Array.Copy(message, i * sourceBlockSize, part, 0, blockLength);
                Array.Copy(preffix, 0, part, sourceBlockSize, preffix.Length);
                part[part.Length - 2] = 0x00;
                part[part.Length - 1] = 0x00;

                var mi = new BigInteger(part);
                var Mi = (mi * (mi + key.b)) % key.n;
                var MiBytes = Mi.ToByteArray();
                while (MiBytes.Length < encryptedBlockSize)
                    MiBytes = MiBytes.Concat(new byte[] { 0 }).ToArray();
                Array.Copy(MiBytes, 0, result, i * encryptedBlockSize, encryptedBlockSize);
            });
            return result;
        }
Example #2
0
        public byte[] Decrypt(byte[] message, PrivateKey privateKey, PublicKey publicKey)
        {
            var keySize = publicKey.n.ToByteArray().Length;
            var encryptedBlockSize = keySize;
            var sourceBlockSize = keySize - preffix.Length - 2;

            var numberBlocks = message.Length / encryptedBlockSize;
            if (message.Length % encryptedBlockSize != 0)
                throw new ArgumentException("Wrong size of encrypted message");

            var decryptedMessage = new byte[numberBlocks * sourceBlockSize];

            Parallel.For(0, numberBlocks, (i) =>
            //for (var i = 0; i < numberBlocks; i++)
            {
                var part = new byte[encryptedBlockSize];

                Array.Copy(message, i * encryptedBlockSize, part, 0, encryptedBlockSize);
                var Mi = new BigInteger(part);
                var D = (publicKey.b * publicKey.b + 4 * Mi) % publicKey.n;
                //var s = BigInteger.ModPow(D, (privateKey.p + 1) / 4, privateKey.p);
                //var r = BigInteger.ModPow(D, (privateKey.q + 1) / 4, privateKey.q);
                var s = BigIntegerHelper.fast_exp(D, (privateKey.p + 1) / 4, privateKey.p);
                var r = BigIntegerHelper.fast_exp(D, (privateKey.q + 1) / 4, privateKey.q);
                BigInteger yp, yq;
                BigInteger d = 1;
                ExtendedEuclid(privateKey.p, privateKey.q, out yp, out yq, out d);
                var roots = new BigInteger[4];

                roots[0] = BigInteger.Abs(yp * privateKey.p * r + yq * privateKey.q * s);
                roots[1] = (-roots[0]) % publicKey.n + publicKey.n;
                roots[0] = roots[0] % publicKey.n;

                roots[2] = BigInteger.Abs(yp * privateKey.p * r - yq * privateKey.q * s);
                roots[3] = (-roots[2]) % publicKey.n + publicKey.n;
                roots[2] = roots[2] % publicKey.n;

                for (var j = 0; j < 4; j++)
                {
                    roots[j] = ((-publicKey.b + roots[j]) / 2) % publicKey.n;
                    roots[j] = roots[j] < 0 ? roots[j] + publicKey.n : roots[j];
                }

                var rightRoot = roots.First(num => num.ToByteArray().Skip(sourceBlockSize).Take(preffix.Length).SequenceEqual(preffix));
                Array.Copy(rightRoot.ToByteArray(), 0, decryptedMessage, i * sourceBlockSize, sourceBlockSize);
            });

            return decryptedMessage;
        }
Example #3
0
        private static void TestOneByte()
        {
            RabinCryptosystem rabin = new RabinCryptosystem(new PrimeNumberGenerator(new MillerRabinTest()));
             //36157
            var privateKey = new PrivateKey { p = 3163, q = 3167 };
            var publicKey = new PublicKey { n = 10017221, b = 4562931 };
            var message = new byte[] { 61 };

            var encrypted = rabin.Encrypt(message, publicKey);
            var decrypted = rabin.Decrypt(encrypted, privateKey, publicKey);

            Console.Write("encrypted = ");
            for (var i = 0; i < encrypted.Length; i++)
                Console.Write("{0} ", encrypted[i]);
            Console.WriteLine();

            Console.Write("decrypted = ");
            for (var i = 0; i < decrypted.Length; i++)
                Console.Write("{0} ", decrypted[i]);
            Console.WriteLine();

        }