Esempio n. 1
0
 static unsafe void fe25519_setzero(fe25519 *r)
 {
     for (int i = 0; i < 32; i++)
     {
         r->v[i] = 0;
     }
 }
Esempio n. 2
0
 public static unsafe void fe25519_add(fe25519 *r, fe25519 *x, fe25519 *y)
 {
     for (int i = 0; i < 32; i++)
     {
         r->v[i] = x->v[i] + y->v[i];
     }
     reduce_add_sub(r);
 }
Esempio n. 3
0
 public static unsafe void fe25519_setone(fe25519 *r)
 {
     r->v[0] = 1;
     for (int i = 1; i < 32; i++)
     {
         r->v[i] = 0;
     }
 }
Esempio n. 4
0
 public static unsafe void fe25519_unpack(fe25519 *r, Byte *x)               //const unsigned char x[32]
 {
     for (int i = 0; i < 32; i++)
     {
         r->v[i] = x[i];
     }
     r->v[31] &= 127;
 }
Esempio n. 5
0
            public static unsafe void fe25519_cmov(fe25519 *r, fe25519 *x, Byte b)
            {
                Byte nb = (Byte)(1 - b);

                for (int i = 0; i < 32; i++)
                {
                    r->v[i] = nb * r->v[i] + b * x->v[i];
                }
            }
Esempio n. 6
0
            /*XXX: Make constant time! */
            public static unsafe void fe25519_pow(fe25519 *r, fe25519 *x, Byte *e)
            {
                /*
                 * fe25519 g;
                 * fe25519_setone(&g);
                 * int i;
                 * unsigned char j;
                 * for(i=32;i>0;i--)
                 * {
                 * for(j=128;j>0;j>>=1)
                 * {
                 *      fe25519_square(&g,&g);
                 *      if(e[i-1] & j)
                 *        fe25519_mul(&g,&g,x);
                 * }
                 * }
                 * for(i=0;i<32;i++) r->v[i] = g.v[i];
                 */
                fe25519 g;

                fe25519_setone(&g);
                fe25519[] pre = new fe25519[(1 << WINDOWSIZE)];
                fe25519   t;
                Byte      w;

                // Precomputation
                fixed(fe25519 *prep = pre) fe25519_setone(prep);

                pre[1] = *x;
                for (int i = 2; i < (1 << WINDOWSIZE); i += 2)
                {
                    fixed(fe25519 *prep = pre)
                    {
                        fe25519_square(prep + i, prep + i / 2);
                        fe25519_mul(prep + i + 1, prep + i, prep + 1);
                    }
                }

                // Fixed-window scalar multiplication
                for (int i = 32; i > 0; i--)
                {
                    for (int j = 8 - WINDOWSIZE; j >= 0; j -= WINDOWSIZE)
                    {
                        for (int k = 0; k < WINDOWSIZE; k++)
                        {
                            fe25519_square(&g, &g);
                        }
                        // Cache-timing resistant loading of precomputed value:
                        w = (Byte)((e[i - 1] >> j) & WINDOWMASK);
                        t = pre[0];
                        for (int k = 1; k < (1 << WINDOWSIZE); k++)
                            fixed(fe25519 *prekp = &pre[k]) fe25519_cmov(&t, prekp, (k == w) ? (Byte)1 : (Byte)0);
                        fe25519_mul(&g, &g, &t);
                    }
                }
                *r = g;
            }
Esempio n. 7
0
            /*freeze input before calling iszero*/
            unsafe static Boolean iszero(fe25519 *x)
            {
                bool r = (x->v[0] == 0);

                for (int i = 1; i < 32; i++)
                {
                    r &= (x->v[i] == 0);
                }
                return(r);
            }
Esempio n. 8
0
            public static unsafe Byte fe25519_getparity(fe25519 *x)
            {
                fe25519 t = new fe25519();

                for (int i = 0; i < 32; i++)
                {
                    t.v[i] = x->v[i];
                }
                freeze(&t);
                return((Byte)(t.v[0] & 1));
            }
Esempio n. 9
0
            public static unsafe void fe25519_neg(fe25519 *r, fe25519 *x)
            {
                fe25519 t = new fe25519();

                for (int i = 0; i < 32; i++)
                {
                    t.v[i] = x->v[i];
                }
                fe25519_setzero(r);
                fe25519_sub(r, r, &t);
            }
Esempio n. 10
0
            unsafe static Boolean issquare(fe25519 *x)
            {
                Byte[] e = new Byte[32] {
                    0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f
                };                                                                                                                                                                                                                                          /* (p-1)/2 */
                fe25519 t;

                fixed(Byte *ep = e) fe25519_pow(&t, x, ep);

                freeze(&t);
                return(isone(&t) || iszero(&t));
            }
