Пример #1
0
        static void fsquare(limb *output, limb *input)
        {
            Long19 t = new Long19();

            fsquare_inner(t.Items, input);
            freduce_degree(t.Items);
            freduce_coefficients(t.Items);
            memcpy(output, t.Items, sizeof(limb) * 10);
        }
Пример #2
0
        /* A helpful wrapper around fproduct: output = in * in2.
         *
         * output must be distinct to both inputs. The output is reduced degree and
         * reduced coefficient.
         */
        static void fmul(limb *output, limb *input, limb *in2)
        {
            Long19 t = new Long19();

            fproduct(t.Items, input, in2);
            freduce_degree(t.Items);
            freduce_coefficients(t.Items);
            memcpy(output, t.Items, sizeof(limb) * 10);
        }
Пример #3
0
        /* Input: Q, Q', Q-Q'
         * Output: 2Q, Q+Q'
         *
         *   x2 z3: long form
         *   x3 z3: long form
         *   x z: short form, destroyed
         *   xprime zprime: short form, destroyed
         *   qmqp: short form, preserved
         */
        static void fmonty(limb *x2, limb *z2,         /* output 2Q */
                           limb *x3, limb *z3,         /* output Q + Q' */
                           limb *x, limb *z,           /* input Q */
                           limb *xprime, limb *zprime, /* input Q' */
                           limb *qmqp /* input Q - Q' */)
        {
            Long19 origx      = new Long19();
            Long19 origxprime = new Long19();
            Long19 zzz        = new Long19();
            Long19 xx         = new Long19();
            Long19 zz         = new Long19();
            Long19 xxprime    = new Long19();
            Long19 zzprime    = new Long19();
            Long19 zzzprime   = new Long19();
            Long19 xxxprime   = new Long19();

            memcpy(origx.Items, x, 10 * sizeof(limb));
            fsum(x, z);
            fdifference(z, origx.Items);  // does x - z

            memcpy(origxprime.Items, xprime, sizeof(limb) * 10);
            fsum(xprime, zprime);
            fdifference(zprime, origxprime.Items);
            fproduct(xxprime.Items, xprime, z);
            fproduct(zzprime.Items, x, zprime);
            freduce_degree(xxprime.Items);
            freduce_coefficients(xxprime.Items);
            freduce_degree(zzprime.Items);
            freduce_coefficients(zzprime.Items);
            memcpy(origxprime.Items, xxprime.Items, sizeof(limb) * 10);
            fsum(xxprime.Items, zzprime.Items);
            fdifference(zzprime.Items, origxprime.Items);
            fsquare(xxxprime.Items, xxprime.Items);
            fsquare(zzzprime.Items, zzprime.Items);
            fproduct(zzprime.Items, zzzprime.Items, qmqp);
            freduce_degree(zzprime.Items);
            freduce_coefficients(zzprime.Items);
            memcpy(x3, xxxprime.Items, sizeof(limb) * 10);
            memcpy(z3, zzprime.Items, sizeof(limb) * 10);

            fsquare(xx.Items, x);
            fsquare(zz.Items, z);
            fproduct(x2, xx.Items, zz.Items);
            freduce_degree(x2);
            freduce_coefficients(x2);
            fdifference(zz.Items, xx.Items);  // does zz = xx - zz
            fscalar_product(zzz.Items, zz.Items, 121665);

            /* No need to call freduce_degree here:
             *             fscalar_product doesn't increase the degree of its input. */
            freduce_coefficients(zzz.Items);
            fsum(zzz.Items, xx.Items);
            fproduct(z2, zz.Items, zzz.Items);
            freduce_degree(z2);
            freduce_coefficients(z2);
        }
Пример #4
0
        public static unsafe void curve25519_donna(byte *mypublic, byte *secret, byte *basepoint)
        {
            Long19 bp    = new Long19();
            Long19 x     = new Long19();
            Long19 z     = new Long19();
            Long19 zmone = new Long19();
            Byte32 e     = new Byte32();
            int    i;

            for (i = 0; i < 32; ++i)
            {
                e.Items[i] = secret[i];
            }
            e.Items[0]  &= 248;
            e.Items[31] &= 127;
            e.Items[31] |= 64;

            fexpand(bp.Items, basepoint);
            cmult(x.Items, z.Items, e.Items, bp.Items);
            crecip(zmone.Items, z.Items);
            fmul(z.Items, x.Items, zmone.Items);
            freduce_coefficients(z.Items);
            fcontract(mypublic, z.Items);
        }
