示例#1
0
        /**
         * Partial modular reduction modulo
         * <code>(&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>.
         * @param k The integer to be reduced.
         * @param m The bitlength of the underlying finite field.
         * @param a The parameter <code>a</code> of the elliptic curve.
         * @param s The auxiliary values <code>s<sub>0</sub></code> and
         * <code>s<sub>1</sub></code>.
         * @param mu The parameter &#956; of the elliptic curve.
         * @param c The precision (number of bits of accuracy) of the partial
         * modular reduction.
         * @return <code>&#961; := k partmod (&#964;<sup>m</sup> - 1)/(&#964; - 1)</code>
         */
        public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a,
                                                   BigInteger[] s, sbyte mu, sbyte c)
        {
            // d0 = s[0] + mu*s[1]; mu is either 1 or -1
            BigInteger d0;

            if (mu == 1)
            {
                d0 = s[0].Add(s[1]);
            }
            else
            {
                d0 = s[0].Subtract(s[1]);
            }

            BigInteger[] v  = GetLucas(mu, m, true);
            BigInteger   vm = v[1];

            SimpleBigDecimal lambda0 = ApproximateDivisionByN(
                k, s[0], vm, a, m, c);

            SimpleBigDecimal lambda1 = ApproximateDivisionByN(
                k, s[1], vm, a, m, c);

            ZTauElement q = Round(lambda0, lambda1, mu);

            // r0 = n - d0*q0 - 2*s1*q1
            BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract(
                BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v));

            // r1 = s1*q0 - s0*q1
            BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v));

            return(new ZTauElement(r0, r1));
        }
示例#2
0
        /**
         * Computes the norm of an element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @return The norm of <code>&#955;</code>.
         */
        public static BigInteger Norm(sbyte mu, ZTauElement lambda)
        {
            BigInteger norm;

            // s1 = u^2
            BigInteger s1 = lambda.u.Multiply(lambda.u);

            // s2 = u * v
            BigInteger s2 = lambda.u.Multiply(lambda.v);

            // s3 = 2 * v^2
            BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1);

            if (mu == 1)
            {
                norm = s1.Add(s2).Add(s3);
            }
            else if (mu == -1)
            {
                norm = s1.Subtract(s2).Add(s3);
            }
            else
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            return(norm);
        }
示例#3
0
        /**
         * Multiplies a {@link NBitcoin.BouncyCastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
         * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
         * using the <code>&#964;</code>-adic NAF (TNAF) method.
         * @param p The AbstractF2mPoint to Multiply.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @return <code>&#955; * p</code>
         */
        public static AbstractF2mPoint MultiplyTnaf(AbstractF2mPoint p, ZTauElement lambda)
        {
            var   curve = (AbstractF2mCurve)p.Curve;
            sbyte mu    = GetMu(curve.A);

            sbyte[] u = TauAdicNaf(mu, lambda);

            AbstractF2mPoint q = MultiplyFromTnaf(p, u);

            return(q);
        }
示例#4
0
文件: Tnaf.cs 项目: wnf0000/NBitcoin
        /**
         * Multiplies a {@link NBitcoin.BouncyCastle.math.ec.F2mPoint F2mPoint}
         * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
         * using the <code>&#964;</code>-adic NAF (TNAF) method.
         * @param p The F2mPoint to Multiply.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @return <code>&#955; * p</code>
         */
        public static F2mPoint MultiplyTnaf(F2mPoint p, ZTauElement lambda)
        {
            F2mCurve curve = (F2mCurve)p.Curve;
            sbyte    mu    = curve.GetMu();

            sbyte[] u = TauAdicNaf(mu, lambda);

            F2mPoint q = MultiplyFromTnaf(p, u);

            return(q);
        }
示例#5
0
        /**
        * Multiplies a {@link NBitcoin.BouncyCastle.math.ec.F2mPoint F2mPoint}
        * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code> using
        * the <code>&#964;</code>-adic NAF (TNAF) method.
        * @param p The F2mPoint to multiply.
        * @param lambda The element <code>&#955;</code> of
        * <code><b>Z</b>[&#964;]</code> of which to compute the
        * <code>[&#964;]</code>-adic NAF.
        * @return <code>p</code> multiplied by <code>&#955;</code>.
        */
        private F2mPoint MultiplyWTnaf(F2mPoint p, ZTauElement lambda,
            PreCompInfo preCompInfo, sbyte a, sbyte mu)
        {
            ZTauElement[] alpha = (a == 0) ? Tnaf.Alpha0 : Tnaf.Alpha1;

            BigInteger tw = Tnaf.GetTw(mu, Tnaf.Width);

            sbyte[]u = Tnaf.TauAdicWNaf(mu, lambda, Tnaf.Width,
                BigInteger.ValueOf(Tnaf.Pow2Width), tw, alpha);

            return MultiplyFromWTnaf(p, u, preCompInfo);
        }
示例#6
0
        /**
         * Multiplies a {@link NBitcoin.BouncyCastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
         * by a <code>BigInteger</code> using the reduced <code>&#964;</code>-adic
         * NAF (RTNAF) method.
         * @param p The AbstractF2mPoint to Multiply.
         * @param k The <code>BigInteger</code> by which to Multiply <code>p</code>.
         * @return <code>k * p</code>
         */
        public static AbstractF2mPoint MultiplyRTnaf(AbstractF2mPoint p, BigInteger k)
        {
            var   curve = (AbstractF2mCurve)p.Curve;
            int   m     = curve.FieldSize;
            int   a     = curve.A.ToBigInteger().IntValue;
            sbyte mu    = GetMu(a);

            BigInteger[] s   = curve.GetSi();
            ZTauElement  rho = PartModReduction(k, m, (sbyte)a, s, mu, (sbyte)10);

            return(MultiplyTnaf(p, rho));
        }
示例#7
0
文件: Tnaf.cs 项目: wnf0000/NBitcoin
        /**
         * Multiplies a {@link NBitcoin.BouncyCastle.math.ec.F2mPoint F2mPoint}
         * by a <code>BigInteger</code> using the reduced <code>&#964;</code>-adic
         * NAF (RTNAF) method.
         * @param p The F2mPoint to Multiply.
         * @param k The <code>BigInteger</code> by which to Multiply <code>p</code>.
         * @return <code>k * p</code>
         */
        public static F2mPoint MultiplyRTnaf(F2mPoint p, BigInteger k)
        {
            F2mCurve curve = (F2mCurve)p.Curve;
            int      m     = curve.M;
            sbyte    a     = (sbyte)curve.A.ToBigInteger().IntValue;
            sbyte    mu    = curve.GetMu();

            BigInteger[] s   = curve.GetSi();
            ZTauElement  rho = PartModReduction(k, m, a, s, mu, (sbyte)10);

            return(MultiplyTnaf(p, rho));
        }
示例#8
0
文件: Tnaf.cs 项目: crowar/NBitcoin
		/**
        * Computes the norm of an element <code>&#955;</code> of
        * <code><b>Z</b>[&#964;]</code>.
        * @param mu The parameter <code>&#956;</code> of the elliptic curve.
        * @param lambda The element <code>&#955;</code> of
        * <code><b>Z</b>[&#964;]</code>.
        * @return The norm of <code>&#955;</code>.
        */
		public static BigInteger Norm(sbyte mu, ZTauElement lambda)
		{
			BigInteger norm;

			// s1 = u^2
			BigInteger s1 = lambda.u.Multiply(lambda.u);

			// s2 = u * v
			BigInteger s2 = lambda.u.Multiply(lambda.v);

			// s3 = 2 * v^2
			BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1);

			if(mu == 1)
			{
				norm = s1.Add(s2).Add(s3);
			}
			else if(mu == -1)
			{
				norm = s1.Subtract(s2).Add(s3);
			}
			else
			{
				throw new ArgumentException("mu must be 1 or -1");
			}

			return norm;
		}