Esempio n. 11
0
 unsafe static void reduce_mul(fe25519 *r)
 {
     for (int rep = 0; rep < 2; rep++)
     {
         UInt32 t = r->v[31] >> 7;
         r->v[31] &= 127;
         t        *= 19;
         r->v[0]  += t;
         for (int i = 0; i < 31; i++)
         {
             t            = r->v[i] >> 8;
             r->v[i + 1] += t;
             r->v[i]     &= 255;
         }
     }
 }
Esempio n. 12
0
            public static unsafe void fe25519_sub(fe25519 *r, fe25519 *x, fe25519 *y)
            {
                UInt32 *t = stackalloc UInt32[32];

                t[0]  = x->v[0] + 0x1da;
                t[31] = x->v[31] + 0xfe;
                for (int i = 1; i < 31; i++)
                {
                    t[i] = x->v[i] + 0x1fe;
                }
                for (int i = 0; i < 32; i++)
                {
                    r->v[i] = t[i] - y->v[i];
                }
                reduce_add_sub(r);
            }
Esempio n. 13
0
            /* reduction modulo 2^255-19 */
            unsafe static void freeze(fe25519 *r)
            {
                UInt32 m = (r->v[31] == 127) ? 1u : 0;

                for (int i = 30; i > 1; i--)
                {
                    m *= (r->v[i] == 255) ? 1u : 0;
                }
                m *= (r->v[0] >= 237) ? 1u : 0;

                r->v[31] -= m * 127;
                for (int i = 30; i > 0; i--)
                {
                    r->v[i] -= m * 255;
                }
                r->v[0] -= m * 237;
            }
Esempio n. 14
0
            /* Return 0 on success, 1 otherwise */
            public static unsafe Boolean fe25519_sqrt_vartime(fe25519 *r, fe25519 *x, Byte parity)
            {
                /* See HAC, Alg. 3.37 */
                if (!issquare(x))
                {
                    return(true);
                }
                Byte[] e = new Byte[32] {
                    0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f
                };                                                                                                                                                                                                                                          /* (p-1)/4 */
                Byte[] e2 = new Byte[32] {
                    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f
                };                                                                                                                                                                                                                                           /* (p+3)/8 */
                Byte[] e3 = new Byte[32] {
                    0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f
                };                                         /* (p-5)/8 */
                fe25519 p = new fe25519();                 // { { 0 } };
                fe25519 d;

                fixed(Byte *ep = e) fe25519.fe25519_pow(&d, x, ep);

                freeze(&d);
                if (isone(&d))
                    fixed(Byte *e2p = e2) fe25519.fe25519_pow(r, x, e2p);
                else
                {
                    for (int i = 0; i < 32; i++)
                    {
                        d.v[i] = 4 * x->v[i];
                        fixed(Byte *e3p = e3) fe25519.fe25519_pow(&d, &d, e3p);

                        for (int i = 0; i < 32; i++)
                            r->v[i] = 2 * x->v[i];
}
                        fe25519_mul(r, r, &d);
                }
                freeze(r);
                if ((r->v[0] & 1) != (parity & 1))
                {
                    fe25519_sub(r, &p, r);
                }
                return(false);
            }
Esempio n. 15
0
            /* Assumes input x being reduced mod 2^255 */
            public static unsafe void fe25519_pack(Byte *r, fe25519 *x)               //unsigned char r[32]
            {
                for (int i = 0; i < 32; i++)
                {
                    r[i] = (byte)x->v[i];
                }

                /* freeze byte array */
                UInt32 m = (r[31] == 127) ? 1u : 0;                 /* XXX: some compilers might use branches; fix */

                for (int i = 30; i > 1; i--)
                {
                    m *= (r[i] == 255) ? 1u : 0;
                }
                m     *= (r[0] >= 237) ? 1u : 0;
                r[31] -= (byte)(m * 127);
                for (int i = 30; i > 0; i--)
                {
                    r[i] -= (byte)(m * 255);
                }
                r[0] -= (byte)(m * 237);
            }
Esempio n. 16
0
            public static unsafe void fe25519_mul(fe25519 *r, fe25519 *x, fe25519 *y)
            {
                UInt32 *t = stackalloc UInt32[63];

                for (int i = 0; i < 63; i++)
                {
                    t[i] = 0;
                }
                for (int i = 0; i < 32; i++)
                {
                    for (int j = 0; j < 32; j++)
                    {
                        t[i + j] += x->v[i] * y->v[j];
                    }
                }

                for (int i = 32; i < 63; i++)
                {
                    r->v[i - 32] = t[i - 32] + 38 * t[i];
                }
                r->v[31] = t[31];                 /* result now in r[0]...r[31] */

                reduce_mul(r);
            }
