Example #1
0
		public byte[] Encrypt (byte[] value, byte[] randomK)
#endif
		{
			int domainLen = (int)((_domain.Bits >> 3) + ((_domain.Bits & 7) == 0 ? 0 : 1));
			int encBlockBytes = (_symmetricAlgo == null ? 0 : _symmetricAlgo.BlockSize >> 3);
			int encKeyLen = (_symmetricAlgo == null ? value.Length : _symmetricAlgo.KeySize >> 3);
			int encPaddingLen = 0;
			int encTotalBytes = value.Length;
			int macKeyLen = _mac.HashSize >> 3;
			byte[] result;
			int ridx = 0;

			if (_params.D == null)
				_params.CreateNewPrivateKey ();
			if (_params.Q == null)
				_params.CreatePublicKeyFromPrivateKey ();
			if (_symmetricAlgo != null) {
				int mod = value.Length % encBlockBytes;
				int rmod = encBlockBytes - mod;
				if (mod == 0) {
					if (!(_symmetricAlgo.Padding == PaddingMode.None || _symmetricAlgo.Padding == PaddingMode.Zeros))
						encPaddingLen = _symmetricAlgo.BlockSize >> 3;
				} else {
					encPaddingLen = rmod;
				}
				encTotalBytes += encPaddingLen;
			}

			// Step.1
#if !TEST
			ECKeyPair pair = new ECKeyPair (null, null, _domain);
#else
			ECKeyPair pair = new ECKeyPair (new Number (randomK, false), null, _domain);
#endif
			
			// Step.2
			// TODO: 点圧縮を利用しないオプションを追加する
			byte[] R = pair.ExportPublicKey (true);
			result = new byte[R.Length + encTotalBytes + macKeyLen];
			for (int i = 0; i < R.Length; i ++) result[ridx ++] = R[i];

			// Step.3 & 4
			// TODO: Cofactor Diffie-Hellmanプリミティブを利用するオプションを追加する
			byte[] z = _params.Q.Multiply (pair.D).Export ().X.ToByteArray (domainLen, false);

			// Step.5
			byte[] K = _kdf.Calculate (z, encKeyLen + macKeyLen);

			// Step.6
			byte[] MK = new byte[macKeyLen];
			for (int i = 0; i < MK.Length; i++)
				MK[i] = K[K.Length - MK.Length + i];

			// Step.7
			if (_symmetricAlgo == null) {
				for (int i = 0; i < value.Length; i++)
					result[ridx++] = (byte)(value[i] ^ K[i]);
			} else {
				byte[] EK = new byte[encKeyLen];
				for (int i = 0; i < EK.Length; i ++)
					EK[i] = K[i];
				using (ICryptoTransform transform = _symmetricAlgo.CreateEncryptor (EK, new byte[encBlockBytes])) {
					int i = 0;
					for (; i < value.Length - encBlockBytes; i += encBlockBytes)
						transform.TransformBlock (value, i, encBlockBytes, result, ridx + i);
					byte[] padding = transform.TransformFinalBlock (value, i, value.Length - i);
					Buffer.BlockCopy (padding, 0, result, ridx + i, padding.Length);
					ridx += i + padding.Length;
				}
			}

			// Step.8
			// TODO: HMAC-SHA1-80への対応
			_mac.Key = MK;
			_mac.Initialize ();
			_mac.TransformBlock (result, R.Length, encTotalBytes, null, 0);
			if (_sharedInfo == null)
				_mac.TransformFinalBlock (result, 0, 0);
			else
				_mac.TransformFinalBlock (_sharedInfo, 0, _sharedInfo.Length);
			_mac.Hash.CopyTo (result, ridx);

			return result;
		}
Example #2
0
        public byte[] Encrypt(byte[] value, byte[] randomK)
#endif
        {
            int domainLen     = (int)((_domain.Bits >> 3) + ((_domain.Bits & 7) == 0 ? 0 : 1));
            int encBlockBytes = (_symmetricAlgo == null ? 0 : _symmetricAlgo.BlockSize >> 3);
            int encKeyLen     = (_symmetricAlgo == null ? value.Length : _symmetricAlgo.KeySize >> 3);
            int encPaddingLen = 0;
            int encTotalBytes = value.Length;
            int macKeyLen     = _mac.HashSize >> 3;

            byte[] result;
            int    ridx = 0;

            if (_params.D == null)
            {
                _params.CreateNewPrivateKey();
            }
            if (_params.Q == null)
            {
                _params.CreatePublicKeyFromPrivateKey();
            }
            if (_symmetricAlgo != null)
            {
                int mod  = value.Length % encBlockBytes;
                int rmod = encBlockBytes - mod;
                if (mod == 0)
                {
                    if (!(_symmetricAlgo.Padding == PaddingMode.None || _symmetricAlgo.Padding == PaddingMode.Zeros))
                    {
                        encPaddingLen = _symmetricAlgo.BlockSize >> 3;
                    }
                }
                else
                {
                    encPaddingLen = rmod;
                }
                encTotalBytes += encPaddingLen;
            }

            // Step.1
#if !TEST
            ECKeyPair pair = new ECKeyPair(null, null, _domain);
#else
            ECKeyPair pair = new ECKeyPair(new Number(randomK, false), null, _domain);
#endif

            // Step.2
            // TODO: 点圧縮を利用しないオプションを追加する
            byte[] R = pair.ExportPublicKey(true);
            result = new byte[R.Length + encTotalBytes + macKeyLen];
            for (int i = 0; i < R.Length; i++)
            {
                result[ridx++] = R[i];
            }

            // Step.3 & 4
            // TODO: Cofactor Diffie-Hellmanプリミティブを利用するオプションを追加する
            byte[] z = _params.Q.Multiply(pair.D).Export().X.ToByteArray(domainLen, false);

            // Step.5
            byte[] K = _kdf.Calculate(z, encKeyLen + macKeyLen);

            // Step.6
            byte[] MK = new byte[macKeyLen];
            for (int i = 0; i < MK.Length; i++)
            {
                MK[i] = K[K.Length - MK.Length + i];
            }

            // Step.7
            if (_symmetricAlgo == null)
            {
                for (int i = 0; i < value.Length; i++)
                {
                    result[ridx++] = (byte)(value[i] ^ K[i]);
                }
            }
            else
            {
                byte[] EK = new byte[encKeyLen];
                for (int i = 0; i < EK.Length; i++)
                {
                    EK[i] = K[i];
                }
                using (ICryptoTransform transform = _symmetricAlgo.CreateEncryptor(EK, new byte[encBlockBytes])) {
                    int i = 0;
                    for (; i < value.Length - encBlockBytes; i += encBlockBytes)
                    {
                        transform.TransformBlock(value, i, encBlockBytes, result, ridx + i);
                    }
                    byte[] padding = transform.TransformFinalBlock(value, i, value.Length - i);
                    Buffer.BlockCopy(padding, 0, result, ridx + i, padding.Length);
                    ridx += i + padding.Length;
                }
            }

            // Step.8
            // TODO: HMAC-SHA1-80への対応
            _mac.Key = MK;
            _mac.Initialize();
            _mac.TransformBlock(result, R.Length, encTotalBytes, null, 0);
            if (_sharedInfo == null)
            {
                _mac.TransformFinalBlock(result, 0, 0);
            }
            else
            {
                _mac.TransformFinalBlock(_sharedInfo, 0, _sharedInfo.Length);
            }
            _mac.Hash.CopyTo(result, ridx);

            return(result);
        }