Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I've ported other related low level functions: ge_frombytes_vartime, ge_scalarmult etc. #15

Open
jdluzen opened this issue Feb 11, 2018 · 3 comments

Comments

@jdluzen
Copy link

jdluzen commented Feb 11, 2018

For an upcoming project I needed various low level ECC primitives. I've been working with Chaos.NaCl for some time now, and used it as a starting point. I ended up needing to port other functions such as:
fe_divpowm1 ge_frombytes_vartime ge_cached_cmov ge_cached_0 ge_scalarmult ge_mul8 etc. I'd be happy to contribute them if interested.

@Syyn926
Copy link

Syyn926 commented Dec 18, 2019

I'm interested in these other functions if you still have them available.

@jdluzen
Copy link
Author

jdluzen commented Jun 27, 2020

Sorry for the late response.

       static void fe_divpowm1(out FieldElement r, ref FieldElement u, ref FieldElement v)
        {
            FieldElement v3, uv7, t0, t1, t2;
            int i;

            FieldOperations.fe_sq(out v3, ref v);
            FieldOperations.fe_mul(out v3, ref v3, ref v); /* v3 = v^3 */
            FieldOperations.fe_sq(out uv7, ref v3);
            FieldOperations.fe_mul(out uv7, ref uv7, ref v);
            FieldOperations.fe_mul(out uv7, ref uv7, ref u); /* uv7 = uv^7 */

            /*fe_pow22523(uv7, uv7);*/

            /* From fe_pow22523.c */

            FieldOperations.fe_sq(out t0, ref uv7);
            FieldOperations.fe_sq(out t1, ref t0);
            FieldOperations.fe_sq(out t1, ref t1);
            FieldOperations.fe_mul(out t1, ref uv7, ref t1);
            FieldOperations.fe_mul(out t0, ref t0, ref t1);
            FieldOperations.fe_sq(out t0, ref t0);
            FieldOperations.fe_mul(out t0, ref t1, ref t0);
            FieldOperations.fe_sq(out t1, ref t0);
            for (i = 0; i < 4; ++i)
            {
                FieldOperations.fe_sq(out t1, ref t1);
            }
            FieldOperations.fe_mul(out t0, ref t1, ref t0);
            FieldOperations.fe_sq(out t1, ref t0);
            for (i = 0; i < 9; ++i)
            {
                FieldOperations.fe_sq(out t1, ref t1);
            }
            FieldOperations.fe_mul(out t1, ref t1, ref t0);
            FieldOperations.fe_sq(out t2, ref t1);
            for (i = 0; i < 19; ++i)
            {
                FieldOperations.fe_sq(out t2, ref t2);
            }
            FieldOperations.fe_mul(out t1, ref t2, ref t1);
            for (i = 0; i < 10; ++i)
            {
                FieldOperations.fe_sq(out t1, ref t1);
            }
            FieldOperations.fe_mul(out t0, ref t1, ref t0);
            FieldOperations.fe_sq(out t1, ref t0);
            for (i = 0; i < 49; ++i)
            {
                FieldOperations.fe_sq(out t1, ref t1);
            }
            FieldOperations.fe_mul(out t1, ref t1, ref t0);
            FieldOperations.fe_sq(out t2, ref t1);
            for (i = 0; i < 99; ++i)
            {
                FieldOperations.fe_sq(out t2, ref t2);
            }
            FieldOperations.fe_mul(out t1, ref t2, ref t1);
            for (i = 0; i < 50; ++i)
            {
                FieldOperations.fe_sq(out t1, ref t1);
            }
            FieldOperations.fe_mul(out t0, ref t1, ref t0);
            FieldOperations.fe_sq(out t0, ref t0);
            FieldOperations.fe_sq(out t0, ref t0);
            FieldOperations.fe_mul(out t0, ref t0, ref uv7);

            /* End fe_pow22523.c */
            /* t0 = (uv^7)^((q-5)/8) */
            FieldOperations.fe_mul(out t0, ref t0, ref v3);
            FieldOperations.fe_mul(out r, ref t0, ref u); /* u^(m+1)v^(-(m+1)) */
        }

        static int ge_frombytes_vartime(out GroupElementP3 h, byte[] s)
        {
            FieldElement u;
            FieldElement v;
            FieldElement vxx;
            FieldElement check;

            /* From fe_frombytes.c */

            long h0 = FieldOperations.load_4(s, 0);
            long h1 = FieldOperations.load_3(s, 4) << 6;
            long h2 = FieldOperations.load_3(s, 7) << 5;
            long h3 = FieldOperations.load_3(s, 10) << 3;
            long h4 = FieldOperations.load_3(s, 13) << 2;
            long h5 = FieldOperations.load_4(s, 16);
            long h6 = FieldOperations.load_3(s, 20) << 7;
            long h7 = FieldOperations.load_3(s, 23) << 5;
            long h8 = FieldOperations.load_3(s, 26) << 4;
            long h9 = (FieldOperations.load_3(s, 29) & 8388607) << 2;
            long carry0;
            long carry1;
            long carry2;
            long carry3;
            long carry4;
            long carry5;
            long carry6;
            long carry7;
            long carry8;
            long carry9;

            /* Validate the number to be canonical */
            if (h9 == 33554428 && h8 == 268435440 && h7 == 536870880 && h6 == 2147483520 &&
              h5 == 4294967295 && h4 == 67108860 && h3 == 134217720 && h2 == 536870880 &&
              h1 == 1073741760 && h0 >= 4294967277)
            {
                h = default;
                return -1;
            }

            carry9 = (h9 + (long)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
            carry1 = (h1 + (long)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
            carry3 = (h3 + (long)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
            carry5 = (h5 + (long)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
            carry7 = (h7 + (long)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25;

            carry0 = (h0 + (long)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
            carry2 = (h2 + (long)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
            carry4 = (h4 + (long)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
            carry6 = (h6 + (long)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
            carry8 = (h8 + (long)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26;

            h.Y.x0 = (int)h0;
            h.Y.x1 = (int)h1;
            h.Y.x2 = (int)h2;
            h.Y.x3 = (int)h3;
            h.Y.x4 = (int)h4;
            h.Y.x5 = (int)h5;
            h.Y.x6 = (int)h6;
            h.Y.x7 = (int)h7;
            h.Y.x8 = (int)h8;
            h.Y.x9 = (int)h9;

            /* End fe_frombytes.c */

            FieldOperations.fe_1(out h.Z);
            FieldOperations.fe_sq(out u, ref h.Y);
            FieldOperations.fe_mul(out v, ref u, ref LookupTables.d);
            FieldOperations.fe_sub(out u, ref u, ref h.Z);       /* u = y^2-1 */
            FieldOperations.fe_add(out v, ref v, ref h.Z);       /* v = dy^2+1 */

            fe_divpowm1(out h.X, ref u, ref v); /* x = uv^3(uv^7)^((q-5)/8) */

            FieldOperations.fe_sq(out vxx, ref h.X);
            FieldOperations.fe_mul(out vxx, ref vxx, ref v);
            FieldOperations.fe_sub(out check, ref vxx, ref u);    /* vx^2-u */
            if (FieldOperations.fe_isnonzero(ref check) != 0)
            {
                FieldOperations.fe_add(out check, ref vxx, ref u);  /* vx^2+u */
                if (FieldOperations.fe_isnonzero(ref check) != 0)
                {
                    h = default;
                    return -1;
                }
                FieldOperations.fe_mul(out h.X, ref h.X, ref LookupTables.sqrtm1);
            }

            if (FieldOperations.fe_isnegative(ref h.X) != (s[31] >> 7))
            {
                /* If x = 0, the sign must be positive */
                if (FieldOperations.fe_isnonzero(ref h.X) == 0)
                {
                    h = default;
                    return -1;
                }
                FieldOperations.fe_neg(out h.X, ref h.X);
            }

            FieldOperations.fe_mul(out h.T, ref h.X, ref h.Y);
            return 0;
        }

        static void ge_cached_cmov(ref GroupElementCached t, ref GroupElementCached u, byte b)
        {
            FieldOperations.fe_cmov(ref t.YplusX, ref u.YplusX, b);
            FieldOperations.fe_cmov(ref t.YminusX, ref u.YminusX, b);
            FieldOperations.fe_cmov(ref t.Z, ref u.Z, b);
            FieldOperations.fe_cmov(ref t.T2d, ref u.T2d, b);
        }

        static void ge_cached_0(out GroupElementCached r)
        {
            FieldOperations.fe_1(out r.YplusX);
            FieldOperations.fe_1(out r.YminusX);
            FieldOperations.fe_1(out r.Z);
            FieldOperations.fe_0(out r.T2d);
        }

        static void fe_copy(out FieldElement h, ref FieldElement f)
        {
            h = f;
        }

        /* Assumes that a[31] <= 127 */
        static void ge_scalarmult(out GroupElementP2 r, byte[] a, ref GroupElementP3 A)
        {
            byte[] e = new byte[64];
            int carry, carry2, i;
            GroupElementCached[] Ai = new GroupElementCached[8]; /* 1 * A, 2 * A, ..., 8 * A */
            GroupElementP1P1 t;
            GroupElementP3 u;

            carry = 0; /* 0..1 */
            for (i = 0; i < 31; i++)
            {
                carry += a[i]; /* 0..256 */
                carry2 = (carry + 8) >> 4; /* 0..16 */
                e[2 * i] = (byte)(carry - (carry2 << 4)); /* -8..7 */
                carry = (carry2 + 8) >> 4; /* 0..1 */
                e[2 * i + 1] = (byte)(carry2 - (carry << 4)); /* -8..7 */
            }
            carry += a[31]; /* 0..128 */
            carry2 = (carry + 8) >> 4; /* 0..8 */
            e[62] = (byte)(carry - (carry2 << 4)); /* -8..7 */
            e[63] = (byte)carry2; /* 0..8 */

            GroupOperations.ge_p3_to_cached(out Ai[0], ref A);
            for (i = 0; i < 7; i++)
            {
                GroupOperations.ge_add(out t, ref A, ref Ai[i]);
                GroupOperations.ge_p1p1_to_p3(out u, ref t);
                GroupOperations.ge_p3_to_cached(out Ai[i + 1], ref u);
            }

            GroupOperations.ge_p2_0(out r);
            for (i = 63; i >= 0; i--)
            {
                sbyte b = (sbyte)e[i];
                byte bnegative = GroupOperations.negative(b);
                byte babs = (byte)(b - (((-bnegative) & b) << 1));
                GroupElementCached cur, minuscur;
                GroupOperations.ge_p2_dbl(out t, ref r);
                GroupOperations.ge_p1p1_to_p2(out r, ref t);
                GroupOperations.ge_p2_dbl(out t, ref r);
                GroupOperations.ge_p1p1_to_p2(out r, ref t);
                GroupOperations.ge_p2_dbl(out t, ref r);
                GroupOperations.ge_p1p1_to_p2(out r, ref t);
                GroupOperations.ge_p2_dbl(out t, ref r);
                GroupOperations.ge_p1p1_to_p3(out u, ref t);
                ge_cached_0(out cur);
                ge_cached_cmov(ref cur, ref Ai[0], GroupOperations.equal(babs, 1));
                ge_cached_cmov(ref cur, ref Ai[1], GroupOperations.equal(babs, 2));
                ge_cached_cmov(ref cur, ref Ai[2], GroupOperations.equal(babs, 3));
                ge_cached_cmov(ref cur, ref Ai[3], GroupOperations.equal(babs, 4));
                ge_cached_cmov(ref cur, ref Ai[4], GroupOperations.equal(babs, 5));
                ge_cached_cmov(ref cur, ref Ai[5], GroupOperations.equal(babs, 6));
                ge_cached_cmov(ref cur, ref Ai[6], GroupOperations.equal(babs, 7));
                ge_cached_cmov(ref cur, ref Ai[7], GroupOperations.equal(babs, 8));
                fe_copy(out minuscur.YplusX, ref cur.YminusX);
                fe_copy(out minuscur.YminusX, ref cur.YplusX);
                fe_copy(out minuscur.Z, ref cur.Z);
                FieldOperations.fe_neg(out minuscur.T2d, ref cur.T2d);
                ge_cached_cmov(ref cur, ref minuscur, bnegative);
                GroupOperations.ge_add(out t, ref u, ref cur);
                GroupOperations.ge_p1p1_to_p2(out r, ref t);
            }
        }

        static void ge_mul8(out GroupElementP1P1 r, ref GroupElementP2 t)
        {
            GroupElementP2 u;
            GroupOperations.ge_p2_dbl(out r, ref t);
            GroupOperations.ge_p1p1_to_p2(out u, ref r);
            GroupOperations.ge_p2_dbl(out r, ref u);
            GroupOperations.ge_p1p1_to_p2(out u, ref r);
            GroupOperations.ge_p2_dbl(out r, ref u);
        }

        static void sc_reduce32(byte[] s)
        {
            long s0 = 2097151 & ScalarOperations.load_3(s, 0);
            long s1 = 2097151 & (ScalarOperations.load_4(s, 2) >> 5);
            long s2 = 2097151 & (ScalarOperations.load_3(s, 5) >> 2);
            long s3 = 2097151 & (ScalarOperations.load_4(s, 7) >> 7);
            long s4 = 2097151 & (ScalarOperations.load_4(s, 10) >> 4);
            long s5 = 2097151 & (ScalarOperations.load_3(s, 13) >> 1);
            long s6 = 2097151 & (ScalarOperations.load_4(s, 15) >> 6);
            long s7 = 2097151 & (ScalarOperations.load_3(s, 18) >> 3);
            long s8 = 2097151 & ScalarOperations.load_3(s, 21);
            long s9 = 2097151 & (ScalarOperations.load_4(s, 23) >> 5);
            long s10 = 2097151 & (ScalarOperations.load_3(s, 26) >> 2);
            long s11 = (ScalarOperations.load_4(s, 28) >> 7);
            long s12 = 0;
            long carry0;
            long carry1;
            long carry2;
            long carry3;
            long carry4;
            long carry5;
            long carry6;
            long carry7;
            long carry8;
            long carry9;
            long carry10;
            long carry11;

            carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
            carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
            carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
            carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
            carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
            carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21;

            carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
            carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
            carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
            carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
            carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
            carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21;

            s0 += s12 * 666643;
            s1 += s12 * 470296;
            s2 += s12 * 654183;
            s3 -= s12 * 997805;
            s4 += s12 * 136657;
            s5 -= s12 * 683901;
            s12 = 0;

            carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
            carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
            carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
            carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
            carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
            carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
            carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
            carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
            carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
            carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
            carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
            carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;

            s0 += s12 * 666643;
            s1 += s12 * 470296;
            s2 += s12 * 654183;
            s3 -= s12 * 997805;
            s4 += s12 * 136657;
            s5 -= s12 * 683901;

            carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
            carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
            carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
            carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
            carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
            carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
            carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
            carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
            carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
            carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
            carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;

            s[0] = (byte)(s0 >> 0);
            s[1] = (byte)(s0 >> 8);
            s[2] = (byte)((s0 >> 16) | (s1 << 5));
            s[3] = (byte)(s1 >> 3);
            s[4] = (byte)(s1 >> 11);
            s[5] = (byte)((s1 >> 19) | (s2 << 2));
            s[6] = (byte)(s2 >> 6);
            s[7] = (byte)((s2 >> 14) | (s3 << 7));
            s[8] = (byte)(s3 >> 1);
            s[9] = (byte)(s3 >> 9);
            s[10] = (byte)((s3 >> 17) | (s4 << 4));
            s[11] = (byte)(s4 >> 4);
            s[12] = (byte)(s4 >> 12);
            s[13] = (byte)((s4 >> 20) | (s5 << 1));
            s[14] = (byte)(s5 >> 7);
            s[15] = (byte)((s5 >> 15) | (s6 << 6));
            s[16] = (byte)(s6 >> 2);
            s[17] = (byte)(s6 >> 10);
            s[18] = (byte)((s6 >> 18) | (s7 << 3));
            s[19] = (byte)(s7 >> 5);
            s[20] = (byte)(s7 >> 13);
            s[21] = (byte)(s8 >> 0);
            s[22] = (byte)(s8 >> 8);
            s[23] = (byte)((s8 >> 16) | (s9 << 5));
            s[24] = (byte)(s9 >> 3);
            s[25] = (byte)(s9 >> 11);
            s[26] = (byte)((s9 >> 19) | (s10 << 2));
            s[27] = (byte)(s10 >> 6);
            s[28] = (byte)((s10 >> 14) | (s11 << 7));
            s[29] = (byte)(s11 >> 1);
            s[30] = (byte)(s11 >> 9);
            s[31] = (byte)(s11 >> 17);
        }

       private static void sc_sub(byte[] s, byte[] a, byte[] b)
        {
            long a0 = 2097151 & ScalarOperations.load_3(a, 0);
            long a1 = 2097151 & (ScalarOperations.load_4(a, 2) >> 5);
            long a2 = 2097151 & (ScalarOperations.load_3(a, 5) >> 2);
            long a3 = 2097151 & (ScalarOperations.load_4(a, 7) >> 7);
            long a4 = 2097151 & (ScalarOperations.load_4(a, 10) >> 4);
            long a5 = 2097151 & (ScalarOperations.load_3(a, 13) >> 1);
            long a6 = 2097151 & (ScalarOperations.load_4(a, 15) >> 6);
            long a7 = 2097151 & (ScalarOperations.load_3(a, 18) >> 3);
            long a8 = 2097151 & ScalarOperations.load_3(a, 21);
            long a9 = 2097151 & (ScalarOperations.load_4(a, 23) >> 5);
            long a10 = 2097151 & (ScalarOperations.load_3(a, 26) >> 2);
            long a11 = (ScalarOperations.load_4(a, 28) >> 7);
            long b0 = 2097151 & ScalarOperations.load_3(b, 0);
            long b1 = 2097151 & (ScalarOperations.load_4(b, 2) >> 5);
            long b2 = 2097151 & (ScalarOperations.load_3(b, 5) >> 2);
            long b3 = 2097151 & (ScalarOperations.load_4(b, 7) >> 7);
            long b4 = 2097151 & (ScalarOperations.load_4(b, 10) >> 4);
            long b5 = 2097151 & (ScalarOperations.load_3(b, 13) >> 1);
            long b6 = 2097151 & (ScalarOperations.load_4(b, 15) >> 6);
            long b7 = 2097151 & (ScalarOperations.load_3(b, 18) >> 3);
            long b8 = 2097151 & ScalarOperations.load_3(b, 21);
            long b9 = 2097151 & (ScalarOperations.load_4(b, 23) >> 5);
            long b10 = 2097151 & (ScalarOperations.load_3(b, 26) >> 2);
            long b11 = (ScalarOperations.load_4(b, 28) >> 7);
            long s0 = a0 - b0;
            long s1 = a1 - b1;
            long s2 = a2 - b2;
            long s3 = a3 - b3;
            long s4 = a4 - b4;
            long s5 = a5 - b5;
            long s6 = a6 - b6;
            long s7 = a7 - b7;
            long s8 = a8 - b8;
            long s9 = a9 - b9;
            long s10 = a10 - b10;
            long s11 = a11 - b11;
            long s12 = 0;
            long carry0;
            long carry1;
            long carry2;
            long carry3;
            long carry4;
            long carry5;
            long carry6;
            long carry7;
            long carry8;
            long carry9;
            long carry10;
            long carry11;

            carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
            carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
            carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
            carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
            carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
            carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21;

            carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
            carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
            carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
            carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
            carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
            carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21;

            s0 += s12 * 666643;
            s1 += s12 * 470296;
            s2 += s12 * 654183;
            s3 -= s12 * 997805;
            s4 += s12 * 136657;
            s5 -= s12 * 683901;
            s12 = 0;

            carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
            carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
            carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
            carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
            carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
            carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
            carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
            carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
            carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
            carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
            carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
            carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;

            s0 += s12 * 666643;
            s1 += s12 * 470296;
            s2 += s12 * 654183;
            s3 -= s12 * 997805;
            s4 += s12 * 136657;
            s5 -= s12 * 683901;

            carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
            carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
            carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
            carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
            carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
            carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
            carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
            carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
            carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
            carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
            carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;

            s[0] = (byte)(s0 >> 0);
            s[1] = (byte)(s0 >> 8);
            s[2] = (byte)((s0 >> 16) | (s1 << 5));
            s[3] = (byte)(s1 >> 3);
            s[4] = (byte)(s1 >> 11);
            s[5] = (byte)((s1 >> 19) | (s2 << 2));
            s[6] = (byte)(s2 >> 6);
            s[7] = (byte)((s2 >> 14) | (s3 << 7));
            s[8] = (byte)(s3 >> 1);
            s[9] = (byte)(s3 >> 9);
            s[10] = (byte)((s3 >> 17) | (s4 << 4));
            s[11] = (byte)(s4 >> 4);
            s[12] = (byte)(s4 >> 12);
            s[13] = (byte)((s4 >> 20) | (s5 << 1));
            s[14] = (byte)(s5 >> 7);
            s[15] = (byte)((s5 >> 15) | (s6 << 6));
            s[16] = (byte)(s6 >> 2);
            s[17] = (byte)(s6 >> 10);
            s[18] = (byte)((s6 >> 18) | (s7 << 3));
            s[19] = (byte)(s7 >> 5);
            s[20] = (byte)(s7 >> 13);
            s[21] = (byte)(s8 >> 0);
            s[22] = (byte)(s8 >> 8);
            s[23] = (byte)((s8 >> 16) | (s9 << 5));
            s[24] = (byte)(s9 >> 3);
            s[25] = (byte)(s9 >> 11);
            s[26] = (byte)((s9 >> 19) | (s10 << 2));
            s[27] = (byte)(s10 >> 6);
            s[28] = (byte)((s10 >> 14) | (s11 << 7));
            s[29] = (byte)(s11 >> 1);
            s[30] = (byte)(s11 >> 9);
            s[31] = (byte)(s11 >> 17);
        }

@Syyn926
Copy link

Syyn926 commented Jun 28, 2020

No worries! Thanks for the update!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants