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; }
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); }