Esempio n. 1
0
		/**
        * Return a random BigInteger not less than 'min' and not greater than 'max'
        * 
        * @param min the least value that may be generated
        * @param max the greatest value that may be generated
        * @param random the source of randomness
        * @return a random BigInteger value in the range [min,max]
        */
		public static BigInteger CreateRandomInRange(
			BigInteger min,
			BigInteger max,
			// TODO Should have been just Random class
			SecureRandom random)
		{
			int cmp = min.CompareTo(max);
			if(cmp >= 0)
			{
				if(cmp > 0)
					throw new ArgumentException("'min' may not be greater than 'max'");

				return min;
			}

			if(min.BitLength > max.BitLength / 2)
			{
				return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min);
			}

			for(int i = 0; i < MaxIterations; ++i)
			{
				BigInteger x = new BigInteger(max.BitLength, random);
				if(x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0)
				{
					return x;
				}
			}

			// fall back to a faster (restricted) method
			return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min);
		}
Esempio n. 2
0
		/**
		 * generate a signature for the given message using the key we were
		 * initialised with. For conventional Gost3410 the message should be a Gost3411
		 * hash of the message of interest.
		 *
		 * @param message the message that will be verified later.
		 */
		public BigInteger[] GenerateSignature(
			byte[] message)
		{
			byte[] mRev = new byte[message.Length]; // conversion is little-endian
			for (int i = 0; i != mRev.Length; i++)
			{
				mRev[i] = message[mRev.Length - 1 - i];
			}

			BigInteger m = new BigInteger(1, mRev);
			Gost3410Parameters parameters = key.Parameters;
			BigInteger k;

			do
			{
				k = new BigInteger(parameters.Q.BitLength, random);
			}
			while (k.CompareTo(parameters.Q) >= 0);

			BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q);

			BigInteger s = k.Multiply(m).
				Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)).
				Mod(parameters.Q);

			return new BigInteger[]{ r, s };
		}
		public Gost3410PrivateKeyParameters(
			BigInteger			x,
			DerObjectIdentifier	publicKeyParamSet)
			: base(true, publicKeyParamSet)
		{
			if (x.SignValue < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0)
				throw new ArgumentException("Invalid x for GOST3410 private key", "x");

			this.x = x;
		}
Esempio n. 4
0
		public DHParameters(
			BigInteger				p,
			BigInteger				g,
			BigInteger				q,
			int						m,
			int						l,
			BigInteger				j,
			DHValidationParameters	validation)
		{
			if (p == null)
				throw new ArgumentNullException("p");
			if (g == null)
				throw new ArgumentNullException("g");
			if (!p.TestBit(0))
				throw new ArgumentException("field must be an odd prime", "p");
			if (g.CompareTo(BigInteger.Two) < 0
				|| g.CompareTo(p.Subtract(BigInteger.Two)) > 0)
				throw new ArgumentException("generator must in the range [2, p - 2]", "g");
			if (q != null && q.BitLength >= p.BitLength)
				throw new ArgumentException("q too big to be a factor of (p-1)", "q");
			if (m >= p.BitLength)
				throw new ArgumentException("m value must be < bitlength of p", "m");
			if (l != 0)
			{ 
	            if (l >= p.BitLength)
                	throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l");
				if (l < m)
					throw new ArgumentException("when l value specified, it may not be less than m value", "l");
			}
			if (j != null && j.CompareTo(BigInteger.Two) < 0)
				throw new ArgumentException("subgroup factor must be >= 2", "j");

			// TODO If q, j both provided, validate p = jq + 1 ?

			this.p = p;
			this.g = g;
			this.q = q;
			this.m = m;
			this.l = l;
			this.j = j;
			this.validation = validation;
        }
        public virtual BigInteger NextK()
        {
            int qBitLength = q.BitLength;

            BigInteger k;
            do
            {
                k = new BigInteger(qBitLength, random);
            }
            while (k.SignValue < 1 || k.CompareTo(q) >= 0);

            return k;
        }
        public AsymmetricCipherKeyPair GenerateKeyPair()
        {
            SecureRandom random = param.Random;
            Gost3410Parameters gost3410Params = param.Parameters;

            BigInteger q = gost3410Params.Q, x;

            int minWeight = 64;
            for (;;)
            {
                x = new BigInteger(256, random);

                if (x.SignValue < 1 || x.CompareTo(q) >= 0)
                    continue;

                /*
                 * Require a minimum weight of the NAF representation, since low-weight primes may be
                 * weak against a version of the number-field-sieve for the discrete-logarithm-problem.
                 * 
                 * See "The number field sieve for integers of low weight", Oliver Schirokauer.
                 */
                if (WNafUtilities.GetNafWeight(x) < minWeight)
                    continue;

                break;
            }

            BigInteger p = gost3410Params.P;
            BigInteger a = gost3410Params.A;

            // calculate the public key.
            BigInteger y = a.ModPow(x, p);

            if (param.PublicKeyParamSet != null)
            {
                return new AsymmetricCipherKeyPair(
                    new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet),
                    new Gost3410PrivateKeyParameters(x, param.PublicKeyParamSet));
            }

            return new AsymmetricCipherKeyPair(
                new Gost3410PublicKeyParameters(y, gost3410Params),
                new Gost3410PrivateKeyParameters(x, gost3410Params));
        }
