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

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

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

public class ge_scalarmult_base {

//CONVERT #include "ge.h"
//CONVERT #include "crypto_uint32.h"

    static int equal(byte b, byte c) {
        int y = (int) b ^ (int) c; /* 0: yes; 1..255: no */
        y -= 1; /* 4294967295: yes; 0..254: no */
        y >>>= 31; /* 1: yes; 0: no */
        return y;
    }

    static byte negative(byte b) {
        return (byte) ((b >> 7) & 1);
    }

    static void cmov(ge_precomp t, ge_precomp u, int b) {
        fe_cmov.fe_cmov(t.yplusx, u.yplusx, b);
        fe_cmov.fe_cmov(t.yminusx, u.yminusx, b);
        fe_cmov.fe_cmov(t.xy2d, u.xy2d, b);
    }

    static void select(ge_precomp t, int pos, byte b) {
        ge_precomp[][] base = (pos <= 7 ? ge_precomp_base_0_7.base :
                (pos <= 15 ? ge_precomp_base_8_15.base :
                        (pos <= 23 ? ge_precomp_base_16_23.base : ge_precomp_base_24_31.base)));

        ge_precomp minust = new ge_precomp();
        byte bnegative = negative(b);
        byte babs = (byte) (b - (((-bnegative) & b) << 1));

        ge_precomp_0.ge_precomp_0(t);
        cmov(t, base[pos][0], equal(babs, (byte) 1));
        cmov(t, base[pos][1], equal(babs, (byte) 2));
        cmov(t, base[pos][2], equal(babs, (byte) 3));
        cmov(t, base[pos][3], equal(babs, (byte) 4));
        cmov(t, base[pos][4], equal(babs, (byte) 5));
        cmov(t, base[pos][5], equal(babs, (byte) 6));
        cmov(t, base[pos][6], equal(babs, (byte) 7));
        cmov(t, base[pos][7], equal(babs, (byte) 8));
        fe_copy.fe_copy(minust.yplusx, t.yminusx);
        fe_copy.fe_copy(minust.yminusx, t.yplusx);
        fe_neg.fe_neg(minust.xy2d, t.xy2d);
        cmov(t, minust, bnegative);
    }

/*
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
*/

    public static void ge_scalarmult_base(ge_p3 h, byte[] a) {
        byte[] e = new byte[64];
        byte carry;
        ge_p1p1 r = new ge_p1p1();
        ge_p2 s = new ge_p2();
        ge_precomp t = new ge_precomp();
        int i;

        for (i = 0; i < 32; ++i) {
            e[2 * i] = (byte) ((a[i]) & 15);
            e[2 * i + 1] = (byte) ((a[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 = (byte) (e[i] + 8);
            carry >>= 4;
            e[i] -= carry << 4;
        }
        e[63] += carry;
        /* each e[i] is between -8 and 8 */

        ge_p3_0.ge_p3_0(h);
        for (i = 1; i < 64; i += 2) {
            select(t, i / 2, e[i]);
            ge_madd.ge_madd(r, h, t);
            ge_p1p1_to_p3.ge_p1p1_to_p3(h, r);
        }

        ge_p3_dbl.ge_p3_dbl(r, h);
        ge_p1p1_to_p2.ge_p1p1_to_p2(s, r);
        ge_p2_dbl.ge_p2_dbl(r, s);
        ge_p1p1_to_p2.ge_p1p1_to_p2(s, r);
        ge_p2_dbl.ge_p2_dbl(r, s);
        ge_p1p1_to_p2.ge_p1p1_to_p2(s, r);
        ge_p2_dbl.ge_p2_dbl(r, s);
        ge_p1p1_to_p3.ge_p1p1_to_p3(h, r);

        for (i = 0; i < 64; i += 2) {
            select(t, i / 2, e[i]);
            ge_madd.ge_madd(r, h, t);
            ge_p1p1_to_p3.ge_p1p1_to_p3(h, r);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy