/**
         * Computes the Window NAF (non-adjacent Form) of an integer.
         * @param width The width <code>w</code> of the Window NAF. The width is
         * defined as the minimal number <code>w</code>, such that for any
         * <code>w</code> consecutive digits in the resulting representation, at
         * most one is non-zero.
         * @param k The integer of which the Window NAF is computed.
         * @return The Window NAF of the given width, such that the following holds:
         * <code>k = &#8722;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
         * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
         * returned <code>sbyte[]</code>.
         */
        public sbyte[] WindowNaf(sbyte width, IBigInteger k)
        {
            // The window NAF is at most 1 element longer than the binary
            // representation of the integer k. sbyte can be used instead of short or
            // int unless the window width is larger than 8. For larger width use
            // short or int. However, a width of more than 8 is not efficient for
            // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than
            // 1000 Bits are currently not used in practice.
            sbyte[] wnaf = new sbyte[k.BitLength + 1];

            // 2^width as short and BigInteger
            short       pow2wB  = (short)(1 << width);
            IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB);

            int i = 0;

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

            // while k >= 1
            while (k.SignValue > 0)
            {
                // if k is odd
                if (k.TestBit(0))
                {
                    // k Mod 2^width
                    IBigInteger remainder = k.Mod(pow2wBI);

                    // if remainder > 2^(width - 1) - 1
                    if (remainder.TestBit(width - 1))
                    {
                        wnaf[i] = (sbyte)(remainder.IntValue - pow2wB);
                    }
                    else
                    {
                        wnaf[i] = (sbyte)remainder.IntValue;
                    }
                    // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1]

                    k      = k.Subtract(BigInteger.ValueOf(wnaf[i]));
                    length = i;
                }
                else
                {
                    wnaf[i] = 0;
                }

                // k = k/2
                k = k.ShiftRight(1);
                i++;
            }

            length++;

            // Reduce the WNAF array to its actual length
            sbyte[] wnafShort = new sbyte[length];
            Array.Copy(wnaf, 0, wnafShort, 0, length);
            return(wnafShort);
        }
        public void TestSetBit()
        {
            Assert.AreEqual(one, zero.SetBit(0));
            Assert.AreEqual(one, one.SetBit(0));
            Assert.AreEqual(three, two.SetBit(0));

            Assert.AreEqual(two, zero.SetBit(1));
            Assert.AreEqual(three, one.SetBit(1));
            Assert.AreEqual(two, two.SetBit(1));

            // TODO Tests for setting bits in negative numbers

            // TODO Tests for setting extended bits

            for (int i = 0; i < 10; ++i)
            {
                IBigInteger n = new BigInteger(128, _random);

                for (int j = 0; j < 10; ++j)
                {
                    int         pos  = _random.Next(128);
                    IBigInteger m    = n.SetBit(pos);
                    bool        test = m.ShiftRight(pos).Remainder(two).Equals(one);

                    Assert.IsTrue(test);
                }
            }

            for (int i = 0; i < 100; ++i)
            {
                IBigInteger pow2      = one.ShiftLeft(i);
                IBigInteger minusPow2 = pow2.Negate();

                Assert.AreEqual(pow2, pow2.SetBit(i));
                Assert.AreEqual(minusPow2, minusPow2.SetBit(i));

                IBigInteger bigI = BigInteger.ValueOf(i);
                IBigInteger negI = bigI.Negate();

                for (int j = 0; j < 10; ++j)
                {
                    string data = "i=" + i + ", j=" + j;
                    Assert.AreEqual(bigI.Or(one.ShiftLeft(j)), bigI.SetBit(j), data);
                    Assert.AreEqual(negI.Or(one.ShiftLeft(j)), negI.SetBit(j), data);
                }
            }
        }
Example #3
0
        /**
         * Approximate division by <code>n</code>. For an integer
         * <code>k</code>, the value <code>&#955; = s k / n</code> is
         * computed to <code>c</code> bits of accuracy.
         * @param k The parameter <code>k</code>.
         * @param s The curve parameter <code>s<sub>0</sub></code> or
         * <code>s<sub>1</sub></code>.
         * @param vm The Lucas Sequence element <code>V<sub>m</sub></code>.
         * @param a The parameter <code>a</code> of the elliptic curve.
         * @param m The bit length of the finite field
         * <code><b>F</b><sub>m</sub></code>.
         * @param c The number of bits of accuracy, i.e. the scale of the returned
         * <code>SimpleBigDecimal</code>.
         * @return The value <code>&#955; = s k / n</code> computed to
         * <code>c</code> bits of accuracy.
         */
        public static SimpleBigDecimal ApproximateDivisionByN(IBigInteger k,
                                                              IBigInteger s, IBigInteger vm, sbyte a, int m, int c)
        {
            int         _k = (m + 5) / 2 + c;
            IBigInteger ns = k.ShiftRight(m - _k - 2 + a);

            IBigInteger gs = s.Multiply(ns);

            IBigInteger hs = gs.ShiftRight(m);

            IBigInteger js = vm.Multiply(hs);

            IBigInteger gsPlusJs = gs.Add(js);
            IBigInteger ls       = gsPlusJs.ShiftRight(_k - c);

            if (gsPlusJs.TestBit(_k - c - 1))
            {
                // round up
                ls = ls.Add(BigInteger.One);
            }

            return(new SimpleBigDecimal(ls, c));
        }
Example #4
0
        /// <summary>
        /// D.1.4 91
        /// return a sqrt root - the routine verifies that the calculation
        /// returns the right value - if none exists it returns null.
        /// </summary>
        /// <returns></returns>
        public override ECFieldElement Sqrt()
        {
            if (!_q.TestBit(0))
            {
                throw Platform.CreateNotImplementedException("even value of q");
            }

            // p mod 4 == 3
            if (_q.TestBit(1))
            {
                // TODO Can this be optimised (inline the Square?)
                // z = g^(u+1) + p, p = 4u + 3
                var z = new FPFieldElement(_q, _x.ModPow(_q.ShiftRight(2).Add(BigInteger.One), _q));

                return(z.Square().Equals(this) ? z : null);
            }

            // p mod 4 == 1
            var qMinusOne = _q.Subtract(BigInteger.One);

            var legendreExponent = qMinusOne.ShiftRight(1);

            if (!(_x.ModPow(legendreExponent, _q).Equals(BigInteger.One)))
            {
                return(null);
            }

            var u = qMinusOne.ShiftRight(2);
            var k = u.ShiftLeft(1).Add(BigInteger.One);

            var Q     = _x;
            var fourQ = Q.ShiftLeft(2).Mod(_q);

            IBigInteger U;
            IBigInteger V;

            do
            {
                IRandom     rand = new Random();
                IBigInteger P;
                do
                {
                    P = new BigInteger(_q.BitLength, rand);
                }while (P.CompareTo(_q) >= 0 ||
                        !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, _q).Equals(qMinusOne)));

                var result = FastLucasSequence(_q, P, Q, k);
                U = result[0];
                V = result[1];

                if (!V.Multiply(V).Mod(_q).Equals(fourQ))
                {
                    continue;
                }

                // Integer division by 2, mod q
                if (V.TestBit(0))
                {
                    V = V.Add(_q);
                }

                V = V.ShiftRight(1);

                Debug.Assert(V.Multiply(V).Mod(_q).Equals(_x));

                return(new FPFieldElement(_q, V));
            }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));

            return(null);
        }
        /**
        * 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, IBigInteger pow2w, IBigInteger tw, ZTauElement[] alpha)
        {
            if (!((mu == 1) || (mu == -1)))
                throw new ArgumentException("mu must be 1 or -1");

            IBigInteger 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)
            IBigInteger pow2wMin1 = pow2w.ShiftRight(1);

            // Split lambda into two BigIntegers to simplify calculations
            IBigInteger r0 = lambda.u;
            IBigInteger 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
                    IBigInteger 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;
                }

                IBigInteger 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;
        }
        /**
        * Approximate division by <code>n</code>. For an integer
        * <code>k</code>, the value <code>&#955; = s k / n</code> is
        * computed to <code>c</code> bits of accuracy.
        * @param k The parameter <code>k</code>.
        * @param s The curve parameter <code>s<sub>0</sub></code> or
        * <code>s<sub>1</sub></code>.
        * @param vm The Lucas Sequence element <code>V<sub>m</sub></code>.
        * @param a The parameter <code>a</code> of the elliptic curve.
        * @param m The bit length of the finite field
        * <code><b>F</b><sub>m</sub></code>.
        * @param c The number of bits of accuracy, i.e. the scale of the returned
        * <code>SimpleBigDecimal</code>.
        * @return The value <code>&#955; = s k / n</code> computed to
        * <code>c</code> bits of accuracy.
        */
        public static SimpleBigDecimal ApproximateDivisionByN(IBigInteger k,
            IBigInteger s, IBigInteger vm, sbyte a, int m, int c)
        {
            int _k = (m + 5)/2 + c;
            IBigInteger ns = k.ShiftRight(m - _k - 2 + a);

            IBigInteger gs = s.Multiply(ns);

            IBigInteger hs = gs.ShiftRight(m);

            IBigInteger js = vm.Multiply(hs);

            IBigInteger gsPlusJs = gs.Add(js);
            IBigInteger ls = gsPlusJs.ShiftRight(_k - c);
            if (gsPlusJs.TestBit(_k-c-1))
            {
                // round up
                ls = ls.Add(BigInteger.One);
            }

            return new SimpleBigDecimal(ls, c);
        }
        /**
        * Computes the Window NAF (non-adjacent Form) of an integer.
        * @param width The width <code>w</code> of the Window NAF. The width is
        * defined as the minimal number <code>w</code>, such that for any
        * <code>w</code> consecutive digits in the resulting representation, at
        * most one is non-zero.
        * @param k The integer of which the Window NAF is computed.
        * @return The Window NAF of the given width, such that the following holds:
        * <code>k = &#8722;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
        * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
        * returned <code>sbyte[]</code>.
        */
        public sbyte[] WindowNaf(sbyte width, IBigInteger k)
        {
            // The window NAF is at most 1 element longer than the binary
            // representation of the integer k. sbyte can be used instead of short or
            // int unless the window width is larger than 8. For larger width use
            // short or int. However, a width of more than 8 is not efficient for
            // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than
            // 1000 Bits are currently not used in practice.
            sbyte[] wnaf = new sbyte[k.BitLength + 1];

            // 2^width as short and BigInteger
            short pow2wB = (short)(1 << width);
            IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB);

            int i = 0;

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

            // while k >= 1
            while (k.SignValue > 0)
            {
                // if k is odd
                if (k.TestBit(0))
                {
                    // k Mod 2^width
                    IBigInteger remainder = k.Mod(pow2wBI);

                    // if remainder > 2^(width - 1) - 1
                    if (remainder.TestBit(width - 1))
                    {
                        wnaf[i] = (sbyte)(remainder.IntValue - pow2wB);
                    }
                    else
                    {
                        wnaf[i] = (sbyte)remainder.IntValue;
                    }
                    // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1]

                    k = k.Subtract(BigInteger.ValueOf(wnaf[i]));
                    length = i;
                }
                else
                {
                    wnaf[i] = 0;
                }

                // k = k/2
                k = k.ShiftRight(1);
                i++;
            }

            length++;

            // Reduce the WNAF array to its actual length
            sbyte[] wnafShort = new sbyte[length];
            Array.Copy(wnaf, 0, wnafShort, 0, length);
            return wnafShort;
        }
 public IBigInteger Floor()
 {
     return(bigInt.ShiftRight(scale));
 }
        /*
         * (non-Javadoc)
         *
         * @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#generateKeyPair()
         */
        public IAsymmetricCipherKeyPair GenerateKeyPair()
        {
            int           strength  = param.Strength;
            ISecureRandom rand      = param.Random;
            int           certainty = param.Certainty;
            bool          debug     = param.IsDebug;

#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("Fetching first " + param.CountSmallPrimes + " primes.");
            }
#endif

            IList smallPrimes = findFirstPrimes(param.CountSmallPrimes);

            smallPrimes = PermuteList(smallPrimes, rand);

            IBigInteger u = BigInteger.One;
            IBigInteger v = BigInteger.One;

            for (int i = 0; i < smallPrimes.Count / 2; i++)
            {
                u = u.Multiply((BigInteger)smallPrimes[i]);
            }
            for (int i = smallPrimes.Count / 2; i < smallPrimes.Count; i++)
            {
                v = v.Multiply((BigInteger)smallPrimes[i]);
            }

            IBigInteger sigma = u.Multiply(v);

            // n = (2 a u _p + 1 ) ( 2 b v _q + 1)
            // -> |n| = strength
            // |2| = 1 in bits
            // -> |a| * |b| = |n| - |u| - |v| - |_p| - |_q| - |2| -|2|
            // remainingStrength = strength - sigma.bitLength() - _p.bitLength() -
            // _q.bitLength() - 1 -1
            int         remainingStrength = strength - sigma.BitLength - 48;
            IBigInteger a = GeneratePrime(remainingStrength / 2 + 1, certainty, rand);
            IBigInteger b = GeneratePrime(remainingStrength / 2 + 1, certainty, rand);

            IBigInteger _p;
            IBigInteger _q;
            IBigInteger p;
            IBigInteger q;

            long tries = 0;
#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("generating p and q");
            }
#endif

            IBigInteger _2au = a.Multiply(u).ShiftLeft(1);
            IBigInteger _2bv = b.Multiply(v).ShiftLeft(1);

            for (; ;)
            {
                tries++;

                _p = GeneratePrime(24, certainty, rand);

                p = _p.Multiply(_2au).Add(BigInteger.One);

                if (!p.IsProbablePrime(certainty))
                {
                    continue;
                }

                for (; ;)
                {
                    _q = GeneratePrime(24, certainty, rand);

                    if (_p.Equals(_q))
                    {
                        continue;
                    }

                    q = _q.Multiply(_2bv).Add(BigInteger.One);

                    if (q.IsProbablePrime(certainty))
                    {
                        break;
                    }
                }

                if (!sigma.Gcd(_p.Multiply(_q)).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    Console.WriteLine("sigma.gcd(_p.mult(_q)) != 1!\n _p: " + _p + "\n _q: " + _q);
#endif
                    continue;
                }

                if (p.Multiply(q).BitLength < strength)
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("key size too small. Should be " + strength + " but is actually "
                                          + p.Multiply(q).BitLength);
                    }
#endif
                    continue;
                }
                break;
            }

#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("needed " + tries + " tries to generate p and q.");
            }
#endif

            IBigInteger n     = p.Multiply(q);
            IBigInteger phi_n = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One));
            IBigInteger g;
            tries = 0;
#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("generating g");
            }