Esempio n. 7
0
		public BigInteger ConvertInput(
			byte[]	inBuf,
			int		inOff,
			int		inLen)
		{
			int maxLength = (bitSize + 7) / 8;

			if (inLen > maxLength)
				throw new DataLengthException("input too large for RSA cipher.");

			BigInteger input = new BigInteger(1, inBuf, inOff, inLen);

			if (input.CompareTo(key.Modulus) >= 0)
				throw new DataLengthException("input too large for RSA cipher.");

			return input;
		}
		/**
		 * Procedure C
		 * procedure generates the a value from the given p,q,
		 * returning the a value.
		 */
		private BigInteger procedure_C(BigInteger p, BigInteger q)
		{
			BigInteger pSub1 = p.Subtract(BigInteger.One);
			BigInteger pSub1Divq = pSub1.Divide(q);

			for(;;)
			{
				BigInteger d = new BigInteger(p.BitLength, init_random);

				// 1 < d < p-1
				if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0)
				{
					BigInteger a = d.ModPow(pSub1Divq, p);

					if (a.CompareTo(BigInteger.One) != 0)
					{
						return a;
					}
				}
			}
		}
Esempio n. 9
0
		public Key Derivate(byte[] cc, uint nChild, out byte[] ccChild)
		{
			byte[] l = null;
			if((nChild >> 31) == 0)
			{
				var pubKey = PubKey.ToBytes();
				l = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.SafeSubarray(1));
			}
			else
			{
				l = Hashes.BIP32Hash(cc, nChild, 0, this.ToBytes());
			}
			var ll = l.SafeSubarray(0, 32);
			var lr = l.SafeSubarray(32, 32);

			ccChild = lr;

			var parse256LL = new BigInteger(1, ll);
			var kPar = new BigInteger(1, vch);
			var N = ECKey.CURVE.N;

			if(parse256LL.CompareTo(N) >= 0)
				throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again.");
			var key = parse256LL.Add(kPar).Mod(N);
			if(key == BigInteger.Zero)
				throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again.");

			var keyBytes = key.ToByteArrayUnsigned();
			if(keyBytes.Length < 32)
				keyBytes = new byte[32 - keyBytes.Length].Concat(keyBytes).ToArray();
			return new Key(keyBytes);
		}
Esempio n. 10
0
        // Section 7.2.6 ECVP-NR, pg 35
        /**
         * return true if the value r and s represent a signature for the
         * message passed in. Generally, the order of the curve should be at
         * least as long as the hash of the message of interest, and with
         * ECNR, it *must* be at least as long.  But just in case the signer
         * applied mod(n) to the longer digest, this implementation will
         * apply mod(n) during verification.
         *
         * @param digest  the digest to be verified.
         * @param r       the r value of the signature.
         * @param s       the s value of the signature.
         * @exception DataLengthException if the digest is longer than the key allows
         */
        public bool VerifySignature(
            byte[]		message,
            BigInteger	r,
            BigInteger	s)
        {
            if (this.forSigning)
            {
                // not properly initilaized... deal with it
                throw new InvalidOperationException("not initialised for verifying");
            }

            ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key;
            BigInteger n = pubKey.Parameters.N;
            int nBitLength = n.BitLength;

            BigInteger e = new BigInteger(1, message);
            int eBitLength = e.BitLength;

            if (eBitLength > nBitLength)
            {
                throw new DataLengthException("input too large for ECNR key.");
            }

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return false;
            }

            // s in the range [0,n-1]           NB: ECNR spec says 0
            if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
            {
                return false;
            }

            // compute P = sG + rW

            ECPoint G = pubKey.Parameters.G;
            ECPoint W = pubKey.Q;
            // calculate P using Bouncy math
            ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize();

            if (P.IsInfinity)
                return false;

            BigInteger x = P.AffineXCoord.ToBigInteger();
            BigInteger t = r.Subtract(x).Mod(n);

            return t.Equals(e);
        }
