コード例 #1
0
ファイル: ECPoint.cs プロジェクト: kazuki/opencrypto.net
        public static unsafe ECPoint MultiplyAndAdd(ECPoint p1, Number scaler1, ECPoint p2, Number scaler2)
        {
#if true
            int l = scaler1.BitCount();
            if (l < scaler2.BitCount())
            {
                l = scaler2.BitCount();
            }
            int *     b1    = stackalloc int[l >> 2];
            int *     b2    = stackalloc int[l >> 2];
            int *     e1    = stackalloc int[l >> 2];
            int *     e2    = stackalloc int[l >> 2];
            int       d1    = ComputeSignedWindowDecomposition(scaler1, b1, e1) - 1;
            int       d2    = ComputeSignedWindowDecomposition(scaler2, b2, e2) - 1;
            ECPoint[] p1ary = p1.SetupMultiplyHelperPoints();
            ECPoint[] p2ary = p2.SetupMultiplyHelperPoints();
            int       lastE;
            ECPoint   Q;
            if (e1[d1] == e2[d2])
            {
                Q     = p1ary[b1[d1]].Add(p2ary[b2[d2--]]);
                lastE = e1[d1--];
            }
            else if (e1[d1] > e2[d2])
            {
                Q     = p1ary[b1[d1]];
                lastE = e1[d1--];
            }
            else
            {
                Q     = p2ary[b2[d2]];
                lastE = e2[d2--];
            }
            while (d1 >= 0 || d2 >= 0)
            {
                int nextE;
                int nextType = 0;
                if (d1 >= 0 && d2 >= 0 && e1[d1] == e2[d2])
                {
                    nextE    = e1[d1];
                    nextType = 0;
                }
                else if ((d1 >= 0 && d2 < 0) || (d1 >= 0 && e1[d1] > e2[d2]))
                {
                    nextE    = e1[d1];
                    nextType = 1;
                }
                else
                {
                    nextE    = e2[d2];
                    nextType = 2;
                }
                for (int k = 0; k < lastE - nextE; k++)
                {
                    Q = Q.Double();
                }
                if (nextType == 0 || nextType == 1)
                {
                    if (b1[d1] > 0)
                    {
                        Q = Q.Add(p1ary[b1[d1--]]);
                    }
                    else
                    {
                        Q = Q.Add(p1ary[-b1[d1--]].Invert());
                    }
                }
                if (nextType == 0 || nextType == 2)
                {
                    if (b2[d2] > 0)
                    {
                        Q = Q.Add(p2ary[b2[d2--]]);
                    }
                    else
                    {
                        Q = Q.Add(p2ary[-b2[d2--]].Invert());
                    }
                }
                lastE = nextE;
            }
            for (int k = 0; k < lastE; k++)
            {
                Q = Q.Double();
            }
            return(Q);
#else
            int l = scaler1.BitCount();
            if (l < scaler2.BitCount())
            {
                l = scaler2.BitCount();
            }
            ECPoint Z = p1.Add(p2);
            ECPoint R = p1._field.GetInfinityPoint(p1._group);
            for (int i = l - 1; i >= 0; i--)
            {
                R = R.Double();
                uint ki = scaler1.GetBit(i);
                uint li = scaler2.GetBit(i);
                if (ki == 0)
                {
                    if (li == 1)
                    {
                        R = R.Add(p2);
                    }
                }
                else
                {
                    if (li == 0)
                    {
                        R = R.Add(p1);
                    }
                    else
                    {
                        R = R.Add(Z);
                    }
                }
            }
            return(R);
#endif
        }
コード例 #2
0
ファイル: ECPoint.cs プロジェクト: kazuki/opencrypto.net
        public unsafe ECPoint Multiply(Number scaler)
        {
            ECPoint[] P = SetupMultiplyHelperPoints();
#if true
            scaler = new Number(scaler, 1);
            int     l = scaler.BitCount() - 1;
            int *   b = stackalloc int [l >> 2];
            int *   e = stackalloc int[l >> 2];
            int     d = ComputeSignedWindowDecomposition(scaler, b, e);
            ECPoint Q = P[b[d - 1]];
            for (int i = d - 2; i >= 0; i--)
            {
                for (int k = 0; k < e[i + 1] - e[i]; k++)
                {
                    Q = Q.Double();
                }
                if (b[i] > 0)
                {
                    Q = Q.Add(P[b[i]]);
                }
                else
                {
                    Q = Q.Add(P[-b[i]].Invert());
                }
            }
            for (int k = 0; k < e[0]; k++)
            {
                Q = Q.Double();
            }
#else
#if true
            if (P == null)
            {
                P     = _multiplyHelperPoints = new ECPoint[16];
                P[1]  = this;
                P[2]  = this.Double();
                P[3]  = P[1].Add(P[2]);
                P[5]  = P[3].Add(P[2]);
                P[7]  = P[5].Add(P[2]);
                P[9]  = P[7].Add(P[2]);
                P[11] = P[9].Add(P[2]);
                P[13] = P[11].Add(P[2]);
                P[15] = P[13].Add(P[2]);
            }
            int     j = scaler.BitCount() - 1;
            ECPoint Q = _field.GetInfinityPoint(_group);
            while (j >= 0)
            {
                if (scaler.GetBit(j) == 0)
                {
                    Q = Q.Double();
                    j--;
                }
                else
                {
                    int  n = j - 1;
                    uint h = (1 << 3) | (scaler.GetBit(n--) << 2) | (scaler.GetBit(n--) << 1) | scaler.GetBit(n);
                    int  t = j - 3;
                    while ((h & 1) == 0)
                    {
                        h >>= 1;
                        t++;
                    }
                    for (int i = 1; i <= j - t + 1; i++)
                    {
                        Q = Q.Double();
                    }
                    Q = Q.Add(P[(int)h]);
                    j = t - 1;
                }
            }
#else
            ECPoint inv = Invert();
            if (P == null)
            {
                P     = _multiplyHelperPoints = new ECPoint[16];
                P[1]  = this;
                P[2]  = this.Double();
                P[3]  = P[1].Add(P[2]);
                P[5]  = P[3].Add(P[2]);
                P[7]  = P[5].Add(P[2]);
                P[9]  = P[7].Add(P[2]);
                P[11] = P[9].Add(P[2]);
                P[13] = P[11].Add(P[2]);
                P[15] = P[13].Add(P[2]);
            }
            int     j = scaler.BitCount() - 1;
            ECPoint Q = _field.GetInfinityPoint(_group);
            while (j >= 0)
            {
                uint continuous = scaler.GetContinuousBitCount(j);
                if (continuous == 0)
                {
                    Q = Q.Double();
                    j--;
                }
                else if (continuous <= 4)
                {
                    int  n = j - 1;
                    uint h = (1 << 3) | (scaler.GetBit(n--) << 2) | (scaler.GetBit(n--) << 1) | scaler.GetBit(n);
                    int  t = j - 3;
                    while ((h & 1) == 0)
                    {
                        h >>= 1;
                        t++;
                    }
                    for (int i = 1; i <= j - t + 1; i++)
                    {
                        Q = Q.Double();
                    }
                    Q = Q.Add(P[(int)h]);
                    j = t - 1;
                }
                else
                {
                    Q = Q.Add(this);
                    for (uint i = 0; i < continuous; i++)
                    {
                        Q = Q.Double();
                    }
                    Q  = Q.Add(inv);
                    j -= (int)continuous;
                }
            }
#endif
#endif
            return(Q);
        }