Ejemplo n.º 1
0
        private JacobianEcPoint Add(JacobianEcPoint p1, JacobianEcPoint p2)
        {
            if (p1.Inf)
            {
                return(p2);
            }
            if (p2.Inf)
            {
                return(p1);
            }

            var a = p1.X * p2.Z * p2.Z % P;
            var b = p2.X * p1.Z * p1.Z % P;
            var c = p1.Y * p2.Z * p2.Z * p2.Z % P;
            var d = p2.Y * p1.Z * p1.Z * p1.Z % P;
            var e = a - b;
            var f = c - d;

            if (e.IsZero)
            {
                return(f.IsZero ? Double(p1) : JacobianEcPoint.Infinity);
            }

            var x = f * f - e * e * e - 2 * b * e * e;
            var y = f * (b * e * e - x) - d * e * e * e;
            var z = p1.Z * p2.Z * e;

            x -= (x / P - (x.Sign < 0 ? 1 : 0)) * P;
            y -= (y / P - (y.Sign < 0 ? 1 : 0)) * P;
            z -= (z / P - (z.Sign < 0 ? 1 : 0)) * P;
            return(new JacobianEcPoint {
                X = x, Y = y, Z = z
            });
        }
Ejemplo n.º 2
0
        private JacobianEcPoint Negate(JacobianEcPoint p)
        {
            if (p.Inf)
            {
                return(p);
            }
            if (p.Y.IsZero)
            {
                return(p);
            }

            return(new JacobianEcPoint {
                X = p.X, Y = P - p.Y, Z = p.Z
            });
        }
Ejemplo n.º 3
0
        public EcPoint ToAffine(JacobianEcPoint jp)
        {
            if (jp.Inf)
            {
                return(EcPoint.Infinity);
            }
            if (jp.Affine)
            {
                return(new EcPoint(jp.X, jp.Y));
            }
            BigInteger x, y;
            var        zc = (jp.Z * jp.Z % P).InvMod(P);
            var        zd = (jp.Z * jp.Z * jp.Z % P).InvMod(P);

            x = jp.X * zc % P;
            y = jp.Y * zd % P;
            return(new EcPoint(x, y));
        }
Ejemplo n.º 4
0
        private JacobianEcPoint Double(JacobianEcPoint p)
        {
            if (p.Inf)
            {
                return(p);
            }
            if (p.Y.IsZero)
            {
                return(JacobianEcPoint.Infinity);
            }

            var a = p.X * p.Y * p.Y % P;
            var b = _inv2 * (3 * p.X * p.X + A * BigInteger.ModPow(p.Z, 4, P)) % P;
            var x = b * b - 2 * a;
            var y = b * (a - x) - BigInteger.ModPow(p.Y, 4, P);
            var z = p.Y * p.Z;

            x -= (x / P - (x.Sign < 0 ? 1 : 0)) * P;
            y -= (y / P - (y.Sign < 0 ? 1 : 0)) * P;
            z -= (z / P - (z.Sign < 0 ? 1 : 0)) * P;
            return(new JacobianEcPoint {
                X = x, Y = y, Z = z
            });
        }