Esempio n. 11
0
        // 5.4 pg 29
        /**
         * return true if the value r and s represent a DSA signature for
         * the passed in message (for standard DSA the message should be
         * a SHA-1 hash of the real message to be verified).
         */
        public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
        {
            BigInteger n = key.Parameters.N;

            // r and s should both in the range [1,n-1]
            if (r.SignValue < 1 || s.SignValue < 1
                || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
            {
                return false;
            }

            BigInteger e = CalculateE(n, message);
            BigInteger c = s.ModInverse(n);

            BigInteger u1 = e.Multiply(c).Mod(n);
            BigInteger u2 = r.Multiply(c).Mod(n);

            ECPoint G = key.Parameters.G;
            ECPoint Q = ((ECPublicKeyParameters) key).Q;

            ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize();

            if (point.IsInfinity)
                return false;

            BigInteger v = point.AffineXCoord.ToBigInteger().Mod(n);

            return v.Equals(r);
        }
Esempio n. 12
0
        /**
         * return true if the value r and s represent a GOST3410 signature for
         * the passed in message (for standard GOST3410 the message should be
         * a GOST3411 hash of the real message to be verified).
         */
        public bool VerifySignature(
            byte[]		message,
            BigInteger	r,
            BigInteger	s)
        {
            byte[] mRev = new byte[message.Length]; // conversion is little-endian
            for (int i = 0; i != mRev.Length; i++)
            {
                mRev[i] = message[mRev.Length - 1 - i];
            }

            BigInteger e = new BigInteger(1, mRev);
            BigInteger n = key.Parameters.N;

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return false;
            }

            // s in the range [1,n-1]
            if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
            {
                return false;
            }

            BigInteger v = e.ModInverse(n);

            BigInteger z1 = s.Multiply(v).Mod(n);
            BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n);

            ECPoint G = key.Parameters.G; // P
            ECPoint Q = ((ECPublicKeyParameters)key).Q;

            ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize();

            if (point.IsInfinity)
                return false;

            BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n);

            return R.Equals(r);
        }
Esempio n. 13
0
		/**
		* Process a single block using the basic ElGamal algorithm.
		*
		* @param in the input array.
		* @param inOff the offset into the input buffer where the data starts.
		* @param length the length of the data to be processed.
		* @return the result of the ElGamal process.
		* @exception DataLengthException the input block is too large.
		*/
		public byte[] ProcessBlock(
			byte[]	input,
			int		inOff,
			int		length)
		{
			if (key == null)
				throw new InvalidOperationException("ElGamal engine not initialised");

			int maxLength = forEncryption
				?	(bitSize - 1 + 7) / 8
				:	GetInputBlockSize();

			if (length > maxLength)
				throw new DataLengthException("input too large for ElGamal cipher.\n");

			BigInteger p = key.Parameters.P;

			byte[] output;
			if (key is ElGamalPrivateKeyParameters) // decryption
			{
				int halfLength = length / 2;
				BigInteger gamma = new BigInteger(1, input, inOff, halfLength);
				BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength);

				ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters) key;

				// a shortcut, which generally relies on p being prime amongst other things.
				// if a problem with this shows up, check the p and g values!
				BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p);

				output = m.ToByteArrayUnsigned();
			}
			else // encryption
			{
				BigInteger tmp = new BigInteger(1, input, inOff, length);

				if (tmp.BitLength >= p.BitLength)
					throw new DataLengthException("input too large for ElGamal cipher.\n");


				ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters) key;

				BigInteger pSub2 = p.Subtract(BigInteger.Two);

				// TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated
				BigInteger k;
				do
				{
					k = new BigInteger(p.BitLength, random);
				}
				while (k.SignValue == 0 || k.CompareTo(pSub2) > 0);

				BigInteger g = key.Parameters.G;
				BigInteger gamma = g.ModPow(k, p);
				BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p);

				output = new byte[this.GetOutputBlockSize()];

				// TODO Add methods to allow writing BigInteger to existing byte array?
				byte[] out1 = gamma.ToByteArrayUnsigned();
				byte[] out2 = phi.ToByteArrayUnsigned();
				out1.CopyTo(output, output.Length / 2 - out1.Length);
				out2.CopyTo(output, output.Length - out2.Length);
			}

			return output;
		}
Esempio n. 14
0
		// 5.4 pg 29
		/**
         * return true if the value r and s represent a DSA signature for
         * the passed in message (for standard DSA the message should be
         * a SHA-1 hash of the real message to be verified).
         */
		public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
		{
			BigInteger n = key.Parameters.N;

			// r and s should both in the range [1,n-1]
			if(r.SignValue < 1 || s.SignValue < 1
				|| r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
			{
				return false;
			}

			BigInteger e = CalculateE(n, message);
			BigInteger c = s.ModInverse(n);

			BigInteger u1 = e.Multiply(c).Mod(n);
			BigInteger u2 = r.Multiply(c).Mod(n);

			ECPoint G = key.Parameters.G;
			ECPoint Q = ((ECPublicKeyParameters)key).Q;

			ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2);

			if(point.IsInfinity)
				return false;

			/*
             * If possible, avoid normalizing the point (to save a modular inversion in the curve field).
             * 
             * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
             * If the cofactor is known and small, we generate those possible field values and project each
             * of them to the same "denominator" (depending on the particular projective coordinates in use)
             * as the calculated point.X. If any of the projected values matches point.X, then we have:
             *     (point.X / Denominator mod p) mod n == r
             * as required, and verification succeeds.
             * 
             * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
             * the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
             */
			ECCurve curve = point.Curve;
			if(curve != null)
			{
				BigInteger cofactor = curve.Cofactor;
				if(cofactor != null && cofactor.CompareTo(Eight) <= 0)
				{
					ECFieldElement D = GetDenominator(curve.CoordinateSystem, point);
					if(D != null && !D.IsZero)
					{
						ECFieldElement X = point.XCoord;
						while(curve.IsValidFieldElement(r))
						{
							ECFieldElement R = curve.FromBigInteger(r).Multiply(D);
							if(R.Equals(X))
							{
								return true;
							}
							r = r.Add(n);
						}
						return false;
					}
				}
			}

			BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n);
			return v.Equals(r);
		}
Esempio n. 15
0
        public bool RabinMillerTest(int certainty, Random random)
        {
            Debug.Assert(certainty > 0);
            Debug.Assert(BitLength > 2);
            Debug.Assert(TestBit(0));

            // let n = 1 + d . 2^s
            BigInteger n = this;
            int s = n.GetLowestSetBitMaskFirst(-1 << 1);
            Debug.Assert(s >= 1);
            BigInteger r = n.ShiftRight(s);

            // NOTE: Avoid conversion to/from Montgomery form and check for R/-R as result instead

            BigInteger montRadix = One.ShiftLeft(32 * n.magnitude.Length).Remainder(n);
            BigInteger minusMontRadix = n.Subtract(montRadix);

            do
            {
                BigInteger a;
                do
                {
                    a = new BigInteger(n.BitLength, random);
                }
                while (a.sign == 0 || a.CompareTo(n) >= 0
                    || a.IsEqualMagnitude(montRadix) || a.IsEqualMagnitude(minusMontRadix));

                BigInteger y = ModPowMonty(a, r, n, false);

                if (!y.Equals(montRadix))
                {
                    int j = 0;
                    while (!y.Equals(minusMontRadix))
                    {
                        if (++j == s)
                            return false;

                        y = ModPowMonty(y, Two, n, false);

                        if (y.Equals(montRadix))
                            return false;
                    }
                }

                certainty -= 2; // composites pass for only 1/4 possible 'a'
            }
            while (certainty > 0);

            return true;
        }
Esempio n. 16
0
		/**
		 * Set the private key.
		 *
		 * @param p   key parameter: field modulus
		 * @param q   key parameter: subgroup order
		 * @param g   key parameter: generator
		 * @param x   private key
		 */
		public void setPrivateKey(BigInteger p, BigInteger q,
				BigInteger g, BigInteger x)
		{
			/*
			 * Perform some basic sanity checks.  We do not
			 * check primality of p or q because that would
			 * be too expensive.
			 *
			 * We reject keys where q is longer than 999 bits,
			 * because it would complicate signature encoding.
			 * Normal DSA keys do not have a q longer than 256
			 * bits anyway.
			 */
			if(p == null || q == null || g == null || x == null
					|| p.SignValue <= 0 || q.SignValue <= 0
					|| g.SignValue <= 0 || x.SignValue <= 0
					|| x.CompareTo(q) >= 0 || q.CompareTo(p) >= 0
					|| q.BitLength > 999
					|| g.CompareTo(p) >= 0 || g.BitLength == 1
					|| g.ModPow(q, p).BitLength != 1)
			{
				throw new InvalidOperationException(
						"invalid DSA private key");
			}
			this.p = p;
			this.q = q;
			this.g = g;
			this.x = x;
			qlen = q.BitLength;
			if(q.SignValue <= 0 || qlen < 8)
			{
				throw new InvalidOperationException(
						"bad group order: " + q);

			}
			rolen = (qlen + 7) >> 3;
			rlen = rolen * 8;

			/*
			 * Convert the private exponent (x) into a sequence
			 * of octets.
			 */
			bx = int2octets(x);
		}
Esempio n. 17
0
        private static BigInteger ReduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu)
        {
            int xLen = x.BitLength, mLen = m.BitLength;
            if (xLen < mLen)
                return x;

            if (xLen - mLen > 1)
            {
                int k = m.magnitude.Length;

                BigInteger q1 = x.DivideWords(k - 1);
                BigInteger q2 = q1.Multiply(yu); // TODO Only need partial multiplication here
                BigInteger q3 = q2.DivideWords(k + 1);

                BigInteger r1 = x.RemainderWords(k + 1);
                BigInteger r2 = q3.Multiply(m); // TODO Only need partial multiplication here
                BigInteger r3 = r2.RemainderWords(k + 1);

                x = r1.Subtract(r3);
                if (x.sign < 0)
                {
                    x = x.Add(mr);
                }
            }

            while (x.CompareTo(m) >= 0)
            {
                x = x.Subtract(m);
            }

            return x;
        }
Esempio n. 18
0
        /**
         * Given the domain parameters this routine generates an EC key
         * pair in accordance with X9.62 section 5.2.1 pages 26, 27.
         */
        public AsymmetricCipherKeyPair GenerateKeyPair()
        {
            BigInteger n = parameters.N;
            BigInteger d;
            int minWeight = n.BitLength >> 2;

            for (;;)
            {
                d = new BigInteger(n.BitLength, random);

                if (d.CompareTo(BigInteger.Two) < 0 || d.CompareTo(n) >= 0)
                    continue;

                /*
                 * Require a minimum weight of the NAF representation, since low-weight primes may be
                 * weak against a version of the number-field-sieve for the discrete-logarithm-problem.
                 * 
                 * See "The number field sieve for integers of low weight", Oliver Schirokauer.
                 */
                if (WNafUtilities.GetNafWeight(d) < minWeight)
                    continue;

                break;
            }

            ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, d);

            if (publicKeyParamSet != null)
            {
                return new AsymmetricCipherKeyPair(
                    new ECPublicKeyParameters(algorithm, q, publicKeyParamSet),
                    new ECPrivateKeyParameters(algorithm, d, publicKeyParamSet));
            }

            return new AsymmetricCipherKeyPair(
                new ECPublicKeyParameters(algorithm, q, parameters),
                new ECPrivateKeyParameters(algorithm, d, parameters));
        }
Esempio n. 19
0
		public PubKey Derivate(byte[] cc, uint nChild, out byte[] ccChild)
		{
			byte[] lr = null;
			byte[] l = new byte[32];
			byte[] r = new byte[32];
			if((nChild >> 31) == 0)
			{
				var pubKey = ToBytes();
				lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray());
			}
			else
			{
				throw new InvalidOperationException("A public key can't derivate an hardened child");
			}
			Array.Copy(lr, l, 32);
			Array.Copy(lr, 32, r, 0, 32);
			ccChild = r;


			BigInteger N = ECKey.CURVE.N;
			BigInteger parse256LL = new BigInteger(1, l);

			if(parse256LL.CompareTo(N) >= 0)
				throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again.");

			var q = ECKey.CURVE.G.Multiply(parse256LL).Add(ECKey.GetPublicKeyParameters().Q);
			if(q.IsInfinity)
				throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again.");

			var p = new NBitcoin.BouncyCastle.Math.EC.FpPoint(ECKey.CURVE.Curve, q.X, q.Y, true);
			return new PubKey(p.GetEncoded());
		}