Пример #5
0
 private static void fsquare(limb* output, limb* input)
 {
     var t = new Long19();
     fsquare_inner(t.Items, input);
     freduce_degree(t.Items);
     freduce_coefficients(t.Items);
     memcpy10(output, t.Items);
 }
Пример #6
0
 /* A helpful wrapper around fproduct: output = in * in2.
  *
  * output must be distinct to both inputs. The output is reduced degree and
  * reduced coefficient.
  */
 private static void fmul(limb* output, limb* input, limb* in2)
 {
     Long19 t = new Long19();
     fproduct(t.Items, input, in2);
     freduce_degree(t.Items);
     freduce_coefficients(t.Items);
     memcpy10(output, t.Items);
 }
Пример #7
0
        /* Input: Q, Q', Q-Q'
         * Output: 2Q, Q+Q'
         *
         *   x2 z3: long form
         *   x3 z3: long form
         *   x z: short form, destroyed
         *   xprime zprime: short form, destroyed
         *   qmqp: short form, preserved
         */
        static void fmonty(limb* x2, limb* z2, /* output 2Q */
            limb* x3, limb* z3, /* output Q + Q' */
            limb* x, limb* z, /* input Q */
            limb* xprime, limb* zprime, /* input Q' */
            limb* qmqp /* input Q - Q' */)
        {
            var origx = new Long19();
            var origxprime = new Long19();
            var zzz = new Long19();
            var xx = new Long19();
            var zz = new Long19();
            var xxprime = new Long19();
            var zzprime = new Long19();
            var zzzprime = new Long19();
            var xxxprime = new Long19();

            memcpy10(origx.Items, x);
            fsum(x, z);
            fdifference(z, origx.Items); // does x - z

            memcpy10(origxprime.Items, xprime);
            fsum(xprime, zprime);
            fdifference(zprime, origxprime.Items);
            fproduct(xxprime.Items, xprime, z);
            fproduct(zzprime.Items, x, zprime);
            freduce_degree(xxprime.Items);
            freduce_coefficients(xxprime.Items);
            freduce_degree(zzprime.Items);
            freduce_coefficients(zzprime.Items);
            memcpy10(origxprime.Items, xxprime.Items);
            fsum(xxprime.Items, zzprime.Items);
            fdifference(zzprime.Items, origxprime.Items);
            fsquare(xxxprime.Items, xxprime.Items);
            fsquare(zzzprime.Items, zzprime.Items);
            fproduct(zzprime.Items, zzzprime.Items, qmqp);
            freduce_degree(zzprime.Items);
            freduce_coefficients(zzprime.Items);
            memcpy10(x3, xxxprime.Items);
            memcpy10(z3, zzprime.Items);

            fsquare(xx.Items, x);
            fsquare(zz.Items, z);
            fproduct(x2, xx.Items, zz.Items);
            freduce_degree(x2);
            freduce_coefficients(x2);
            fdifference(zz.Items, xx.Items); // does zz = xx - zz
            fscalar_product(zzz.Items, zz.Items, 121665);
            /* No need to call freduce_degree here:
               fscalar_product doesn't increase the degree of its input. */
            freduce_coefficients(zzz.Items);
            fsum(zzz.Items, xx.Items);
            fproduct(z2, zz.Items, zzz.Items);
            freduce_degree(z2);
            freduce_coefficients(z2);
        }