Ejemplo n.º 5
0
        public JacobianEcPoint Multiply(BigInteger k, JacobianEcPoint p, AnyRng rng)
        {
            if (k.Sign < 0)
            {
                k = -k;
                p = Negate(p);
            }

            if (k.IsZero)
            {
                return(JacobianEcPoint.Infinity);
            }
            if (k.IsOne)
            {
                return(p);
            }

            var ks = rng.NextBigInt(BigInteger.One, k);

            // return MultiplyAndAdd(ks, p, k - ks, p, rng);
            var(k1, k2) = ToNafBytes(k - ks, ks);
            var i = 0;

            while (i < k1.Length - 1)
            {
                var c = k1[i].NafValue() + k2[i].NafValue();
                if (c != 0)
                {
                    i++;
                    continue;
                }

                if (k2[i + 1].NafValue() > 0)
                {
                    k2[i + 1] = (byte)((k2[i + 1].H() << 4) | ((k2[i + 1].L() - 1) & 0xF));
                    k2[i]     = (byte)(((k2[i].H() + 2) << 4) | (k2[i].L() & 0xF));
                }
                else
                {
                    k2[i + 1] = (byte)((k2[i + 1].H() << 4) | ((k2[i + 1].L() + 1) & 0xF));
                    k2[i]     = (byte)(((k2[i].H() - 2) << 4) | (k2[i].L() & 0xF));
                }
            }

            var lut = new [] {
                JacobianEcPoint.Infinity,
                p,
                Double(p),
                Add(Double(p), p),
                Double(Double(p))
            };

            var r = lut[k1.Back().NafValue() + k2.Back().NafValue()];

            for (i = k1.Length - 2; i >= 0; i--)
            {
                var c = k1[i].NafValue() + k2[i].NafValue();
                r = Add(Double(Double(r)), c < 0 ? Negate(lut[-c]) : lut[c]);
            }

            return(r);
        }
Ejemplo n.º 6
0
        public JacobianEcPoint MultiplyAndAdd(BigInteger k, JacobianEcPoint p, BigInteger m, JacobianEcPoint s, AnyRng rng)
        {
            if (k.Sign < 0)
            {
                k = -k;
                p = Negate(p);
            }
            if (m.Sign < 0)
            {
                m = -m;
                s = Negate(s);
            }

            if (k.IsZero)
            {
                return(Multiply(m, s, rng));
            }
            if (m.IsZero)
            {
                return(Multiply(k, p, rng));
            }
            if (k.IsOne)
            {
                return(Add(p, Multiply(m, s, rng)));
            }
            if (m.IsOne)
            {
                return(Add(s, Multiply(k, p, rng)));
            }

            var(kk, mm) = ToNafBytes(k, m);
            var i = 0;

            while (i < kk.Length - 1)
            {
                if (kk[i] != 0 || mm[i] != 0)
                {
                    i++;
                    continue;
                }

                switch (mm[i + 1])
                {
                case 0:
                    mm[i + 1] = 0x01;
                    mm[i]     = 0xE0;
                    break;

                case 0x0F:
                    mm[i + 1] = 0xF0;
                    mm[i]     = 0x20;
                    break;

                case 0x01:
                    mm[i + 1] = 0x10;
                    mm[i]     = 0xE0;
                    break;

                case 0xF0:
                    mm[i + 1] = 0x0F;
                    mm[i]     = 0xE0;
                    break;

                case 0x10:
                    mm[i + 1] = 0x01;
                    mm[i]     = 0x20;
                    break;

                default:
                    throw new Exception();
                }
            }

            var lut = new [] { // T[x,y] = lut[7x+y-1]
                s, Double(s), JacobianEcPoint.Infinity, Double(Double(s)),
                Add(p, Negate(Double(s))), Add(p, Negate(s)), p, Add(p, s), Add(p, Double(s)),
                JacobianEcPoint.Infinity, JacobianEcPoint.Infinity,
                Add(Double(p), Negate(Double(s))), Add(Double(p), Negate(s)),
                Double(p), Add(Double(p), s), Add(Double(p), Double(s))
            };

            var r = lut[kk.Back().NafValue() * 7 + mm.Back().NafValue() - 1];

            for (i = kk.Length - 2; i >= 0; i--)
            {
                r = Double(Double(r));
                if (kk[i] == 0)
                {
                    if (mm[i].NafValue() < 0)
                    {
                        r = Add(r, Negate(lut[-mm[i].NafValue() - 1]));
                    }
                    else
                    {
                        r = Add(r, lut[mm[i].NafValue() - 1]);
                    }
                }
                else if (kk[i].NafValue() < 0)
                {
                    r = Add(r, Negate(lut[-kk[i].NafValue() * 7 - mm[i].NafValue() - 1]));
                }
                else
                {
                    r = Add(r, lut[kk[i].NafValue() * 7 + mm[i].NafValue() - 1]);
                }
            }

            return(r);
        }