diff --git a/Crypto/src/crypto/generators/Mgf1BytesGenerator.cs b/Crypto/src/crypto/generators/Mgf1BytesGenerator.cs
new file mode 100644
index 000000000..23a3aca25
--- /dev/null
+++ b/Crypto/src/crypto/generators/Mgf1BytesGenerator.cs
@@ -0,0 +1,117 @@
+using System;
+//using Org.BouncyCastle.Math;
+//using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+
+namespace Org.BouncyCastle.Crypto.Generators
+{
+ /**
+ * Generator for MGF1 as defined in Pkcs 1v2
+ */
+ public class Mgf1BytesGenerator : IDerivationFunction
+ {
+ private IDigest digest;
+ private byte[] seed;
+ private int hLen;
+
+ /**
+ * @param digest the digest to be used as the source of Generated bytes
+ */
+ public Mgf1BytesGenerator(
+ IDigest digest)
+ {
+ this.digest = digest;
+ this.hLen = digest.GetDigestSize();
+ }
+
+ public void Init(
+ IDerivationParameters parameters)
+ {
+ if (!(typeof(MgfParameters).IsInstanceOfType(parameters)))
+ {
+ throw new ArgumentException("MGF parameters required for MGF1Generator");
+ }
+
+ MgfParameters p = (MgfParameters)parameters;
+
+ seed = p.GetSeed();
+ }
+
+ /**
+ * return the underlying digest.
+ */
+ public IDigest Digest
+ {
+ get
+ {
+ return digest;
+ }
+ }
+
+ /**
+ * int to octet string.
+ */
+ private void ItoOSP(
+ int i,
+ byte[] sp)
+ {
+ sp[0] = (byte)((uint) i >> 24);
+ sp[1] = (byte)((uint) i >> 16);
+ sp[2] = (byte)((uint) i >> 8);
+ sp[3] = (byte)((uint) i >> 0);
+ }
+
+ /**
+ * fill len bytes of the output buffer with bytes Generated from
+ * the derivation function.
+ *
+ * @throws DataLengthException if the out buffer is too small.
+ */
+ public int GenerateBytes(
+ byte[] output,
+ int outOff,
+ int length)
+ {
+ if ((output.Length - length) < outOff)
+ {
+ throw new DataLengthException("output buffer too small");
+ }
+
+ byte[] hashBuf = new byte[hLen];
+ byte[] C = new byte[4];
+ int counter = 0;
+
+ digest.Reset();
+
+ if (length > hLen)
+ {
+ do
+ {
+ ItoOSP(counter, C);
+
+ digest.BlockUpdate(seed, 0, seed.Length);
+ digest.BlockUpdate(C, 0, C.Length);
+ digest.DoFinal(hashBuf, 0);
+
+ Array.Copy(hashBuf, 0, output, outOff + counter * hLen, hLen);
+ }
+ while (++counter < (length / hLen));
+ }
+
+ if ((counter * hLen) < length)
+ {
+ ItoOSP(counter, C);
+
+ digest.BlockUpdate(seed, 0, seed.Length);
+ digest.BlockUpdate(C, 0, C.Length);
+ digest.DoFinal(hashBuf, 0);
+
+ Array.Copy(hashBuf, 0, output, outOff + counter * hLen, length - (counter * hLen));
+ }
+
+ return length;
+ }
+ }
+
+}
|