Пример #8
0
        // -----------------------------------------------------------------------------
        // Shamelessly copied from djb's code
        // -----------------------------------------------------------------------------
        private static void crecip(limb* output, limb* z)
        {
            Long19 z2 = new Long19();
            Long19 z9 = new Long19();
            Long19 z11 = new Long19();
            Long19 z2_5_0 = new Long19();
            Long19 z2_10_0 = new Long19();
            Long19 z2_20_0 = new Long19();
            Long19 z2_50_0 = new Long19();
            Long19 z2_100_0 = new Long19();
            Long19 t0 = new Long19();
            Long19 t1 = new Long19();
            int i;

            /* 2 */
            fsquare(z2.Items, z);
            /* 4 */
            fsquare(t1.Items, z2.Items);
            /* 8 */
            fsquare(t0.Items, t1.Items);
            /* 9 */
            fmul(z9.Items, t0.Items, z);
            /* 11 */
            fmul(z11.Items, z9.Items, z2.Items);
            /* 22 */
            fsquare(t0.Items, z11.Items);
            /* 2^5 - 2^0 = 31 */
            fmul(z2_5_0.Items, t0.Items, z9.Items);

            /* 2^6 - 2^1 */
            fsquare(t0.Items, z2_5_0.Items);
            /* 2^7 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^8 - 2^3 */
            fsquare(t0.Items, t1.Items);
            /* 2^9 - 2^4 */
            fsquare(t1.Items, t0.Items);
            /* 2^10 - 2^5 */
            fsquare(t0.Items, t1.Items);
            /* 2^10 - 2^0 */
            fmul(z2_10_0.Items, t0.Items, z2_5_0.Items);

            /* 2^11 - 2^1 */
            fsquare(t0.Items, z2_10_0.Items);
            /* 2^12 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^20 - 2^10 */
            for (i = 2; i < 10; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^20 - 2^0 */
            fmul(z2_20_0.Items, t1.Items, z2_10_0.Items);

            /* 2^21 - 2^1 */
            fsquare(t0.Items, z2_20_0.Items);
            /* 2^22 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^40 - 2^20 */
            for (i = 2; i < 20; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^40 - 2^0 */
            fmul(t0.Items, t1.Items, z2_20_0.Items);

            /* 2^41 - 2^1 */
            fsquare(t1.Items, t0.Items);
            /* 2^42 - 2^2 */
            fsquare(t0.Items, t1.Items);
            /* 2^50 - 2^10 */
            for (i = 2; i < 10; i += 2)
            {
                fsquare(t1.Items, t0.Items);
                fsquare(t0.Items, t1.Items);
            }
            /* 2^50 - 2^0 */
            fmul(z2_50_0.Items, t0.Items, z2_10_0.Items);

            /* 2^51 - 2^1 */
            fsquare(t0.Items, z2_50_0.Items);
            /* 2^52 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^100 - 2^50 */
            for (i = 2; i < 50; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^100 - 2^0 */
            fmul(z2_100_0.Items, t1.Items, z2_50_0.Items);

            /* 2^101 - 2^1 */
            fsquare(t1.Items, z2_100_0.Items);
            /* 2^102 - 2^2 */
            fsquare(t0.Items, t1.Items);
            /* 2^200 - 2^100 */
            for (i = 2; i < 100; i += 2)
            {
                fsquare(t1.Items, t0.Items);
                fsquare(t0.Items, t1.Items);
            }
            /* 2^200 - 2^0 */
            fmul(t1.Items, t0.Items, z2_100_0.Items);

            /* 2^201 - 2^1 */
            fsquare(t0.Items, t1.Items);
            /* 2^202 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^250 - 2^50 */
            for (i = 2; i < 50; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^250 - 2^0 */
            fmul(t0.Items, t1.Items, z2_50_0.Items);

            /* 2^251 - 2^1 */
            fsquare(t1.Items, t0.Items);
            /* 2^252 - 2^2 */
            fsquare(t0.Items, t1.Items);
            /* 2^253 - 2^3 */
            fsquare(t1.Items, t0.Items);
            /* 2^254 - 2^4 */
            fsquare(t0.Items, t1.Items);
            /* 2^255 - 2^5 */
            fsquare(t1.Items, t0.Items);
            /* 2^255 - 21 */
            fmul(output, t1.Items, z11.Items);
        }
Пример #9
0
        /* Calculates nQ where Q is the x-coordinate of a point on the curve
         *
         *   resultx/resultz: the x coordinate of the resulting curve point (short form)
         *   n: a little endian, 32-byte number
         *   q: a point of the curve (short form)
         */
        private static void cmult(limb* resultx, limb* resultz, byte* n, limb* q)
        {
            Long19 a = new Long19();
            Long19 b = new Long19();
            Long19 c = new Long19();
            Long19 d = new Long19();
            b.Items[0] = 1;
            c.Items[0] = 1;
            limb* nqpqx = a.Items,
                nqpqz = b.Items,
                nqx = c.Items,
                nqz = d.Items,
                t;
            Long19 e = new Long19();
            Long19 f = new Long19();
            Long19 g = new Long19();
            Long19 h = new Long19();
            f.Items[0] = 1;
            h.Items[0] = 1;
            limb* nqpqx2 = e.Items,
                nqpqz2 = f.Items,
                nqx2 = g.Items,
                nqz2 = h.Items;

            memcpy10(nqpqx, q);

            for (int i = 0; i < 32; ++i)
            {
                byte @byte = n[31 - i];
                for (int j = 0; j < 8; ++j)
                {
                    limb bit = @byte >> 7;

                    swap_conditional(nqx, nqpqx, bit);
                    swap_conditional(nqz, nqpqz, bit);
                    fmonty(nqx2, nqz2,
                        nqpqx2, nqpqz2,
                        nqx, nqz,
                        nqpqx, nqpqz,
                        q);
                    swap_conditional(nqx2, nqpqx2, bit);
                    swap_conditional(nqz2, nqpqz2, bit);

                    t = nqx;
                    nqx = nqx2;
                    nqx2 = t;
                    t = nqz;
                    nqz = nqz2;
                    nqz2 = t;
                    t = nqpqx;
                    nqpqx = nqpqx2;
                    nqpqx2 = t;
                    t = nqpqz;
                    nqpqz = nqpqz2;
                    nqpqz2 = t;

                    @byte <<= 1;
                }
            }

            memcpy10(resultx, nqx);
            memcpy10(resultz, nqz);
        }
Пример #10
0
        internal static void curve25519_donna(byte* mypublic, byte* secret, byte* basepoint)
        {
            Long19 bp = new Long19();
            Long19 x = new Long19();
            Long19 z = new Long19();
            Long19 zmone = new Long19();
            Byte32 e = new Byte32();
            int i;

            for (i = 0; i < 32; ++i)
                e.Items[i] = secret[i];
            e.Items[0] &= 248;
            e.Items[31] &= 127;
            e.Items[31] |= 64;

            fexpand(bp.Items, basepoint);
            cmult(x.Items, z.Items, e.Items, bp.Items);
            crecip(zmone.Items, z.Items);
            fmul(z.Items, x.Items, zmone.Items);
            freduce_coefficients(z.Items);
            fcontract(mypublic, z.Items);
        }
Пример #11
0
        crecip(limb *output, limb *z)
        {
            Long19 z2       = new Long19();
            Long19 z9       = new Long19();
            Long19 z11      = new Long19();
            Long19 z2_5_0   = new Long19();
            Long19 z2_10_0  = new Long19();
            Long19 z2_20_0  = new Long19();
            Long19 z2_50_0  = new Long19();
            Long19 z2_100_0 = new Long19();
            Long19 t0       = new Long19();
            Long19 t1       = new Long19();
            int    i;

            /* 2 */
            fsquare(z2.Items, z);
            /* 4 */
            fsquare(t1.Items, z2.Items);
            /* 8 */
            fsquare(t0.Items, t1.Items);
            /* 9 */
            fmul(z9.Items, t0.Items, z);
            /* 11 */
            fmul(z11.Items, z9.Items, z2.Items);
            /* 22 */
            fsquare(t0.Items, z11.Items);
            /* 2^5 - 2^0 = 31 */
            fmul(z2_5_0.Items, t0.Items, z9.Items);

            /* 2^6 - 2^1 */
            fsquare(t0.Items, z2_5_0.Items);
            /* 2^7 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^8 - 2^3 */
            fsquare(t0.Items, t1.Items);
            /* 2^9 - 2^4 */
            fsquare(t1.Items, t0.Items);
            /* 2^10 - 2^5 */
            fsquare(t0.Items, t1.Items);
            /* 2^10 - 2^0 */
            fmul(z2_10_0.Items, t0.Items, z2_5_0.Items);

            /* 2^11 - 2^1 */
            fsquare(t0.Items, z2_10_0.Items);
            /* 2^12 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^20 - 2^10 */
            for (i = 2; i < 10; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^20 - 2^0 */
            fmul(z2_20_0.Items, t1.Items, z2_10_0.Items);

            /* 2^21 - 2^1 */
            fsquare(t0.Items, z2_20_0.Items);
            /* 2^22 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^40 - 2^20 */
            for (i = 2; i < 20; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^40 - 2^0 */
            fmul(t0.Items, t1.Items, z2_20_0.Items);

            /* 2^41 - 2^1 */
            fsquare(t1.Items, t0.Items);
            /* 2^42 - 2^2 */
            fsquare(t0.Items, t1.Items);
            /* 2^50 - 2^10 */
            for (i = 2; i < 10; i += 2)
            {
                fsquare(t1.Items, t0.Items);
                fsquare(t0.Items, t1.Items);
            }
            /* 2^50 - 2^0 */
            fmul(z2_50_0.Items, t0.Items, z2_10_0.Items);

            /* 2^51 - 2^1 */
            fsquare(t0.Items, z2_50_0.Items);
            /* 2^52 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^100 - 2^50 */
            for (i = 2; i < 50; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^100 - 2^0 */
            fmul(z2_100_0.Items, t1.Items, z2_50_0.Items);

            /* 2^101 - 2^1 */
            fsquare(t1.Items, z2_100_0.Items);
            /* 2^102 - 2^2 */
            fsquare(t0.Items, t1.Items);
            /* 2^200 - 2^100 */
            for (i = 2; i < 100; i += 2)
            {
                fsquare(t1.Items, t0.Items);
                fsquare(t0.Items, t1.Items);
            }
            /* 2^200 - 2^0 */
            fmul(t1.Items, t0.Items, z2_100_0.Items);

            /* 2^201 - 2^1 */
            fsquare(t0.Items, t1.Items);
            /* 2^202 - 2^2 */
            fsquare(t1.Items, t0.Items);
            /* 2^250 - 2^50 */
            for (i = 2; i < 50; i += 2)
            {
                fsquare(t0.Items, t1.Items);
                fsquare(t1.Items, t0.Items);
            }
            /* 2^250 - 2^0 */
            fmul(t0.Items, t1.Items, z2_50_0.Items);

            /* 2^251 - 2^1 */
            fsquare(t1.Items, t0.Items);
            /* 2^252 - 2^2 */
            fsquare(t0.Items, t1.Items);
            /* 2^253 - 2^3 */
            fsquare(t1.Items, t0.Items);
            /* 2^254 - 2^4 */
            fsquare(t0.Items, t1.Items);
            /* 2^255 - 2^5 */
            fsquare(t1.Items, t0.Items);
            /* 2^255 - 21 */
            fmul(output, t1.Items, z11.Items);
        }
Пример #12
0
        cmult(limb *resultx, limb *resultz, byte *n, limb *q)
        {
            Long19 a = new Long19();
            Long19 b = new Long19();
            Long19 c = new Long19();
            Long19 d = new Long19();

            b.Items[0] = 1;
            c.Items[0] = 1;
            limb *nqpqx = a.Items,
                 nqpqz  = b.Items,
                 nqx    = c.Items,
                 nqz    = d.Items,
                 t;
            Long19 e = new Long19();
            Long19 f = new Long19();
            Long19 g = new Long19();
            Long19 h = new Long19();

            f.Items[0] = 1;
            h.Items[0] = 1;
            limb *nqpqx2 = e.Items,
                 nqpqz2  = f.Items,
                 nqx2    = g.Items,
                 nqz2    = h.Items;

            memcpy(nqpqx, q, sizeof(limb) * 10);

            for (int i = 0; i < 32; ++i)
            {
                byte @byte = n[31 - i];
                for (int j = 0; j < 8; ++j)
                {
                    limb bit = @byte >> 7;

                    swap_conditional(nqx, nqpqx, bit);
                    swap_conditional(nqz, nqpqz, bit);
                    fmonty(nqx2, nqz2,
                           nqpqx2, nqpqz2,
                           nqx, nqz,
                           nqpqx, nqpqz,
                           q);
                    swap_conditional(nqx2, nqpqx2, bit);
                    swap_conditional(nqz2, nqpqz2, bit);

                    t      = nqx;
                    nqx    = nqx2;
                    nqx2   = t;
                    t      = nqz;
                    nqz    = nqz2;
                    nqz2   = t;
                    t      = nqpqx;
                    nqpqx  = nqpqx2;
                    nqpqx2 = t;
                    t      = nqpqz;
                    nqpqz  = nqpqz2;
                    nqpqz2 = t;

                    @byte <<= 1;
                }
            }

            memcpy(resultx, nqx, sizeof(limb) * 10);
            memcpy(resultz, nqz, sizeof(limb) * 10);
        }