#endif
            for (; ;)
            {
                // TODO After the first loop, just regenerate one randomly-selected gPart each time?
                IList gParts = Platform.CreateArrayList();
                for (int ind = 0; ind != smallPrimes.Count; ind++)
                {
                    IBigInteger i = (BigInteger)smallPrimes[ind];
                    IBigInteger e = phi_n.Divide(i);

                    for (; ;)
                    {
                        tries++;

                        g = GeneratePrime(strength, certainty, rand);

                        if (!g.ModPow(e, n).Equals(BigInteger.One))
                        {
                            gParts.Add(g);
                            break;
                        }
                    }
                }
                g = BigInteger.One;
                for (int i = 0; i < smallPrimes.Count; i++)
                {
                    IBigInteger gPart      = (BigInteger)gParts[i];
                    IBigInteger smallPrime = (BigInteger)smallPrimes[i];
                    g = g.Multiply(gPart.ModPow(sigma.Divide(smallPrime), n)).Mod(n);
                }

                // make sure that g is not divisible by p_i or q_i
                bool divisible = false;
                for (int i = 0; i < smallPrimes.Count; i++)
                {
                    if (g.ModPow(phi_n.Divide((BigInteger)smallPrimes[i]), n).Equals(BigInteger.One))
                    {
#if !NETFX_CORE
                        if (debug)
                        {
                            Console.WriteLine("g has order phi(n)/" + smallPrimes[i] + "\n g: " + g);
                        }
#endif
                        divisible = true;
                        break;
                    }
                }

                if (divisible)
                {
                    continue;
                }

                // make sure that g has order > phi_n/4

                //if (g.ModPow(phi_n.Divide(BigInteger.ValueOf(4)), n).Equals(BigInteger.One))
                if (g.ModPow(phi_n.ShiftRight(2), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/4\n g:" + g);
                    }
#endif
                    continue;
                }

                if (g.ModPow(phi_n.Divide(_p), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/p'\n g: " + g);
                    }
#endif
                    continue;
                }
                if (g.ModPow(phi_n.Divide(_q), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/q'\n g: " + g);
                    }
#endif
                    continue;
                }
                if (g.ModPow(phi_n.Divide(a), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/a\n g: " + g);
                    }
#endif
                    continue;
                }
                if (g.ModPow(phi_n.Divide(b), n).Equals(BigInteger.One))
                {
#if !NETFX_CORE
                    if (debug)
                    {
                        Console.WriteLine("g has order phi(n)/b\n g: " + g);
                    }
#endif
                    continue;
                }
                break;
            }
#if !NETFX_CORE
            if (debug)
            {
                Console.WriteLine("needed " + tries + " tries to generate g");
                Console.WriteLine();
                Console.WriteLine("found new NaccacheStern cipher variables:");
                Console.WriteLine("smallPrimes: " + CollectionUtilities.ToString(smallPrimes));
                Console.WriteLine("sigma:...... " + sigma + " (" + sigma.BitLength + " bits)");
                Console.WriteLine("a:.......... " + a);
                Console.WriteLine("b:.......... " + b);
                Console.WriteLine("p':......... " + _p);
                Console.WriteLine("q':......... " + _q);
                Console.WriteLine("p:.......... " + p);
                Console.WriteLine("q:.......... " + q);
                Console.WriteLine("n:.......... " + n);
                Console.WriteLine("phi(n):..... " + phi_n);
                Console.WriteLine("g:.......... " + g);
                Console.WriteLine();
            }
#endif

            return(new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.BitLength),
                                               new NaccacheSternPrivateKeyParameters(g, n, sigma.BitLength, smallPrimes, phi_n)));
        }
Example #10
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, IBigInteger pow2w, IBigInteger tw, ZTauElement[] alpha)
        {
            if (!((mu == 1) || (mu == -1)))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            IBigInteger 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)
            IBigInteger pow2wMin1 = pow2w.ShiftRight(1);

            // Split lambda into two BigIntegers to simplify calculations
            IBigInteger r0 = lambda.u;
            IBigInteger 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
                    IBigInteger 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;
                }

                IBigInteger 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);
        }
Example #11
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");
            }

            IBigInteger 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;

            IBigInteger r0 = lambda.u;
            IBigInteger 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;
                }

                IBigInteger t = r0;
                IBigInteger 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);
        }