Beispiel #1
0
        private static GroupElementP4 Select(int pos, sbyte b)
        {
            GroupElementP4 t;

            GroupElementP4 minust;
            var            bnegative = Negative(b);
            var            babs      = (byte)(b - ((-bnegative & b) << 1));

            t = new GroupElementP4
            {
                YplusX  = FieldElementOperations.Set1(),
                YminusX = FieldElementOperations.Set1(),
                XY2D    = FieldElementOperations.Set0()
            };

            var table = LookupTables.Base[pos];

            Cmov(ref t, ref table[0], Equal(babs, 1));
            Cmov(ref t, ref table[1], Equal(babs, 2));
            Cmov(ref t, ref table[2], Equal(babs, 3));
            Cmov(ref t, ref table[3], Equal(babs, 4));
            Cmov(ref t, ref table[4], Equal(babs, 5));
            Cmov(ref t, ref table[5], Equal(babs, 6));
            Cmov(ref t, ref table[6], Equal(babs, 7));
            Cmov(ref t, ref table[7], Equal(babs, 8));
            minust.YplusX  = t.YminusX;
            minust.YminusX = t.YplusX;
            minust.XY2D    = FieldElementOperations.Negate(ref t.XY2D);
            Cmov(ref t, ref minust, bnegative);

            return(t);
        }
Beispiel #2
0
        /// <summary>
        /// h = a * B
        /// where a = a[0]+256*a[1]+...+256^31 a[31]
        /// B is the Ed25519 base point (x,4/5) with x positive.
        ///
        /// Preconditions:
        /// a[31] <= 127
        /// </summary>
        /// <param name="a"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        internal static GroupElementP3 ScalarMultiplicationBase(byte[] a, int offset = 0)
        {
            GroupElementP3 h;

            var            e = new sbyte[64];
            sbyte          carry;
            GroupElementP1 r;
            GroupElementP2 s;
            GroupElementP4 t;
            int            i;

            for (i = 0; i < 32; ++i)
            {
                e[2 * i + 0] = (sbyte)((a[offset + i] >> 0) & 15);
                e[2 * i + 1] = (sbyte)((a[offset + i] >> 4) & 15);
            }
            /* each e[i] is between 0 and 15 */
            /* e[63] is between 0 and 7 */

            carry = 0;
            for (i = 0; i < 63; ++i)
            {
                e[i]   += carry;
                carry   = (sbyte)(e[i] + 8);
                carry >>= 4;
                e[i]   -= (sbyte)(carry << 4);
            }
            e[63] += carry;
            /* each e[i] is between -8 and 8 */

            h = new GroupElementP3
            {
                X = FieldElementOperations.Set0(),
                Y = FieldElementOperations.Set1(),
                Z = FieldElementOperations.Set1(),
                T = FieldElementOperations.Set0()
            };

            for (i = 1; i < 64; i += 2)
            {
                t = Select(i / 2, e[i]);
                r = Madd(ref h, ref t);
                h = P1ToP3(ref r);
            }

            r = P3ToP1(ref h);
            s = P1ToP2(ref r);

            r = P2ToP1(ref s);
            s = P1ToP2(ref r);

            r = P2ToP1(ref s);
            s = P1ToP2(ref r);

            r = P2ToP1(ref s);
            h = P1ToP3(ref r);

            for (i = 0; i < 64; i += 2)
            {
                t = Select(i / 2, e[i]);
                r = Madd(ref h, ref t);
                h = P1ToP3(ref r);
            }

            return(h);
        }
        private static FieldElement CalculateLadderStep(byte[] n, ref FieldElement p, int noffset = 0)
        {
            var          e = new byte[32];
            uint         i;
            FieldElement x1;
            FieldElement x2;
            FieldElement z2;
            FieldElement x3;
            FieldElement z3;
            int          pos;
            uint         swap;

            for (i = 0; i < 32; ++i)
            {
                e[i] = n[noffset + i];
            }
            ClampOperation.Clamp(e, 0);
            x1 = p;
            x2 = FieldElementOperations.Set1();
            z2 = FieldElementOperations.Set0();
            x3 = x1;
            z3 = FieldElementOperations.Set1();

            swap = 0;
            for (pos = 254; pos >= 0; --pos)
            {
                var b = (uint)(e[pos / 8] >> (pos & 7));
                b    &= 1;
                swap ^= b;
                FieldElementOperations.Swap(ref x2, ref x3, swap);
                FieldElementOperations.Swap(ref z2, ref z3, swap);
                swap = b;

                /* D = X3-Z3 */
                var tmp0 = FieldElementOperations.Sub(ref x3, ref z3);

                /* B = X2-Z2 */
                var tmp1 = FieldElementOperations.Sub(ref x2, ref z2);

                /* A = X2+Z2 */
                x2 = FieldElementOperations.Add(ref x2, ref z2);

                /* C = X3+Z3 */
                z2 = FieldElementOperations.Add(ref x3, ref z3);

                /* DA = D*A */
                z3 = FieldElementOperations.Multiplication(ref tmp0, ref x2);

                /* CB = C*B */
                z2 = FieldElementOperations.Multiplication(ref z2, ref tmp1);

                /* BB = B^2 */
                tmp0 = FieldElementOperations.Squared(ref tmp1);

                /* AA = A^2 */
                tmp1 = FieldElementOperations.Squared(ref x2);

                /* t0 = DA+CB */
                x3 = FieldElementOperations.Add(ref z3, ref z2);

                /* t1 = DA-CB */
                z2 = FieldElementOperations.Sub(ref z3, ref z2);

                /* X4 = AA*BB */
                x2 = FieldElementOperations.Multiplication(ref tmp1, ref tmp0);

                /* E = AA-BB */
                tmp1 = FieldElementOperations.Sub(ref tmp1, ref tmp0);

                /* t2 = t1^2 */
                z2 = FieldElementOperations.Squared(ref z2);

                /* t3 = a24*E */
                z3 = FieldElementOperations.Multiply121666(ref tmp1);

                /* X5 = t0^2 */
                x3 = FieldElementOperations.Squared(ref x3);

                /* t4 = BB+t3 */
                tmp0 = FieldElementOperations.Add(ref tmp0, ref z3);

                /* Z5 = X1*t2 */
                z3 = FieldElementOperations.Multiplication(ref x1, ref z2);

                /* Z4 = E*t4 */
                z2 = FieldElementOperations.Multiplication(ref tmp1, ref tmp0);
            }

            FieldElementOperations.Swap(ref x2, ref x3, swap);
            FieldElementOperations.Swap(ref z2, ref z3, swap);
            z2 = FieldElementOperations.Invert(ref z2);
            x2 = FieldElementOperations.Multiplication(ref x2, ref z2);
            var q = x2;

            Array.Clear(e, 0, e.Length);
            return(q);
        }