All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.whispersystems.curve25519.java.ge_double_scalarmult Maven / Gradle / Ivy

The newest version!
package org.whispersystems.curve25519.java;

public class ge_double_scalarmult {

//CONVERT #include "ge.h"

    static public void slide(byte[] r, byte[] a) {
        int i;
        int b;
        int k;

        for (i = 0; i < 256; ++i) {
            //CONVERT r[i] = 1 & (a[i >> 3] >> (i & 7));
            r[i] = (byte) (1 & (a[i >> 3] >>> (i & 7)));
        }

        for (i = 0; i < 256; ++i)
            if (r[i] != 0) {
                for (b = 1; b <= 6 && i + b < 256; ++b) {
                    if (r[i + b] != 0) {
                        if (r[i] + (r[i + b] << b) <= 15) {
                            r[i] += r[i + b] << b;
                            r[i + b] = 0;
                        } else if (r[i] - (r[i + b] << b) >= -15) {
                            r[i] -= r[i + b] << b;
                            for (k = i + b; k < 256; ++k) {
                                if (r[k] == 0) {
                                    r[k] = 1;
                                    break;
                                }
                                r[k] = 0;
                            }
                        } else
                            break;
                    }
                }
            }

    }

    static ge_precomp[] Bi;

    static {
        Bi = new ge_precomp[8];
        Bi[0] = new ge_precomp(
                new int[]{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605},
                new int[]{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378},
                new int[]{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}
        );
        Bi[1] = new ge_precomp(
                new int[]{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024},
                new int[]{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574},
                new int[]{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}
        );
        Bi[2] = new ge_precomp(
                new int[]{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380},
                new int[]{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306},
                new int[]{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}
        );
        Bi[3] = new ge_precomp(
                new int[]{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766},
                new int[]{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701},
                new int[]{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}
        );
        Bi[4] = new ge_precomp(
                new int[]{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877},
                new int[]{-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951},
                new int[]{4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784}
        );
        Bi[5] = new ge_precomp(
                new int[]{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436},
                new int[]{25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918},
                new int[]{23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877}
        );
        Bi[6] = new ge_precomp(
                new int[]{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800},
                new int[]{-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305},
                new int[]{-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300}
        );
        Bi[7] = new ge_precomp(
                new int[]{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876},
                new int[]{-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619},
                new int[]{-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683}
        );
    }

/*
r = a * A + b * B
where a = a[0]+256*a[1]+...+256^31 a[31].
and b = b[0]+256*b[1]+...+256^31 b[31].
B is the Ed25519 base point (x,4/5) with x positive.
*/

    public static void ge_double_scalarmult_vartime(ge_p2 r, byte[] a, ge_p3 A, byte[] b, ge_p3 B) {
        byte[] aslide = new byte[256];
        byte[] bslide = new byte[256];
        ge_cached[] Ai = new ge_cached[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
        for (int count = 0; count < 8; count++)
            Ai[count] = new ge_cached();
        ge_p1p1 t = new ge_p1p1();
        ge_p3 u = new ge_p3();
        ge_p3 A2 = new ge_p3();

        ge_cached Bi_noconst[] = new ge_cached[8]; /* B,3B,5B,7B,9B,11B,13B,15B */
        for (int count = 0; count < 8; count++)
            Bi_noconst[count] = new ge_cached();

        ge_p3 B2 = new ge_p3();
        int i;

        slide(aslide, a);
        slide(bslide, b);

        ge_p3_to_cached.ge_p3_to_cached(Ai[0], A);
        ge_p3_dbl.ge_p3_dbl(t, A);
        ge_p1p1_to_p3.ge_p1p1_to_p3(A2, t);
        ge_add.ge_add(t, A2, Ai[0]);
        ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
        ge_p3_to_cached.ge_p3_to_cached(Ai[1], u);
        ge_add.ge_add(t, A2, Ai[1]);
        ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
        ge_p3_to_cached.ge_p3_to_cached(Ai[2], u);
        ge_add.ge_add(t, A2, Ai[2]);
        ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
        ge_p3_to_cached.ge_p3_to_cached(Ai[3], u);
        ge_add.ge_add(t, A2, Ai[3]);
        ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
        ge_p3_to_cached.ge_p3_to_cached(Ai[4], u);
        ge_add.ge_add(t, A2, Ai[4]);
        ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
        ge_p3_to_cached.ge_p3_to_cached(Ai[5], u);
        ge_add.ge_add(t, A2, Ai[5]);
        ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
        ge_p3_to_cached.ge_p3_to_cached(Ai[6], u);
        ge_add.ge_add(t, A2, Ai[6]);
        ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
        ge_p3_to_cached.ge_p3_to_cached(Ai[7], u);

        if (B != null) {
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[0], B);
            ge_p3_dbl.ge_p3_dbl(t, B);
            ge_p1p1_to_p3.ge_p1p1_to_p3(B2, t);
            ge_add.ge_add(t, B2, Bi_noconst[0]);
            ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[1], u);
            ge_add.ge_add(t, B2, Bi_noconst[1]);
            ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[2], u);
            ge_add.ge_add(t, B2, Bi_noconst[2]);
            ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[3], u);
            ge_add.ge_add(t, B2, Bi_noconst[3]);
            ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[4], u);
            ge_add.ge_add(t, B2, Bi_noconst[4]);
            ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[5], u);
            ge_add.ge_add(t, B2, Bi_noconst[5]);
            ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[6], u);
            ge_add.ge_add(t, B2, Bi_noconst[6]);
            ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
            ge_p3_to_cached.ge_p3_to_cached(Bi_noconst[7], u);
        }


        ge_p2_0.ge_p2_0(r);

        for (i = 255; i >= 0; --i) {
            if (aslide[i] != 0 || bslide[i] != 0) break;
        }

        for (; i >= 0; --i) {
            ge_p2_dbl.ge_p2_dbl(t, r);

            if (aslide[i] > 0) {
                ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
                ge_add.ge_add(t, u, Ai[aslide[i] / 2]);
            } else if (aslide[i] < 0) {
                ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);
                ge_sub.ge_sub(t, u, Ai[(-aslide[i]) / 2]);
            }

            if (bslide[i] > 0) {
                ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);

                if (B == null) ge_madd.ge_madd(t, u, Bi[bslide[i] / 2]);
                else ge_add.ge_add(t, u, Bi_noconst[bslide[i] / 2]);

            } else if (bslide[i] < 0) {
                ge_p1p1_to_p3.ge_p1p1_to_p3(u, t);

                if (B == null) ge_msub.ge_msub(t, u, Bi[(-bslide[i]) / 2]);
                else ge_sub.ge_sub(t, u, Bi_noconst[-bslide[i] / 2]);
            }

            ge_p1p1_to_p2.ge_p1p1_to_p2(r, t);
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy