예제 #1
0
        internal Projective EcFullSub(Projective s, Projective t)
        {
            var u = new Projective()
            {
                x = t.x.Clone(), y = p.SubMod(t.y, p, negP), z = t.z.Clone()
            };
            var res = EcFullAdd(s, u);

            u.Clear();
            return(res);
        }
예제 #2
0
        internal Projective EcDouble(Projective s)
        {
            var size = s.x.Length;

            var t1 = s.x;
            var t2 = s.y;
            var t3 = s.z;

            if (t3.IsZero())
            {
                return(new Projective()
                {
                    x = new BigInt(1, size), y = new BigInt(1, size), z = new BigInt(0, size)
                });
            }
            var t4      = modp(t3 * t3);
            var t5      = t1.SubMod(t4, p, negP);
            var t4_2    = t1.AddMod(t4, p, negP);
            var t5_2    = modp(t4_2 * t5);
            var t4_3    = t5_2.Mul3Mod(p, negP);
            var t3_2    = modp(t3 * t2);
            var t3_3    = t3_2.AddMod(t3_2, p, negP);
            var t2_2    = modp(t2 * t2);
            var t5_3    = modp(t1 * t2_2);
            var t5_4    = t5_3.Mul4Mod(p, negP);
            var t1_2    = modp(t4_3 * t4_3);
            var t1_3tmp = t1_2.SubMod(t5_4, p, negP);
            var t1_3    = t1_3tmp.SubMod(t5_4, p, negP);
            var t2_3    = modp(t2_2 * t2_2);
            var t2_4    = t2_3.Mul8Mod(p, negP);
            var t5_5    = t5_4.SubMod(t1_3, p, negP);
            var t5_6    = modp(t4_3 * t5_5);
            var t2_5    = t5_6.SubMod(t2_4, p, negP);

            t4.Clear();
            t5.Clear();
            t4_2.Clear();
            t5_2.Clear();
            t4_3.Clear();
            t3_2.Clear();
            t2_2.Clear();
            t5_3.Clear();
            t5_4.Clear();
            t1_2.Clear();
            t1_3tmp.Clear();
            t2_3.Clear();
            t2_4.Clear();
            t5_5.Clear();
            t5_6.Clear();
            return(new Projective()
            {
                x = t1_3, y = t2_5, z = t3_3
            });
        }
예제 #3
0
        internal Projective EcMult(BigInt d, Projective s)
        {
            var size = s.x.Length;

            if (d.IsZero() || s.z.IsZero())
            {
                return(new Projective()
                {
                    x = new BigInt(1, size), y = new BigInt(1, size), z = new BigInt(0, size)
                });
            }
            if (d.IsOne())
            {
                return(s.Clone());
            }
            if (!s.z.IsOne())
            {
                var affine = EcAffinify(s);
                s = EcProjectify(affine);
                affine.Clear();
            }
            else
            {
                s = s.Clone();
            }
            var r = s.Clone();
            var h = d.Mul3();

            for (var i = h.BitCount() - 2; i >= 1; i--)
            {
                var rTmp = r;
                r = EcDouble(r);
                rTmp.Clear();

                if (h.BitAt(i) && !d.BitAt(i))
                {
                    var u = EcFullAdd(r, s);
                    r.Clear();
                    r = u;
                }
                else if (!h.BitAt(i) && d.BitAt(i))
                {
                    var u = EcFullSub(r, s);
                    r.Clear();
                    r = u;
                }
            }
            h.Clear();

            return(r);
        }
예제 #4
0
        internal Affine EcAffinify(Projective s)
        {
            Debug.Assert(!s.z.IsZero());

            var lambda  = s.z.ModInv(p, negP);
            var lambda2 = modp(lambda * lambda);
            var lambda3 = modp(lambda2 * lambda);

            var res = new Affine()
            {
                x = modp(lambda2 * s.x), y = modp(lambda3 * s.y)
            };

            lambda.Clear();
            lambda2.Clear();
            lambda3.Clear();
            return(res);
        }
예제 #5
0
        internal Projective EcFullAdd(Projective s, Projective t)
        {
            if (s.z.IsZero())
            {
                return(t.Clone());
            }
            if (t.z.IsZero())
            {
                return(s.Clone());
            }
            Projective r = EcAdd(s, t);

            if (r.x.IsZero() && r.y.IsZero() && r.z.IsZero())
            {
                return(EcDouble(s));
            }
            return(r);
        }