Esempio n. 17
0
            public static unsafe void fe25519_invert(fe25519 *r, fe25519 *x)
            {
                fe25519 z2;
                fe25519 z9;
                fe25519 z11;
                fe25519 z2_5_0;
                fe25519 z2_10_0;
                fe25519 z2_20_0;
                fe25519 z2_50_0;
                fe25519 z2_100_0;
                fe25519 t0;
                fe25519 t1;

                /* 2 */
                fe25519_square(&z2, x);
                /* 4 */
                fe25519_square(&t1, &z2);
                /* 8 */
                fe25519_square(&t0, &t1);
                /* 9 */
                fe25519_mul(&z9, &t0, x);
                /* 11 */
                fe25519_mul(&z11, &z9, &z2);
                /* 22 */
                fe25519_square(&t0, &z11);
                /* 2^5 - 2^0 = 31 */
                fe25519_mul(&z2_5_0, &t0, &z9);

                /* 2^6 - 2^1 */
                fe25519_square(&t0, &z2_5_0);
                /* 2^7 - 2^2 */
                fe25519_square(&t1, &t0);
                /* 2^8 - 2^3 */
                fe25519_square(&t0, &t1);
                /* 2^9 - 2^4 */
                fe25519_square(&t1, &t0);
                /* 2^10 - 2^5 */
                fe25519_square(&t0, &t1);
                /* 2^10 - 2^0 */
                fe25519_mul(&z2_10_0, &t0, &z2_5_0);

                /* 2^11 - 2^1 */
                fe25519_square(&t0, &z2_10_0);
                /* 2^12 - 2^2 */
                fe25519_square(&t1, &t0);
                /* 2^20 - 2^10 */
                for (int i = 2; i < 10; i += 2)
                {
                    fe25519_square(&t0, &t1); fe25519_square(&t1, &t0);
                }
                /* 2^20 - 2^0 */
                fe25519_mul(&z2_20_0, &t1, &z2_10_0);

                /* 2^21 - 2^1 */
                fe25519_square(&t0, &z2_20_0);
                /* 2^22 - 2^2 */
                fe25519_square(&t1, &t0);
                /* 2^40 - 2^20 */
                for (int i = 2; i < 20; i += 2)
                {
                    fe25519_square(&t0, &t1); fe25519_square(&t1, &t0);
                }
                /* 2^40 - 2^0 */
                fe25519_mul(&t0, &t1, &z2_20_0);

                /* 2^41 - 2^1 */
                fe25519_square(&t1, &t0);
                /* 2^42 - 2^2 */
                fe25519_square(&t0, &t1);
                /* 2^50 - 2^10 */
                for (int i = 2; i < 10; i += 2)
                {
                    fe25519_square(&t1, &t0); fe25519_square(&t0, &t1);
                }
                /* 2^50 - 2^0 */
                fe25519_mul(&z2_50_0, &t0, &z2_10_0);

                /* 2^51 - 2^1 */
                fe25519_square(&t0, &z2_50_0);
                /* 2^52 - 2^2 */
                fe25519_square(&t1, &t0);
                /* 2^100 - 2^50 */
                for (int i = 2; i < 50; i += 2)
                {
                    fe25519_square(&t0, &t1); fe25519_square(&t1, &t0);
                }
                /* 2^100 - 2^0 */
                fe25519_mul(&z2_100_0, &t1, &z2_50_0);

                /* 2^101 - 2^1 */
                fe25519_square(&t1, &z2_100_0);
                /* 2^102 - 2^2 */
                fe25519_square(&t0, &t1);
                /* 2^200 - 2^100 */
                for (int i = 2; i < 100; i += 2)
                {
                    fe25519_square(&t1, &t0); fe25519_square(&t0, &t1);
                }
                /* 2^200 - 2^0 */
                fe25519_mul(&t1, &t0, &z2_100_0);

                /* 2^201 - 2^1 */
                fe25519_square(&t0, &t1);
                /* 2^202 - 2^2 */
                fe25519_square(&t1, &t0);
                /* 2^250 - 2^50 */
                for (int i = 2; i < 50; i += 2)
                {
                    fe25519_square(&t0, &t1); fe25519_square(&t1, &t0);
                }
                /* 2^250 - 2^0 */
                fe25519_mul(&t0, &t1, &z2_50_0);

                /* 2^251 - 2^1 */
                fe25519_square(&t1, &t0);
                /* 2^252 - 2^2 */
                fe25519_square(&t0, &t1);
                /* 2^253 - 2^3 */
                fe25519_square(&t1, &t0);
                /* 2^254 - 2^4 */
                fe25519_square(&t0, &t1);
                /* 2^255 - 2^5 */
                fe25519_square(&t1, &t0);
                /* 2^255 - 21 */
                fe25519_mul(r, &t1, &z11);
            }
Esempio n. 18
0
 public static unsafe void fe25519_square(fe25519 *r, fe25519 *x)
 {
     fe25519_mul(r, x, x);
 }