示例#9
0
文件: Tnaf.cs 项目: crowar/NBitcoin
		/**
        * Computes the <code>[&#964;]</code>-adic window NAF of an element
        * <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
        * @param mu The parameter &#956; of the elliptic curve.
        * @param lambda The element <code>&#955;</code> of
        * <code><b>Z</b>[&#964;]</code> of which to compute the
        * <code>[&#964;]</code>-adic NAF.
        * @param width The window width of the resulting WNAF.
        * @param pow2w 2<sup>width</sup>.
        * @param tw The auxiliary value <code>t<sub>w</sub></code>.
        * @param alpha The <code>&#945;<sub>u</sub></code>'s for the window width.
        * @return The <code>[&#964;]</code>-adic window NAF of
        * <code>&#955;</code>.
        */
		public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda,
			sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
		{
			if(!((mu == 1) || (mu == -1)))
				throw new ArgumentException("mu must be 1 or -1");

			BigInteger norm = Norm(mu, lambda);

			// Ceiling of log2 of the norm 
			int log2Norm = norm.BitLength;

			// If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
			int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width;

			// The array holding the TNAF
			sbyte[] u = new sbyte[maxLength];

			// 2^(width - 1)
			BigInteger pow2wMin1 = pow2w.ShiftRight(1);

			// Split lambda into two BigIntegers to simplify calculations
			BigInteger r0 = lambda.u;
			BigInteger r1 = lambda.v;
			int i = 0;

			// while lambda <> (0, 0)
			while(!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
			{
				// if r0 is odd
				if(r0.TestBit(0))
				{
					// uUnMod = r0 + r1*tw Mod 2^width
					BigInteger uUnMod
						= r0.Add(r1.Multiply(tw)).Mod(pow2w);

					sbyte uLocal;
					// if uUnMod >= 2^(width - 1)
					if(uUnMod.CompareTo(pow2wMin1) >= 0)
					{
						uLocal = (sbyte)uUnMod.Subtract(pow2w).IntValue;
					}
					else
					{
						uLocal = (sbyte)uUnMod.IntValue;
					}
					// uLocal is now in [-2^(width-1), 2^(width-1)-1]

					u[i] = uLocal;
					bool s = true;
					if(uLocal < 0)
					{
						s = false;
						uLocal = (sbyte)-uLocal;
					}
					// uLocal is now >= 0

					if(s)
					{
						r0 = r0.Subtract(alpha[uLocal].u);
						r1 = r1.Subtract(alpha[uLocal].v);
					}
					else
					{
						r0 = r0.Add(alpha[uLocal].u);
						r1 = r1.Add(alpha[uLocal].v);
					}
				}
				else
				{
					u[i] = 0;
				}

				BigInteger t = r0;

				if(mu == 1)
				{
					r0 = r1.Add(r0.ShiftRight(1));
				}
				else
				{
					// mu == -1
					r0 = r1.Subtract(r0.ShiftRight(1));
				}
				r1 = t.ShiftRight(1).Negate();
				i++;
			}
			return u;
		}
示例#10
0
文件: Tnaf.cs 项目: crowar/NBitcoin
		/**
        * Multiplies a {@link NBitcoin.BouncyCastle.math.ec.AbstractF2mPoint AbstractF2mPoint}
        * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
        * using the <code>&#964;</code>-adic NAF (TNAF) method.
        * @param p The AbstractF2mPoint to Multiply.
        * @param lambda The element <code>&#955;</code> of
        * <code><b>Z</b>[&#964;]</code>.
        * @return <code>&#955; * p</code>
        */
		public static AbstractF2mPoint MultiplyTnaf(AbstractF2mPoint p, ZTauElement lambda)
		{
			AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve;
			sbyte mu = GetMu(curve.A);
			sbyte[] u = TauAdicNaf(mu, lambda);

			AbstractF2mPoint q = MultiplyFromTnaf(p, u);

			return q;
		}
示例#11
0
文件: Tnaf.cs 项目: crowar/NBitcoin
		/**
        * Computes the <code>&#964;</code>-adic NAF (non-adjacent form) of an
        * element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
        * @param mu The parameter <code>&#956;</code> of the elliptic curve.
        * @param lambda The element <code>&#955;</code> of
        * <code><b>Z</b>[&#964;]</code>.
        * @return The <code>&#964;</code>-adic NAF of <code>&#955;</code>.
        */
		public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda)
		{
			if(!((mu == 1) || (mu == -1)))
				throw new ArgumentException("mu must be 1 or -1");

			BigInteger norm = Norm(mu, lambda);

			// Ceiling of log2 of the norm 
			int log2Norm = norm.BitLength;

			// If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
			int maxLength = log2Norm > 30 ? log2Norm + 4 : 34;

			// The array holding the TNAF
			sbyte[] u = new sbyte[maxLength];
			int i = 0;

			// The actual length of the TNAF
			int length = 0;

			BigInteger r0 = lambda.u;
			BigInteger r1 = lambda.v;

			while(!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
			{
				// If r0 is odd
				if(r0.TestBit(0))
				{
					u[i] = (sbyte)BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue;

					// r0 = r0 - u[i]
					if(u[i] == 1)
					{
						r0 = r0.ClearBit(0);
					}
					else
					{
						// u[i] == -1
						r0 = r0.Add(BigInteger.One);
					}
					length = i;
				}
				else
				{
					u[i] = 0;
				}

				BigInteger t = r0;
				BigInteger s = r0.ShiftRight(1);
				if(mu == 1)
				{
					r0 = r1.Add(s);
				}
				else
				{
					// mu == -1
					r0 = r1.Subtract(s);
				}

				r1 = t.ShiftRight(1).Negate();
				i++;
			}

			length++;

			// Reduce the TNAF array to its actual length
			sbyte[] tnaf = new sbyte[length];
			Array.Copy(u, 0, tnaf, 0, length);
			return tnaf;
		}
示例#12
0
        /**
         * Computes the <code>[&#964;]</code>-adic window NAF of an element
         * <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter &#956; of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code> of which to compute the
         * <code>[&#964;]</code>-adic NAF.
         * @param width The window width of the resulting WNAF.
         * @param pow2w 2<sup>width</sup>.
         * @param tw The auxiliary value <code>t<sub>w</sub></code>.
         * @param alpha The <code>&#945;<sub>u</sub></code>'s for the window width.
         * @return The <code>[&#964;]</code>-adic window NAF of
         * <code>&#955;</code>.
         */
        public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda,
                                          sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha)
        {
            if (!((mu == 1) || (mu == -1)))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            BigInteger norm = Norm(mu, lambda);

            // Ceiling of log2 of the norm
            int log2Norm = norm.BitLength;

            // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
            int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width;

            // The array holding the TNAF
            var u = new sbyte[maxLength];

            // 2^(width - 1)
            BigInteger pow2wMin1 = pow2w.ShiftRight(1);

            // Split lambda into two BigIntegers to simplify calculations
            BigInteger r0 = lambda.u;
            BigInteger r1 = lambda.v;
            int        i  = 0;

            // while lambda <> (0, 0)
            while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
            {
                // if r0 is odd
                if (r0.TestBit(0))
                {
                    // uUnMod = r0 + r1*tw Mod 2^width
                    BigInteger uUnMod
                        = r0.Add(r1.Multiply(tw)).Mod(pow2w);

                    sbyte uLocal;
                    // if uUnMod >= 2^(width - 1)
                    if (uUnMod.CompareTo(pow2wMin1) >= 0)
                    {
                        uLocal = (sbyte)uUnMod.Subtract(pow2w).IntValue;
                    }
                    else
                    {
                        uLocal = (sbyte)uUnMod.IntValue;
                    }
                    // uLocal is now in [-2^(width-1), 2^(width-1)-1]

                    u[i] = uLocal;
                    bool s = true;
                    if (uLocal < 0)
                    {
                        s      = false;
                        uLocal = (sbyte)-uLocal;
                    }
                    // uLocal is now >= 0

                    if (s)
                    {
                        r0 = r0.Subtract(alpha[uLocal].u);
                        r1 = r1.Subtract(alpha[uLocal].v);
                    }
                    else
                    {
                        r0 = r0.Add(alpha[uLocal].u);
                        r1 = r1.Add(alpha[uLocal].v);
                    }
                }
                else
                {
                    u[i] = 0;
                }

                BigInteger t = r0;

                if (mu == 1)
                {
                    r0 = r1.Add(r0.ShiftRight(1));
                }
                else
                {
                    // mu == -1
                    r0 = r1.Subtract(r0.ShiftRight(1));
                }
                r1 = t.ShiftRight(1).Negate();
                i++;
            }
            return(u);
        }
示例#13
0
        /**
         * Computes the <code>&#964;</code>-adic NAF (non-adjacent form) of an
         * element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>.
         * @param mu The parameter <code>&#956;</code> of the elliptic curve.
         * @param lambda The element <code>&#955;</code> of
         * <code><b>Z</b>[&#964;]</code>.
         * @return The <code>&#964;</code>-adic NAF of <code>&#955;</code>.
         */
        public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda)
        {
            if (!((mu == 1) || (mu == -1)))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            BigInteger norm = Norm(mu, lambda);

            // Ceiling of log2 of the norm
            int log2Norm = norm.BitLength;

            // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52
            int maxLength = log2Norm > 30 ? log2Norm + 4 : 34;

            // The array holding the TNAF
            var u = new sbyte[maxLength];
            int i = 0;

            // The actual length of the TNAF
            int length = 0;

            BigInteger r0 = lambda.u;
            BigInteger r1 = lambda.v;

            while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero))))
            {
                // If r0 is odd
                if (r0.TestBit(0))
                {
                    u[i] = (sbyte)BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue;

                    // r0 = r0 - u[i]
                    if (u[i] == 1)
                    {
                        r0 = r0.ClearBit(0);
                    }
                    else
                    {
                        // u[i] == -1
                        r0 = r0.Add(BigInteger.One);
                    }
                    length = i;
                }
                else
                {
                    u[i] = 0;
                }

                BigInteger t = r0;
                BigInteger s = r0.ShiftRight(1);
                if (mu == 1)
                {
                    r0 = r1.Add(s);
                }
                else
                {
                    // mu == -1
                    r0 = r1.Subtract(s);
                }

                r1 = t.ShiftRight(1).Negate();
                i++;
            }

            length++;

            // Reduce the TNAF array to its actual length
            var tnaf = new sbyte[length];

            Array.Copy(u, 0, tnaf, 0, length);
            return(tnaf);
        }
示例#14
0
        /**
        * Multiplies a {@link NBitcoin.BouncyCastle.math.ec.F2mPoint F2mPoint}
        * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
        * using the <code>&#964;</code>-adic NAF (TNAF) method.
        * @param p The F2mPoint to Multiply.
        * @param lambda The element <code>&#955;</code> of
        * <code><b>Z</b>[&#964;]</code>.
        * @return <code>&#955; * p</code>
        */
        public static F2mPoint MultiplyTnaf(F2mPoint p, ZTauElement lambda)
        {
            F2mCurve curve = (F2mCurve)p.Curve;
            sbyte mu = curve.GetMu();
            sbyte[] u = TauAdicNaf(mu, lambda);

            F2mPoint q = MultiplyFromTnaf(p, u);

            return q;
        }