예제 #6
0
        internal Projective EcAdd(Projective s, Projective t)
        {
            var size = s.x.Length;

            var t1 = s.x.Clone();
            var t2 = s.y.Clone();
            var t3 = s.z.Clone();
            var t4 = t.x;
            var t5 = t.y;
            var t6 = t.z;

            if (!t.z.IsOne())
            {
                var t7_ = modp(t6 * t6);
                Assign(ref t1, modp(t1 * t7_));
                Assign(ref t7_, modp(t6 * t7_));
                Assign(ref t2, modp(t2 * t7_));
                t7_.Clear();
            }
            var t7 = modp(t3 * t3);

            t4 = modp(t4 * t7);
            Assign(ref t7, modp(t3 * t7));
            t5 = modp(t5 * t7);
            Assign(ref t4, t1.SubMod(t4, p, negP));
            Assign(ref t5, t2.SubMod(t5, p, negP));
            if (t4.IsZero())
            {
                t1.Clear();
                t2.Clear();
                t3.Clear();
                t4.Clear();
                t7.Clear();
                if (t5.IsZero())
                {
                    return(new Projective()
                    {
                        x = new BigInt(0, size), y = new BigInt(0, size), z = new BigInt(0, size)
                    });
                }
                else
                {
                    t5.Clear();
                    return(new Projective()
                    {
                        x = new BigInt(1, size), y = new BigInt(1, size), z = new BigInt(0, size)
                    });
                }
            }
            Assign(ref t1, t1.AddMod(t1, p, negP));
            Assign(ref t1, t1.SubMod(t4, p, negP));
            Assign(ref t2, t2.AddMod(t2, p, negP));
            Assign(ref t2, t2.SubMod(t5, p, negP));
            if (!t.z.IsOne())
            {
                Assign(ref t3, modp(t3 * t6));
            }
            Assign(ref t3, modp(t3 * t4));
            Assign(ref t7, modp(t4 * t4));
            Assign(ref t4, modp(t4 * t7));
            Assign(ref t7, modp(t1 * t7));
            Assign(ref t1, modp(t5 * t5));
            Assign(ref t1, t1.SubMod(t7, p, negP));
            Assign(ref t7, t7.SubMod(t1, p, negP));
            Assign(ref t7, t7.SubMod(t1, p, negP));
            Assign(ref t5, modp(t5 * t7));
            Assign(ref t4, modp(t2 * t4));
            Assign(ref t2, t5.SubMod(t4, p, negP));
            t2.Div2(p);
            t4.Clear();
            t5.Clear();
            t7.Clear();
            return(new Projective()
            {
                x = t1, y = t2, z = t3
            });
        }
예제 #7
0
        internal Projective EcTwinMult(BigInt d0, Projective S, BigInt d1, Projective T)
        {
            var d = new BigInt[2] {
                d0, d1
            };

            var SpT = EcFullAdd(S, T);
            var SmT = EcFullSub(S, T);

            var m0 = d0.BitCount();
            var m1 = d1.BitCount();
            var m  = Math.Max(m0, m1);

            var c = new int[2][];

            c[0] = new int[6] {
                0, 0, d0.BitAt(m - 1) ? 1 : 0, d0.BitAt(m - 2) ? 1 : 0, d0.BitAt(m - 3) ? 1 : 0, d0.BitAt(m - 4) ? 1 : 0
            };
            c[1] = new int[6] {
                0, 0, d1.BitAt(m - 1) ? 1 : 0, d1.BitAt(m - 2) ? 1 : 0, d1.BitAt(m - 3) ? 1 : 0, d1.BitAt(m - 4) ? 1 : 0
            };

            var R = new Projective()
            {
                x = new BigInt(1, S.x.Length), y = new BigInt(1, S.x.Length), z = new BigInt(0, S.x.Length)
            };

            int[] h = new int[2], u = new int[2];

            for (var k = m; k >= 0; k--)
            {
                for (var i = 0; i <= 1; i++)
                {
                    h[i] = (c[i][1] << 4) + (c[i][2] << 3) + (c[i][3] << 2) + (c[i][4] << 1) + c[i][5];
                    if (c[i][0] == 1)
                    {
                        h[i] = 31 - h[i];
                    }
                }
                for (var i = 0; i <= 1; i++)
                {
                    var t = h[1 - i];
                    int f;
                    if (18 <= t && t < 22)
                    {
                        f = 9;
                    }
                    else if (14 <= t && t < 18)
                    {
                        f = 10;
                    }
                    else if (22 <= t && t < 24)
                    {
                        f = 11;
                    }
                    else if (4 <= t && t < 12)
                    {
                        f = 14;
                    }
                    else
                    {
                        f = 12;
                    }
                    if (h[i] < f)
                    {
                        u[i] = 0;
                    }
                    else
                    {
                        u[i] = (c[i][0] & 1) != 0 ? -1 : 1;
                    }
                }
                for (var i = 0; i < 2; i++)
                {
                    c[i][0] = ((u[i] != 0) ^ (c[i][1] != 0)) ? 1 : 0;
                    c[i][1] = c[i][2];
                    c[i][2] = c[i][3];
                    c[i][3] = c[i][4];
                    c[i][4] = c[i][5];
                    c[i][5] = d[i].BitAt(k - 5) ? 1 : 0;
                }
                R = EcDouble(R);
                if (u[0] == -1)
                {
                    if (u[1] == -1)
                    {
                        R = EcFullSub(R, SpT);
                    }
                    else if (u[1] == 0)
                    {
                        R = EcFullSub(R, S);
                    }
                    else
                    {
                        R = EcFullSub(R, SmT);
                    }
                }
                else if (u[0] == 0)
                {
                    if (u[1] == -1)
                    {
                        R = EcFullSub(R, T);
                    }
                    else if (u[1] == 1)
                    {
                        R = EcFullAdd(R, T);
                    }
                }
                else if (u[0] == 1)
                {
                    if (u[1] == -1)
                    {
                        R = EcFullAdd(R, SmT);
                    }
                    else if (u[1] == 0)
                    {
                        R = EcFullAdd(R, S);
                    }
                    else
                    {
                        R = EcFullAdd(R, SpT);
                    }
                }
            }

            return(R);
        }