/** * Author......: See docs/credits.txt * License.....: MIT */ #include "inc_bignum_operations.h" // n[128], input and result, n = n % m // m[128], modulo, we increased it from m[64] for speed (memory+comparison) purposes // similar to mod_512 () for 512bit modulo from OpenCL/inc_ecc_secp256k1.cl: DECLSPEC void mod_4096 (PRIVATE_AS u32 *n, PRIVATE_AS const u32 *m) { // we need to perform a modulo operation with 4096-bit % 2048-bit (bignum modulo): // 512 bytes % 256 bytes (or 128 u32 % 64 u32) // note: we increased the size of m to avoid further temp variables/copies of m // but in general the modulo is just 256 bytes // ATTENTION: least significant byte are at n[0] and m[0] /* the general modulo by shift and substract code (n = n % m): x = m; t = n >> 1; while (x <= t) x <<= 1; while (n >= m) { if (n >= x) n -= x; x >>= 1; } return n; // remainder */ /* * Start: */ // x = m; u32 x[128]; // we use a shift trick similar to the mod_512 () shortcut from // OpenCL/inc_ecc_secp256k1.cl // for (u32 i = 0; i < 64; i++) x[i] = 0; // for (u32 i = 64; i < 128; i++) x[i] = m[i - 64]; x[ 0] = 0; x[ 1] = 0; x[ 2] = 0; x[ 3] = 0; x[ 4] = 0; x[ 5] = 0; x[ 6] = 0; x[ 7] = 0; x[ 8] = 0; x[ 9] = 0; x[ 10] = 0; x[ 11] = 0; x[ 12] = 0; x[ 13] = 0; x[ 14] = 0; x[ 15] = 0; x[ 16] = 0; x[ 17] = 0; x[ 18] = 0; x[ 19] = 0; x[ 20] = 0; x[ 21] = 0; x[ 22] = 0; x[ 23] = 0; x[ 24] = 0; x[ 25] = 0; x[ 26] = 0; x[ 27] = 0; x[ 28] = 0; x[ 29] = 0; x[ 30] = 0; x[ 31] = 0; x[ 32] = 0; x[ 33] = 0; x[ 34] = 0; x[ 35] = 0; x[ 36] = 0; x[ 37] = 0; x[ 38] = 0; x[ 39] = 0; x[ 40] = 0; x[ 41] = 0; x[ 42] = 0; x[ 43] = 0; x[ 44] = 0; x[ 45] = 0; x[ 46] = 0; x[ 47] = 0; x[ 48] = 0; x[ 49] = 0; x[ 50] = 0; x[ 51] = 0; x[ 52] = 0; x[ 53] = 0; x[ 54] = 0; x[ 55] = 0; x[ 56] = 0; x[ 57] = 0; x[ 58] = 0; x[ 59] = 0; x[ 60] = 0; x[ 61] = 0; x[ 62] = 0; x[ 63] = 0; x[ 64] = m[ 0]; x[ 65] = m[ 1]; x[ 66] = m[ 2]; x[ 67] = m[ 3]; x[ 68] = m[ 4]; x[ 69] = m[ 5]; x[ 70] = m[ 6]; x[ 71] = m[ 7]; x[ 72] = m[ 8]; x[ 73] = m[ 9]; x[ 74] = m[ 10]; x[ 75] = m[ 11]; x[ 76] = m[ 12]; x[ 77] = m[ 13]; x[ 78] = m[ 14]; x[ 79] = m[ 15]; x[ 80] = m[ 16]; x[ 81] = m[ 17]; x[ 82] = m[ 18]; x[ 83] = m[ 19]; x[ 84] = m[ 20]; x[ 85] = m[ 21]; x[ 86] = m[ 22]; x[ 87] = m[ 23]; x[ 88] = m[ 24]; x[ 89] = m[ 25]; x[ 90] = m[ 26]; x[ 91] = m[ 27]; x[ 92] = m[ 28]; x[ 93] = m[ 29]; x[ 94] = m[ 30]; x[ 95] = m[ 31]; x[ 96] = m[ 32]; x[ 97] = m[ 33]; x[ 98] = m[ 34]; x[ 99] = m[ 35]; x[100] = m[ 36]; x[101] = m[ 37]; x[102] = m[ 38]; x[103] = m[ 39]; x[104] = m[ 40]; x[105] = m[ 41]; x[106] = m[ 42]; x[107] = m[ 43]; x[108] = m[ 44]; x[109] = m[ 45]; x[110] = m[ 46]; x[111] = m[ 47]; x[112] = m[ 48]; x[113] = m[ 49]; x[114] = m[ 50]; x[115] = m[ 51]; x[116] = m[ 52]; x[117] = m[ 53]; x[118] = m[ 54]; x[119] = m[ 55]; x[120] = m[ 56]; x[121] = m[ 57]; x[122] = m[ 58]; x[123] = m[ 59]; x[124] = m[ 60]; x[125] = m[ 61]; x[126] = m[ 62]; x[127] = m[ 63]; // n >= b while (n[127] >= m[127]) { u32 shift_needed = 1; for (int i = 127; i >= 0; i--) { if (n[i] < m[i]) // FAIL case { shift_needed = 0; break; } else if (n[i] > m[i]) // definitely a SUCCESS case (otherwise continue to check if equal) { break; } } if (shift_needed == 0) break; // r = x (copy it to have the original values for the subtraction) u32 r[128]; // for (u32 i = 0; i < 128; i++) r[i] = x[i]; r[ 0] = x[ 0]; r[ 1] = x[ 1]; r[ 2] = x[ 2]; r[ 3] = x[ 3]; r[ 4] = x[ 4]; r[ 5] = x[ 5]; r[ 6] = x[ 6]; r[ 7] = x[ 7]; r[ 8] = x[ 8]; r[ 9] = x[ 9]; r[ 10] = x[ 10]; r[ 11] = x[ 11]; r[ 12] = x[ 12]; r[ 13] = x[ 13]; r[ 14] = x[ 14]; r[ 15] = x[ 15]; r[ 16] = x[ 16]; r[ 17] = x[ 17]; r[ 18] = x[ 18]; r[ 19] = x[ 19]; r[ 20] = x[ 20]; r[ 21] = x[ 21]; r[ 22] = x[ 22]; r[ 23] = x[ 23]; r[ 24] = x[ 24]; r[ 25] = x[ 25]; r[ 26] = x[ 26]; r[ 27] = x[ 27]; r[ 28] = x[ 28]; r[ 29] = x[ 29]; r[ 30] = x[ 30]; r[ 31] = x[ 31]; r[ 32] = x[ 32]; r[ 33] = x[ 33]; r[ 34] = x[ 34]; r[ 35] = x[ 35]; r[ 36] = x[ 36]; r[ 37] = x[ 37]; r[ 38] = x[ 38]; r[ 39] = x[ 39]; r[ 40] = x[ 40]; r[ 41] = x[ 41]; r[ 42] = x[ 42]; r[ 43] = x[ 43]; r[ 44] = x[ 44]; r[ 45] = x[ 45]; r[ 46] = x[ 46]; r[ 47] = x[ 47]; r[ 48] = x[ 48]; r[ 49] = x[ 49]; r[ 50] = x[ 50]; r[ 51] = x[ 51]; r[ 52] = x[ 52]; r[ 53] = x[ 53]; r[ 54] = x[ 54]; r[ 55] = x[ 55]; r[ 56] = x[ 56]; r[ 57] = x[ 57]; r[ 58] = x[ 58]; r[ 59] = x[ 59]; r[ 60] = x[ 60]; r[ 61] = x[ 61]; r[ 62] = x[ 62]; r[ 63] = x[ 63]; r[ 64] = x[ 64]; r[ 65] = x[ 65]; r[ 66] = x[ 66]; r[ 67] = x[ 67]; r[ 68] = x[ 68]; r[ 69] = x[ 69]; r[ 70] = x[ 70]; r[ 71] = x[ 71]; r[ 72] = x[ 72]; r[ 73] = x[ 73]; r[ 74] = x[ 74]; r[ 75] = x[ 75]; r[ 76] = x[ 76]; r[ 77] = x[ 77]; r[ 78] = x[ 78]; r[ 79] = x[ 79]; r[ 80] = x[ 80]; r[ 81] = x[ 81]; r[ 82] = x[ 82]; r[ 83] = x[ 83]; r[ 84] = x[ 84]; r[ 85] = x[ 85]; r[ 86] = x[ 86]; r[ 87] = x[ 87]; r[ 88] = x[ 88]; r[ 89] = x[ 89]; r[ 90] = x[ 90]; r[ 91] = x[ 91]; r[ 92] = x[ 92]; r[ 93] = x[ 93]; r[ 94] = x[ 94]; r[ 95] = x[ 95]; r[ 96] = x[ 96]; r[ 97] = x[ 97]; r[ 98] = x[ 98]; r[ 99] = x[ 99]; r[100] = x[100]; r[101] = x[101]; r[102] = x[102]; r[103] = x[103]; r[104] = x[104]; r[105] = x[105]; r[106] = x[106]; r[107] = x[107]; r[108] = x[108]; r[109] = x[109]; r[110] = x[110]; r[111] = x[111]; r[112] = x[112]; r[113] = x[113]; r[114] = x[114]; r[115] = x[115]; r[116] = x[116]; r[117] = x[117]; r[118] = x[118]; r[119] = x[119]; r[120] = x[120]; r[121] = x[121]; r[122] = x[122]; r[123] = x[123]; r[124] = x[124]; r[125] = x[125]; r[126] = x[126]; r[127] = x[127]; // x >>= 1 (half it): // for (u32 i = 0; i < 127; i++) x[i] = (x[i + 1] << 31) | (x[i] >> 1); // x[127] >>= 1; x[ 0] = (x[ 1] << 31) | (x[ 0] >> 1); x[ 1] = (x[ 2] << 31) | (x[ 1] >> 1); x[ 2] = (x[ 3] << 31) | (x[ 2] >> 1); x[ 3] = (x[ 4] << 31) | (x[ 3] >> 1); x[ 4] = (x[ 5] << 31) | (x[ 4] >> 1); x[ 5] = (x[ 6] << 31) | (x[ 5] >> 1); x[ 6] = (x[ 7] << 31) | (x[ 6] >> 1); x[ 7] = (x[ 8] << 31) | (x[ 7] >> 1); x[ 8] = (x[ 9] << 31) | (x[ 8] >> 1); x[ 9] = (x[ 10] << 31) | (x[ 9] >> 1); x[ 10] = (x[ 11] << 31) | (x[ 10] >> 1); x[ 11] = (x[ 12] << 31) | (x[ 11] >> 1); x[ 12] = (x[ 13] << 31) | (x[ 12] >> 1); x[ 13] = (x[ 14] << 31) | (x[ 13] >> 1); x[ 14] = (x[ 15] << 31) | (x[ 14] >> 1); x[ 15] = (x[ 16] << 31) | (x[ 15] >> 1); x[ 16] = (x[ 17] << 31) | (x[ 16] >> 1); x[ 17] = (x[ 18] << 31) | (x[ 17] >> 1); x[ 18] = (x[ 19] << 31) | (x[ 18] >> 1); x[ 19] = (x[ 20] << 31) | (x[ 19] >> 1); x[ 20] = (x[ 21] << 31) | (x[ 20] >> 1); x[ 21] = (x[ 22] << 31) | (x[ 21] >> 1); x[ 22] = (x[ 23] << 31) | (x[ 22] >> 1); x[ 23] = (x[ 24] << 31) | (x[ 23] >> 1); x[ 24] = (x[ 25] << 31) | (x[ 24] >> 1); x[ 25] = (x[ 26] << 31) | (x[ 25] >> 1); x[ 26] = (x[ 27] << 31) | (x[ 26] >> 1); x[ 27] = (x[ 28] << 31) | (x[ 27] >> 1); x[ 28] = (x[ 29] << 31) | (x[ 28] >> 1); x[ 29] = (x[ 30] << 31) | (x[ 29] >> 1); x[ 30] = (x[ 31] << 31) | (x[ 30] >> 1); x[ 31] = (x[ 32] << 31) | (x[ 31] >> 1); x[ 32] = (x[ 33] << 31) | (x[ 32] >> 1); x[ 33] = (x[ 34] << 31) | (x[ 33] >> 1); x[ 34] = (x[ 35] << 31) | (x[ 34] >> 1); x[ 35] = (x[ 36] << 31) | (x[ 35] >> 1); x[ 36] = (x[ 37] << 31) | (x[ 36] >> 1); x[ 37] = (x[ 38] << 31) | (x[ 37] >> 1); x[ 38] = (x[ 39] << 31) | (x[ 38] >> 1); x[ 39] = (x[ 40] << 31) | (x[ 39] >> 1); x[ 40] = (x[ 41] << 31) | (x[ 40] >> 1); x[ 41] = (x[ 42] << 31) | (x[ 41] >> 1); x[ 42] = (x[ 43] << 31) | (x[ 42] >> 1); x[ 43] = (x[ 44] << 31) | (x[ 43] >> 1); x[ 44] = (x[ 45] << 31) | (x[ 44] >> 1); x[ 45] = (x[ 46] << 31) | (x[ 45] >> 1); x[ 46] = (x[ 47] << 31) | (x[ 46] >> 1); x[ 47] = (x[ 48] << 31) | (x[ 47] >> 1); x[ 48] = (x[ 49] << 31) | (x[ 48] >> 1); x[ 49] = (x[ 50] << 31) | (x[ 49] >> 1); x[ 50] = (x[ 51] << 31) | (x[ 50] >> 1); x[ 51] = (x[ 52] << 31) | (x[ 51] >> 1); x[ 52] = (x[ 53] << 31) | (x[ 52] >> 1); x[ 53] = (x[ 54] << 31) | (x[ 53] >> 1); x[ 54] = (x[ 55] << 31) | (x[ 54] >> 1); x[ 55] = (x[ 56] << 31) | (x[ 55] >> 1); x[ 56] = (x[ 57] << 31) | (x[ 56] >> 1); x[ 57] = (x[ 58] << 31) | (x[ 57] >> 1); x[ 58] = (x[ 59] << 31) | (x[ 58] >> 1); x[ 59] = (x[ 60] << 31) | (x[ 59] >> 1); x[ 60] = (x[ 61] << 31) | (x[ 60] >> 1); x[ 61] = (x[ 62] << 31) | (x[ 61] >> 1); x[ 62] = (x[ 63] << 31) | (x[ 62] >> 1); x[ 63] = (x[ 64] << 31) | (x[ 63] >> 1); x[ 64] = (x[ 65] << 31) | (x[ 64] >> 1); x[ 65] = (x[ 66] << 31) | (x[ 65] >> 1); x[ 66] = (x[ 67] << 31) | (x[ 66] >> 1); x[ 67] = (x[ 68] << 31) | (x[ 67] >> 1); x[ 68] = (x[ 69] << 31) | (x[ 68] >> 1); x[ 69] = (x[ 70] << 31) | (x[ 69] >> 1); x[ 70] = (x[ 71] << 31) | (x[ 70] >> 1); x[ 71] = (x[ 72] << 31) | (x[ 71] >> 1); x[ 72] = (x[ 73] << 31) | (x[ 72] >> 1); x[ 73] = (x[ 74] << 31) | (x[ 73] >> 1); x[ 74] = (x[ 75] << 31) | (x[ 74] >> 1); x[ 75] = (x[ 76] << 31) | (x[ 75] >> 1); x[ 76] = (x[ 77] << 31) | (x[ 76] >> 1); x[ 77] = (x[ 78] << 31) | (x[ 77] >> 1); x[ 78] = (x[ 79] << 31) | (x[ 78] >> 1); x[ 79] = (x[ 80] << 31) | (x[ 79] >> 1); x[ 80] = (x[ 81] << 31) | (x[ 80] >> 1); x[ 81] = (x[ 82] << 31) | (x[ 81] >> 1); x[ 82] = (x[ 83] << 31) | (x[ 82] >> 1); x[ 83] = (x[ 84] << 31) | (x[ 83] >> 1); x[ 84] = (x[ 85] << 31) | (x[ 84] >> 1); x[ 85] = (x[ 86] << 31) | (x[ 85] >> 1); x[ 86] = (x[ 87] << 31) | (x[ 86] >> 1); x[ 87] = (x[ 88] << 31) | (x[ 87] >> 1); x[ 88] = (x[ 89] << 31) | (x[ 88] >> 1); x[ 89] = (x[ 90] << 31) | (x[ 89] >> 1); x[ 90] = (x[ 91] << 31) | (x[ 90] >> 1); x[ 91] = (x[ 92] << 31) | (x[ 91] >> 1); x[ 92] = (x[ 93] << 31) | (x[ 92] >> 1); x[ 93] = (x[ 94] << 31) | (x[ 93] >> 1); x[ 94] = (x[ 95] << 31) | (x[ 94] >> 1); x[ 95] = (x[ 96] << 31) | (x[ 95] >> 1); x[ 96] = (x[ 97] << 31) | (x[ 96] >> 1); x[ 97] = (x[ 98] << 31) | (x[ 97] >> 1); x[ 98] = (x[ 99] << 31) | (x[ 98] >> 1); x[ 99] = (x[100] << 31) | (x[ 99] >> 1); x[100] = (x[101] << 31) | (x[100] >> 1); x[101] = (x[102] << 31) | (x[101] >> 1); x[102] = (x[103] << 31) | (x[102] >> 1); x[103] = (x[104] << 31) | (x[103] >> 1); x[104] = (x[105] << 31) | (x[104] >> 1); x[105] = (x[106] << 31) | (x[105] >> 1); x[106] = (x[107] << 31) | (x[106] >> 1); x[107] = (x[108] << 31) | (x[107] >> 1); x[108] = (x[109] << 31) | (x[108] >> 1); x[109] = (x[110] << 31) | (x[109] >> 1); x[110] = (x[111] << 31) | (x[110] >> 1); x[111] = (x[112] << 31) | (x[111] >> 1); x[112] = (x[113] << 31) | (x[112] >> 1); x[113] = (x[114] << 31) | (x[113] >> 1); x[114] = (x[115] << 31) | (x[114] >> 1); x[115] = (x[116] << 31) | (x[115] >> 1); x[116] = (x[117] << 31) | (x[116] >> 1); x[117] = (x[118] << 31) | (x[117] >> 1); x[118] = (x[119] << 31) | (x[118] >> 1); x[119] = (x[120] << 31) | (x[119] >> 1); x[120] = (x[121] << 31) | (x[120] >> 1); x[121] = (x[122] << 31) | (x[121] >> 1); x[122] = (x[123] << 31) | (x[122] >> 1); x[123] = (x[124] << 31) | (x[123] >> 1); x[124] = (x[125] << 31) | (x[124] >> 1); x[125] = (x[126] << 31) | (x[125] >> 1); x[126] = (x[127] << 31) | (x[126] >> 1); x[127] = (x[127] >> 1); /* * if (n >= r) n -= r; */ // check if (n >= r): u32 sub_needed = 1; for (int i = 127; i >= 0; i--) { if (n[i] < r[i]) // FAIL case { sub_needed = 0; break; } else if (n[i] > r[i]) // definitely a SUCCESS case (otherwise continue to check if equal) { break; } } if (sub_needed == 0) continue; // n -= r; // u32 res = 0; for (u32 i = 0; i < 128; i++) res |= r[i]; if (res == 0) break; if ((r[ 0] == 0) && (r[ 1] == 0) && (r[ 2] == 0) && (r[ 3] == 0) && (r[ 4] == 0) && (r[ 5] == 0) && (r[ 6] == 0) && (r[ 7] == 0) && (r[ 8] == 0) && (r[ 9] == 0) && (r[ 10] == 0) && (r[ 11] == 0) && (r[ 12] == 0) && (r[ 13] == 0) && (r[ 14] == 0) && (r[ 15] == 0) && (r[ 16] == 0) && (r[ 17] == 0) && (r[ 18] == 0) && (r[ 19] == 0) && (r[ 20] == 0) && (r[ 21] == 0) && (r[ 22] == 0) && (r[ 23] == 0) && (r[ 24] == 0) && (r[ 25] == 0) && (r[ 26] == 0) && (r[ 27] == 0) && (r[ 28] == 0) && (r[ 29] == 0) && (r[ 30] == 0) && (r[ 31] == 0) && (r[ 32] == 0) && (r[ 33] == 0) && (r[ 34] == 0) && (r[ 35] == 0) && (r[ 36] == 0) && (r[ 37] == 0) && (r[ 38] == 0) && (r[ 39] == 0) && (r[ 40] == 0) && (r[ 41] == 0) && (r[ 42] == 0) && (r[ 43] == 0) && (r[ 44] == 0) && (r[ 45] == 0) && (r[ 46] == 0) && (r[ 47] == 0) && (r[ 48] == 0) && (r[ 49] == 0) && (r[ 50] == 0) && (r[ 51] == 0) && (r[ 52] == 0) && (r[ 53] == 0) && (r[ 54] == 0) && (r[ 55] == 0) && (r[ 56] == 0) && (r[ 57] == 0) && (r[ 58] == 0) && (r[ 59] == 0) && (r[ 60] == 0) && (r[ 61] == 0) && (r[ 62] == 0) && (r[ 63] == 0) && (r[ 64] == 0) && (r[ 65] == 0) && (r[ 66] == 0) && (r[ 67] == 0) && (r[ 68] == 0) && (r[ 69] == 0) && (r[ 70] == 0) && (r[ 71] == 0) && (r[ 72] == 0) && (r[ 73] == 0) && (r[ 74] == 0) && (r[ 75] == 0) && (r[ 76] == 0) && (r[ 77] == 0) && (r[ 78] == 0) && (r[ 79] == 0) && (r[ 80] == 0) && (r[ 81] == 0) && (r[ 82] == 0) && (r[ 83] == 0) && (r[ 84] == 0) && (r[ 85] == 0) && (r[ 86] == 0) && (r[ 87] == 0) && (r[ 88] == 0) && (r[ 89] == 0) && (r[ 90] == 0) && (r[ 91] == 0) && (r[ 92] == 0) && (r[ 93] == 0) && (r[ 94] == 0) && (r[ 95] == 0) && (r[ 96] == 0) && (r[ 97] == 0) && (r[ 98] == 0) && (r[ 99] == 0) && (r[100] == 0) && (r[101] == 0) && (r[102] == 0) && (r[103] == 0) && (r[104] == 0) && (r[105] == 0) && (r[106] == 0) && (r[107] == 0) && (r[108] == 0) && (r[109] == 0) && (r[110] == 0) && (r[111] == 0) && (r[112] == 0) && (r[113] == 0) && (r[114] == 0) && (r[115] == 0) && (r[116] == 0) && (r[117] == 0) && (r[118] == 0) && (r[119] == 0) && (r[120] == 0) && (r[121] == 0) && (r[122] == 0) && (r[123] == 0) && (r[124] == 0) && (r[125] == 0) && (r[126] == 0) && (r[127] == 0)) break; // error if r == 0 // for (u32 i = 0; i < 128; i++) r[i] = n[i] - r[i]; r[ 0] = n[ 0] - r[ 0]; r[ 1] = n[ 1] - r[ 1]; r[ 2] = n[ 2] - r[ 2]; r[ 3] = n[ 3] - r[ 3]; r[ 4] = n[ 4] - r[ 4]; r[ 5] = n[ 5] - r[ 5]; r[ 6] = n[ 6] - r[ 6]; r[ 7] = n[ 7] - r[ 7]; r[ 8] = n[ 8] - r[ 8]; r[ 9] = n[ 9] - r[ 9]; r[ 10] = n[ 10] - r[ 10]; r[ 11] = n[ 11] - r[ 11]; r[ 12] = n[ 12] - r[ 12]; r[ 13] = n[ 13] - r[ 13]; r[ 14] = n[ 14] - r[ 14]; r[ 15] = n[ 15] - r[ 15]; r[ 16] = n[ 16] - r[ 16]; r[ 17] = n[ 17] - r[ 17]; r[ 18] = n[ 18] - r[ 18]; r[ 19] = n[ 19] - r[ 19]; r[ 20] = n[ 20] - r[ 20]; r[ 21] = n[ 21] - r[ 21]; r[ 22] = n[ 22] - r[ 22]; r[ 23] = n[ 23] - r[ 23]; r[ 24] = n[ 24] - r[ 24]; r[ 25] = n[ 25] - r[ 25]; r[ 26] = n[ 26] - r[ 26]; r[ 27] = n[ 27] - r[ 27]; r[ 28] = n[ 28] - r[ 28]; r[ 29] = n[ 29] - r[ 29]; r[ 30] = n[ 30] - r[ 30]; r[ 31] = n[ 31] - r[ 31]; r[ 32] = n[ 32] - r[ 32]; r[ 33] = n[ 33] - r[ 33]; r[ 34] = n[ 34] - r[ 34]; r[ 35] = n[ 35] - r[ 35]; r[ 36] = n[ 36] - r[ 36]; r[ 37] = n[ 37] - r[ 37]; r[ 38] = n[ 38] - r[ 38]; r[ 39] = n[ 39] - r[ 39]; r[ 40] = n[ 40] - r[ 40]; r[ 41] = n[ 41] - r[ 41]; r[ 42] = n[ 42] - r[ 42]; r[ 43] = n[ 43] - r[ 43]; r[ 44] = n[ 44] - r[ 44]; r[ 45] = n[ 45] - r[ 45]; r[ 46] = n[ 46] - r[ 46]; r[ 47] = n[ 47] - r[ 47]; r[ 48] = n[ 48] - r[ 48]; r[ 49] = n[ 49] - r[ 49]; r[ 50] = n[ 50] - r[ 50]; r[ 51] = n[ 51] - r[ 51]; r[ 52] = n[ 52] - r[ 52]; r[ 53] = n[ 53] - r[ 53]; r[ 54] = n[ 54] - r[ 54]; r[ 55] = n[ 55] - r[ 55]; r[ 56] = n[ 56] - r[ 56]; r[ 57] = n[ 57] - r[ 57]; r[ 58] = n[ 58] - r[ 58]; r[ 59] = n[ 59] - r[ 59]; r[ 60] = n[ 60] - r[ 60]; r[ 61] = n[ 61] - r[ 61]; r[ 62] = n[ 62] - r[ 62]; r[ 63] = n[ 63] - r[ 63]; r[ 64] = n[ 64] - r[ 64]; r[ 65] = n[ 65] - r[ 65]; r[ 66] = n[ 66] - r[ 66]; r[ 67] = n[ 67] - r[ 67]; r[ 68] = n[ 68] - r[ 68]; r[ 69] = n[ 69] - r[ 69]; r[ 70] = n[ 70] - r[ 70]; r[ 71] = n[ 71] - r[ 71]; r[ 72] = n[ 72] - r[ 72]; r[ 73] = n[ 73] - r[ 73]; r[ 74] = n[ 74] - r[ 74]; r[ 75] = n[ 75] - r[ 75]; r[ 76] = n[ 76] - r[ 76]; r[ 77] = n[ 77] - r[ 77]; r[ 78] = n[ 78] - r[ 78]; r[ 79] = n[ 79] - r[ 79]; r[ 80] = n[ 80] - r[ 80]; r[ 81] = n[ 81] - r[ 81]; r[ 82] = n[ 82] - r[ 82]; r[ 83] = n[ 83] - r[ 83]; r[ 84] = n[ 84] - r[ 84]; r[ 85] = n[ 85] - r[ 85]; r[ 86] = n[ 86] - r[ 86]; r[ 87] = n[ 87] - r[ 87]; r[ 88] = n[ 88] - r[ 88]; r[ 89] = n[ 89] - r[ 89]; r[ 90] = n[ 90] - r[ 90]; r[ 91] = n[ 91] - r[ 91]; r[ 92] = n[ 92] - r[ 92]; r[ 93] = n[ 93] - r[ 93]; r[ 94] = n[ 94] - r[ 94]; r[ 95] = n[ 95] - r[ 95]; r[ 96] = n[ 96] - r[ 96]; r[ 97] = n[ 97] - r[ 97]; r[ 98] = n[ 98] - r[ 98]; r[ 99] = n[ 99] - r[ 99]; r[100] = n[100] - r[100]; r[101] = n[101] - r[101]; r[102] = n[102] - r[102]; r[103] = n[103] - r[103]; r[104] = n[104] - r[104]; r[105] = n[105] - r[105]; r[106] = n[106] - r[106]; r[107] = n[107] - r[107]; r[108] = n[108] - r[108]; r[109] = n[109] - r[109]; r[110] = n[110] - r[110]; r[111] = n[111] - r[111]; r[112] = n[112] - r[112]; r[113] = n[113] - r[113]; r[114] = n[114] - r[114]; r[115] = n[115] - r[115]; r[116] = n[116] - r[116]; r[117] = n[117] - r[117]; r[118] = n[118] - r[118]; r[119] = n[119] - r[119]; r[120] = n[120] - r[120]; r[121] = n[121] - r[121]; r[122] = n[122] - r[122]; r[123] = n[123] - r[123]; r[124] = n[124] - r[124]; r[125] = n[125] - r[125]; r[126] = n[126] - r[126]; r[127] = n[127] - r[127]; // take care of the "borrow": // for (u32 i = 0; i < 127; i++) if (r[i] > n[i]) r[i + 1]--; // if (r[ 0] > n[ 0]) r[ 1]--; // if (r[ 1] > n[ 1]) r[ 2]--; // if (r[ 2] > n[ 2]) r[ 3]--; // if (r[ 3] > n[ 3]) r[ 4]--; // if (r[ 4] > n[ 4]) r[ 5]--; // if (r[ 5] > n[ 5]) r[ 6]--; // if (r[ 6] > n[ 6]) r[ 7]--; // if (r[ 7] > n[ 7]) r[ 8]--; // if (r[ 8] > n[ 8]) r[ 9]--; // if (r[ 9] > n[ 9]) r[ 10]--; // if (r[ 10] > n[ 10]) r[ 11]--; // if (r[ 11] > n[ 11]) r[ 12]--; // if (r[ 12] > n[ 12]) r[ 13]--; // if (r[ 13] > n[ 13]) r[ 14]--; // if (r[ 14] > n[ 14]) r[ 15]--; // if (r[ 15] > n[ 15]) r[ 16]--; // if (r[ 16] > n[ 16]) r[ 17]--; // if (r[ 17] > n[ 17]) r[ 18]--; // if (r[ 18] > n[ 18]) r[ 19]--; // if (r[ 19] > n[ 19]) r[ 20]--; // if (r[ 20] > n[ 20]) r[ 21]--; // if (r[ 21] > n[ 21]) r[ 22]--; // if (r[ 22] > n[ 22]) r[ 23]--; // if (r[ 23] > n[ 23]) r[ 24]--; // if (r[ 24] > n[ 24]) r[ 25]--; // if (r[ 25] > n[ 25]) r[ 26]--; // if (r[ 26] > n[ 26]) r[ 27]--; // if (r[ 27] > n[ 27]) r[ 28]--; // if (r[ 28] > n[ 28]) r[ 29]--; // if (r[ 29] > n[ 29]) r[ 30]--; // if (r[ 30] > n[ 30]) r[ 31]--; // if (r[ 31] > n[ 31]) r[ 32]--; // if (r[ 32] > n[ 32]) r[ 33]--; // if (r[ 33] > n[ 33]) r[ 34]--; // if (r[ 34] > n[ 34]) r[ 35]--; // if (r[ 35] > n[ 35]) r[ 36]--; // if (r[ 36] > n[ 36]) r[ 37]--; // if (r[ 37] > n[ 37]) r[ 38]--; // if (r[ 38] > n[ 38]) r[ 39]--; // if (r[ 39] > n[ 39]) r[ 40]--; // if (r[ 40] > n[ 40]) r[ 41]--; // if (r[ 41] > n[ 41]) r[ 42]--; // if (r[ 42] > n[ 42]) r[ 43]--; // if (r[ 43] > n[ 43]) r[ 44]--; // if (r[ 44] > n[ 44]) r[ 45]--; // if (r[ 45] > n[ 45]) r[ 46]--; // if (r[ 46] > n[ 46]) r[ 47]--; // if (r[ 47] > n[ 47]) r[ 48]--; // if (r[ 48] > n[ 48]) r[ 49]--; // if (r[ 49] > n[ 49]) r[ 50]--; // if (r[ 50] > n[ 50]) r[ 51]--; // if (r[ 51] > n[ 51]) r[ 52]--; // if (r[ 52] > n[ 52]) r[ 53]--; // if (r[ 53] > n[ 53]) r[ 54]--; // if (r[ 54] > n[ 54]) r[ 55]--; // if (r[ 55] > n[ 55]) r[ 56]--; // if (r[ 56] > n[ 56]) r[ 57]--; // if (r[ 57] > n[ 57]) r[ 58]--; // if (r[ 58] > n[ 58]) r[ 59]--; // if (r[ 59] > n[ 59]) r[ 60]--; // if (r[ 60] > n[ 60]) r[ 61]--; // if (r[ 61] > n[ 61]) r[ 62]--; // if (r[ 62] > n[ 62]) r[ 63]--; // if (r[ 63] > n[ 63]) r[ 64]--; // if (r[ 64] > n[ 64]) r[ 65]--; // if (r[ 65] > n[ 65]) r[ 66]--; // if (r[ 66] > n[ 66]) r[ 67]--; // if (r[ 67] > n[ 67]) r[ 68]--; // if (r[ 68] > n[ 68]) r[ 69]--; // if (r[ 69] > n[ 69]) r[ 70]--; // if (r[ 70] > n[ 70]) r[ 71]--; // if (r[ 71] > n[ 71]) r[ 72]--; // if (r[ 72] > n[ 72]) r[ 73]--; // if (r[ 73] > n[ 73]) r[ 74]--; // if (r[ 74] > n[ 74]) r[ 75]--; // if (r[ 75] > n[ 75]) r[ 76]--; // if (r[ 76] > n[ 76]) r[ 77]--; // if (r[ 77] > n[ 77]) r[ 78]--; // if (r[ 78] > n[ 78]) r[ 79]--; // if (r[ 79] > n[ 79]) r[ 80]--; // if (r[ 80] > n[ 80]) r[ 81]--; // if (r[ 81] > n[ 81]) r[ 82]--; // if (r[ 82] > n[ 82]) r[ 83]--; // if (r[ 83] > n[ 83]) r[ 84]--; // if (r[ 84] > n[ 84]) r[ 85]--; // if (r[ 85] > n[ 85]) r[ 86]--; // if (r[ 86] > n[ 86]) r[ 87]--; // if (r[ 87] > n[ 87]) r[ 88]--; // if (r[ 88] > n[ 88]) r[ 89]--; // if (r[ 89] > n[ 89]) r[ 90]--; // if (r[ 90] > n[ 90]) r[ 91]--; // if (r[ 91] > n[ 91]) r[ 92]--; // if (r[ 92] > n[ 92]) r[ 93]--; // if (r[ 93] > n[ 93]) r[ 94]--; // if (r[ 94] > n[ 94]) r[ 95]--; // if (r[ 95] > n[ 95]) r[ 96]--; // if (r[ 96] > n[ 96]) r[ 97]--; // if (r[ 97] > n[ 97]) r[ 98]--; // if (r[ 98] > n[ 98]) r[ 99]--; // if (r[ 99] > n[ 99]) r[100]--; // if (r[100] > n[100]) r[101]--; // if (r[101] > n[101]) r[102]--; // if (r[102] > n[102]) r[103]--; // if (r[103] > n[103]) r[104]--; // if (r[104] > n[104]) r[105]--; // if (r[105] > n[105]) r[106]--; // if (r[106] > n[106]) r[107]--; // if (r[107] > n[107]) r[108]--; // if (r[108] > n[108]) r[109]--; // if (r[109] > n[109]) r[110]--; // if (r[110] > n[110]) r[111]--; // if (r[111] > n[111]) r[112]--; // if (r[112] > n[112]) r[113]--; // if (r[113] > n[113]) r[114]--; // if (r[114] > n[114]) r[115]--; // if (r[115] > n[115]) r[116]--; // if (r[116] > n[116]) r[117]--; // if (r[117] > n[117]) r[118]--; // if (r[118] > n[118]) r[119]--; // if (r[119] > n[119]) r[120]--; // if (r[120] > n[120]) r[121]--; // if (r[121] > n[121]) r[122]--; // if (r[122] > n[122]) r[123]--; // if (r[123] > n[123]) r[124]--; // if (r[124] > n[124]) r[125]--; // if (r[125] > n[125]) r[126]--; // if (r[126] > n[126]) r[127]--; // for (u32 i = 1; i < 128; i++) r[i] -= r[i - 1] > n[i - 1]; r[ 1] -= r[ 0] > n[ 0]; r[ 2] -= r[ 1] > n[ 1]; r[ 3] -= r[ 2] > n[ 2]; r[ 4] -= r[ 3] > n[ 3]; r[ 5] -= r[ 4] > n[ 4]; r[ 6] -= r[ 5] > n[ 5]; r[ 7] -= r[ 6] > n[ 6]; r[ 8] -= r[ 7] > n[ 7]; r[ 9] -= r[ 8] > n[ 8]; r[ 10] -= r[ 9] > n[ 9]; r[ 11] -= r[ 10] > n[ 10]; r[ 12] -= r[ 11] > n[ 11]; r[ 13] -= r[ 12] > n[ 12]; r[ 14] -= r[ 13] > n[ 13]; r[ 15] -= r[ 14] > n[ 14]; r[ 16] -= r[ 15] > n[ 15]; r[ 17] -= r[ 16] > n[ 16]; r[ 18] -= r[ 17] > n[ 17]; r[ 19] -= r[ 18] > n[ 18]; r[ 20] -= r[ 19] > n[ 19]; r[ 21] -= r[ 20] > n[ 20]; r[ 22] -= r[ 21] > n[ 21]; r[ 23] -= r[ 22] > n[ 22]; r[ 24] -= r[ 23] > n[ 23]; r[ 25] -= r[ 24] > n[ 24]; r[ 26] -= r[ 25] > n[ 25]; r[ 27] -= r[ 26] > n[ 26]; r[ 28] -= r[ 27] > n[ 27]; r[ 29] -= r[ 28] > n[ 28]; r[ 30] -= r[ 29] > n[ 29]; r[ 31] -= r[ 30] > n[ 30]; r[ 32] -= r[ 31] > n[ 31]; r[ 33] -= r[ 32] > n[ 32]; r[ 34] -= r[ 33] > n[ 33]; r[ 35] -= r[ 34] > n[ 34]; r[ 36] -= r[ 35] > n[ 35]; r[ 37] -= r[ 36] > n[ 36]; r[ 38] -= r[ 37] > n[ 37]; r[ 39] -= r[ 38] > n[ 38]; r[ 40] -= r[ 39] > n[ 39]; r[ 41] -= r[ 40] > n[ 40]; r[ 42] -= r[ 41] > n[ 41]; r[ 43] -= r[ 42] > n[ 42]; r[ 44] -= r[ 43] > n[ 43]; r[ 45] -= r[ 44] > n[ 44]; r[ 46] -= r[ 45] > n[ 45]; r[ 47] -= r[ 46] > n[ 46]; r[ 48] -= r[ 47] > n[ 47]; r[ 49] -= r[ 48] > n[ 48]; r[ 50] -= r[ 49] > n[ 49]; r[ 51] -= r[ 50] > n[ 50]; r[ 52] -= r[ 51] > n[ 51]; r[ 53] -= r[ 52] > n[ 52]; r[ 54] -= r[ 53] > n[ 53]; r[ 55] -= r[ 54] > n[ 54]; r[ 56] -= r[ 55] > n[ 55]; r[ 57] -= r[ 56] > n[ 56]; r[ 58] -= r[ 57] > n[ 57]; r[ 59] -= r[ 58] > n[ 58]; r[ 60] -= r[ 59] > n[ 59]; r[ 61] -= r[ 60] > n[ 60]; r[ 62] -= r[ 61] > n[ 61]; r[ 63] -= r[ 62] > n[ 62]; r[ 64] -= r[ 63] > n[ 63]; r[ 65] -= r[ 64] > n[ 64]; r[ 66] -= r[ 65] > n[ 65]; r[ 67] -= r[ 66] > n[ 66]; r[ 68] -= r[ 67] > n[ 67]; r[ 69] -= r[ 68] > n[ 68]; r[ 70] -= r[ 69] > n[ 69]; r[ 71] -= r[ 70] > n[ 70]; r[ 72] -= r[ 71] > n[ 71]; r[ 73] -= r[ 72] > n[ 72]; r[ 74] -= r[ 73] > n[ 73]; r[ 75] -= r[ 74] > n[ 74]; r[ 76] -= r[ 75] > n[ 75]; r[ 77] -= r[ 76] > n[ 76]; r[ 78] -= r[ 77] > n[ 77]; r[ 79] -= r[ 78] > n[ 78]; r[ 80] -= r[ 79] > n[ 79]; r[ 81] -= r[ 80] > n[ 80]; r[ 82] -= r[ 81] > n[ 81]; r[ 83] -= r[ 82] > n[ 82]; r[ 84] -= r[ 83] > n[ 83]; r[ 85] -= r[ 84] > n[ 84]; r[ 86] -= r[ 85] > n[ 85]; r[ 87] -= r[ 86] > n[ 86]; r[ 88] -= r[ 87] > n[ 87]; r[ 89] -= r[ 88] > n[ 88]; r[ 90] -= r[ 89] > n[ 89]; r[ 91] -= r[ 90] > n[ 90]; r[ 92] -= r[ 91] > n[ 91]; r[ 93] -= r[ 92] > n[ 92]; r[ 94] -= r[ 93] > n[ 93]; r[ 95] -= r[ 94] > n[ 94]; r[ 96] -= r[ 95] > n[ 95]; r[ 97] -= r[ 96] > n[ 96]; r[ 98] -= r[ 97] > n[ 97]; r[ 99] -= r[ 98] > n[ 98]; r[100] -= r[ 99] > n[ 99]; r[101] -= r[100] > n[100]; r[102] -= r[101] > n[101]; r[103] -= r[102] > n[102]; r[104] -= r[103] > n[103]; r[105] -= r[104] > n[104]; r[106] -= r[105] > n[105]; r[107] -= r[106] > n[106]; r[108] -= r[107] > n[107]; r[109] -= r[108] > n[108]; r[110] -= r[109] > n[109]; r[111] -= r[110] > n[110]; r[112] -= r[111] > n[111]; r[113] -= r[112] > n[112]; r[114] -= r[113] > n[113]; r[115] -= r[114] > n[114]; r[116] -= r[115] > n[115]; r[117] -= r[116] > n[116]; r[118] -= r[117] > n[117]; r[119] -= r[118] > n[118]; r[120] -= r[119] > n[119]; r[121] -= r[120] > n[120]; r[122] -= r[121] > n[121]; r[123] -= r[122] > n[122]; r[124] -= r[123] > n[123]; r[125] -= r[124] > n[124]; r[126] -= r[125] > n[125]; r[127] -= r[126] > n[126]; // for (u32 i = 0; i < 128; i++) n[i] = r[i]; n[ 0] = r[ 0]; n[ 1] = r[ 1]; n[ 2] = r[ 2]; n[ 3] = r[ 3]; n[ 4] = r[ 4]; n[ 5] = r[ 5]; n[ 6] = r[ 6]; n[ 7] = r[ 7]; n[ 8] = r[ 8]; n[ 9] = r[ 9]; n[ 10] = r[ 10]; n[ 11] = r[ 11]; n[ 12] = r[ 12]; n[ 13] = r[ 13]; n[ 14] = r[ 14]; n[ 15] = r[ 15]; n[ 16] = r[ 16]; n[ 17] = r[ 17]; n[ 18] = r[ 18]; n[ 19] = r[ 19]; n[ 20] = r[ 20]; n[ 21] = r[ 21]; n[ 22] = r[ 22]; n[ 23] = r[ 23]; n[ 24] = r[ 24]; n[ 25] = r[ 25]; n[ 26] = r[ 26]; n[ 27] = r[ 27]; n[ 28] = r[ 28]; n[ 29] = r[ 29]; n[ 30] = r[ 30]; n[ 31] = r[ 31]; n[ 32] = r[ 32]; n[ 33] = r[ 33]; n[ 34] = r[ 34]; n[ 35] = r[ 35]; n[ 36] = r[ 36]; n[ 37] = r[ 37]; n[ 38] = r[ 38]; n[ 39] = r[ 39]; n[ 40] = r[ 40]; n[ 41] = r[ 41]; n[ 42] = r[ 42]; n[ 43] = r[ 43]; n[ 44] = r[ 44]; n[ 45] = r[ 45]; n[ 46] = r[ 46]; n[ 47] = r[ 47]; n[ 48] = r[ 48]; n[ 49] = r[ 49]; n[ 50] = r[ 50]; n[ 51] = r[ 51]; n[ 52] = r[ 52]; n[ 53] = r[ 53]; n[ 54] = r[ 54]; n[ 55] = r[ 55]; n[ 56] = r[ 56]; n[ 57] = r[ 57]; n[ 58] = r[ 58]; n[ 59] = r[ 59]; n[ 60] = r[ 60]; n[ 61] = r[ 61]; n[ 62] = r[ 62]; n[ 63] = r[ 63]; n[ 64] = r[ 64]; n[ 65] = r[ 65]; n[ 66] = r[ 66]; n[ 67] = r[ 67]; n[ 68] = r[ 68]; n[ 69] = r[ 69]; n[ 70] = r[ 70]; n[ 71] = r[ 71]; n[ 72] = r[ 72]; n[ 73] = r[ 73]; n[ 74] = r[ 74]; n[ 75] = r[ 75]; n[ 76] = r[ 76]; n[ 77] = r[ 77]; n[ 78] = r[ 78]; n[ 79] = r[ 79]; n[ 80] = r[ 80]; n[ 81] = r[ 81]; n[ 82] = r[ 82]; n[ 83] = r[ 83]; n[ 84] = r[ 84]; n[ 85] = r[ 85]; n[ 86] = r[ 86]; n[ 87] = r[ 87]; n[ 88] = r[ 88]; n[ 89] = r[ 89]; n[ 90] = r[ 90]; n[ 91] = r[ 91]; n[ 92] = r[ 92]; n[ 93] = r[ 93]; n[ 94] = r[ 94]; n[ 95] = r[ 95]; n[ 96] = r[ 96]; n[ 97] = r[ 97]; n[ 98] = r[ 98]; n[ 99] = r[ 99]; n[100] = r[100]; n[101] = r[101]; n[102] = r[102]; n[103] = r[103]; n[104] = r[104]; n[105] = r[105]; n[106] = r[106]; n[107] = r[107]; n[108] = r[108]; n[109] = r[109]; n[110] = r[110]; n[111] = r[111]; n[112] = r[112]; n[113] = r[113]; n[114] = r[114]; n[115] = r[115]; n[116] = r[116]; n[117] = r[117]; n[118] = r[118]; n[119] = r[119]; n[120] = r[120]; n[121] = r[121]; n[122] = r[122]; n[123] = r[123]; n[124] = r[124]; n[125] = r[125]; n[126] = r[126]; n[127] = r[127]; } } // r[128], result, r = x * y // x[ 64], multiplier (1st factor) // y[ 64], multiplicand (2nd factor) DECLSPEC void mul (PRIVATE_AS u32 *r, PRIVATE_AS const u32 *x, PRIVATE_AS const u32 *y) { for (u32 i = 0; i < 64; i++) { u64 c = 0; // carry for (u32 j = 0; j < 64; j++) { const u32 idx = i + j; const u64 p = (u64) x[i] * y[j]; // main product const u32 u = p >> 32; const u32 l = p >> 0; const u64 s = c + r[idx] + l; // sum c = (s >> 32) + u; r[idx] = (s >> 0); } r[i + 64] = (u32) c; } } // r[64], result, r = lower_bits (x * y), r = (x * y) & mask // x[64], multiplier (1st factor) // y[64], multiplicand (2nd factor) // only compute lower bits (because we exploit our Montgomery "mask") DECLSPEC void mul_masked (PRIVATE_AS u32 *r, PRIVATE_AS const u32 *x, PRIVATE_AS const u32 *y) { for (u32 i = 0; i < 64; i++) { u64 c = 0; // carry // for (u32 j = 0; j < 64; j++) // { // const u32 idx = i + j; // if (idx >= 63) break; // ... // } // or: for (u32 j = 0; j < (64 - i); j++) // our implied "mask" (only lower 256 bytes for idx) { const u32 idx = i + j; const u64 p = (u64) x[i] * y[j]; // product const u32 u = p >> 32; const u32 l = p >> 0; const u64 s = c + r[idx] + l; // sum c = (s >> 32) + u; r[idx] = (s >> 0); } } } // x [ 64], multiplier, input and at the same time output, (x = (x * y) % m) // y [ 64], multiplicand // m [128], modulo // fact[ 64], our m' (actually it is fact[65]) DECLSPEC void mul_mod128 (PRIVATE_AS u32 *x, PRIVATE_AS const u32 *y, PRIVATE_AS const u32 *m, PRIVATE_AS const u32 *fact) { // 1st multiplication // p = x * y u32 p[128] = { 0 }; mul (p, x, y); // 2nd multiplication // t = ((p & mask) * fact) & mask, (we optimize this in mul_masked ()) u32 t[64] = { 0 }; // or use t[128] here, but not needed mul_masked (t, p, fact); // 3rd multiplication // z = t * m u32 z[128] = { 0 }; mul (z, t, m); // result: // t = (p + z) >> bits // u32 t[128] = { 0 }; // optimization, smaller t[] array: // u32 t[ 64] = { 0 }; // for (u32 i = 0; i < 128; i++) t[i] = p[i] + z[i]; // t[ 0] = p[ 0] + z[ 0]; t[ 1] = p[ 1] + z[ 1]; // t[ 2] = p[ 2] + z[ 2]; t[ 3] = p[ 3] + z[ 3]; // t[ 4] = p[ 4] + z[ 4]; t[ 5] = p[ 5] + z[ 5]; // t[ 6] = p[ 6] + z[ 6]; t[ 7] = p[ 7] + z[ 7]; // t[ 8] = p[ 8] + z[ 8]; t[ 9] = p[ 9] + z[ 9]; // t[ 10] = p[ 10] + z[ 10]; t[ 11] = p[ 11] + z[ 11]; // t[ 12] = p[ 12] + z[ 12]; t[ 13] = p[ 13] + z[ 13]; // t[ 14] = p[ 14] + z[ 14]; t[ 15] = p[ 15] + z[ 15]; // t[ 16] = p[ 16] + z[ 16]; t[ 17] = p[ 17] + z[ 17]; // t[ 18] = p[ 18] + z[ 18]; t[ 19] = p[ 19] + z[ 19]; // t[ 20] = p[ 20] + z[ 20]; t[ 21] = p[ 21] + z[ 21]; // t[ 22] = p[ 22] + z[ 22]; t[ 23] = p[ 23] + z[ 23]; // t[ 24] = p[ 24] + z[ 24]; t[ 25] = p[ 25] + z[ 25]; // t[ 26] = p[ 26] + z[ 26]; t[ 27] = p[ 27] + z[ 27]; // t[ 28] = p[ 28] + z[ 28]; t[ 29] = p[ 29] + z[ 29]; // t[ 30] = p[ 30] + z[ 30]; t[ 31] = p[ 31] + z[ 31]; // t[ 32] = p[ 32] + z[ 32]; t[ 33] = p[ 33] + z[ 33]; // t[ 34] = p[ 34] + z[ 34]; t[ 35] = p[ 35] + z[ 35]; // t[ 36] = p[ 36] + z[ 36]; t[ 37] = p[ 37] + z[ 37]; // t[ 38] = p[ 38] + z[ 38]; t[ 39] = p[ 39] + z[ 39]; // t[ 40] = p[ 40] + z[ 40]; t[ 41] = p[ 41] + z[ 41]; // t[ 42] = p[ 42] + z[ 42]; t[ 43] = p[ 43] + z[ 43]; // t[ 44] = p[ 44] + z[ 44]; t[ 45] = p[ 45] + z[ 45]; // t[ 46] = p[ 46] + z[ 46]; t[ 47] = p[ 47] + z[ 47]; // t[ 48] = p[ 48] + z[ 48]; t[ 49] = p[ 49] + z[ 49]; // t[ 50] = p[ 50] + z[ 50]; t[ 51] = p[ 51] + z[ 51]; // t[ 52] = p[ 52] + z[ 52]; t[ 53] = p[ 53] + z[ 53]; // t[ 54] = p[ 54] + z[ 54]; t[ 55] = p[ 55] + z[ 55]; // t[ 56] = p[ 56] + z[ 56]; t[ 57] = p[ 57] + z[ 57]; // t[ 58] = p[ 58] + z[ 58]; t[ 59] = p[ 59] + z[ 59]; // t[ 60] = p[ 60] + z[ 60]; t[ 61] = p[ 61] + z[ 61]; // t[ 62] = p[ 62] + z[ 62]; t[ 63] = p[ 63] + z[ 63]; // t[ 64] = p[ 64] + z[ 64]; t[ 65] = p[ 65] + z[ 65]; // t[ 66] = p[ 66] + z[ 66]; t[ 67] = p[ 67] + z[ 67]; // t[ 68] = p[ 68] + z[ 68]; t[ 69] = p[ 69] + z[ 69]; // t[ 70] = p[ 70] + z[ 70]; t[ 71] = p[ 71] + z[ 71]; // t[ 72] = p[ 72] + z[ 72]; t[ 73] = p[ 73] + z[ 73]; // t[ 74] = p[ 74] + z[ 74]; t[ 75] = p[ 75] + z[ 75]; // t[ 76] = p[ 76] + z[ 76]; t[ 77] = p[ 77] + z[ 77]; // t[ 78] = p[ 78] + z[ 78]; t[ 79] = p[ 79] + z[ 79]; // t[ 80] = p[ 80] + z[ 80]; t[ 81] = p[ 81] + z[ 81]; // t[ 82] = p[ 82] + z[ 82]; t[ 83] = p[ 83] + z[ 83]; // t[ 84] = p[ 84] + z[ 84]; t[ 85] = p[ 85] + z[ 85]; // t[ 86] = p[ 86] + z[ 86]; t[ 87] = p[ 87] + z[ 87]; // t[ 88] = p[ 88] + z[ 88]; t[ 89] = p[ 89] + z[ 89]; // t[ 90] = p[ 90] + z[ 90]; t[ 91] = p[ 91] + z[ 91]; // t[ 92] = p[ 92] + z[ 92]; t[ 93] = p[ 93] + z[ 93]; // t[ 94] = p[ 94] + z[ 94]; t[ 95] = p[ 95] + z[ 95]; // t[ 96] = p[ 96] + z[ 96]; t[ 97] = p[ 97] + z[ 97]; // t[ 98] = p[ 98] + z[ 98]; t[ 99] = p[ 99] + z[ 99]; // t[100] = p[100] + z[100]; t[101] = p[101] + z[101]; // t[102] = p[102] + z[102]; t[103] = p[103] + z[103]; // t[104] = p[104] + z[104]; t[105] = p[105] + z[105]; // t[106] = p[106] + z[106]; t[107] = p[107] + z[107]; // t[108] = p[108] + z[108]; t[109] = p[109] + z[109]; // t[110] = p[110] + z[110]; t[111] = p[111] + z[111]; // t[112] = p[112] + z[112]; t[113] = p[113] + z[113]; // t[114] = p[114] + z[114]; t[115] = p[115] + z[115]; // t[116] = p[116] + z[116]; t[117] = p[117] + z[117]; // t[118] = p[118] + z[118]; t[119] = p[119] + z[119]; // t[120] = p[120] + z[120]; t[121] = p[121] + z[121]; // t[122] = p[122] + z[122]; t[123] = p[123] + z[123]; // t[124] = p[124] + z[124]; t[125] = p[125] + z[125]; // t[126] = p[126] + z[126]; t[127] = p[127] + z[127]; // optimization, we shift it down already here: // for (u32 i = 0; i < 64; i++) t[i] = p[i + 64] + z[i + 64]; t[ 0] = p[ 64] + z[ 64]; t[ 1] = p[ 65] + z[ 65]; t[ 2] = p[ 66] + z[ 66]; t[ 3] = p[ 67] + z[ 67]; t[ 4] = p[ 68] + z[ 68]; t[ 5] = p[ 69] + z[ 69]; t[ 6] = p[ 70] + z[ 70]; t[ 7] = p[ 71] + z[ 71]; t[ 8] = p[ 72] + z[ 72]; t[ 9] = p[ 73] + z[ 73]; t[10] = p[ 74] + z[ 74]; t[11] = p[ 75] + z[ 75]; t[12] = p[ 76] + z[ 76]; t[13] = p[ 77] + z[ 77]; t[14] = p[ 78] + z[ 78]; t[15] = p[ 79] + z[ 79]; t[16] = p[ 80] + z[ 80]; t[17] = p[ 81] + z[ 81]; t[18] = p[ 82] + z[ 82]; t[19] = p[ 83] + z[ 83]; t[20] = p[ 84] + z[ 84]; t[21] = p[ 85] + z[ 85]; t[22] = p[ 86] + z[ 86]; t[23] = p[ 87] + z[ 87]; t[24] = p[ 88] + z[ 88]; t[25] = p[ 89] + z[ 89]; t[26] = p[ 90] + z[ 90]; t[27] = p[ 91] + z[ 91]; t[28] = p[ 92] + z[ 92]; t[29] = p[ 93] + z[ 93]; t[30] = p[ 94] + z[ 94]; t[31] = p[ 95] + z[ 95]; t[32] = p[ 96] + z[ 96]; t[33] = p[ 97] + z[ 97]; t[34] = p[ 98] + z[ 98]; t[35] = p[ 99] + z[ 99]; t[36] = p[100] + z[100]; t[37] = p[101] + z[101]; t[38] = p[102] + z[102]; t[39] = p[103] + z[103]; t[40] = p[104] + z[104]; t[41] = p[105] + z[105]; t[42] = p[106] + z[106]; t[43] = p[107] + z[107]; t[44] = p[108] + z[108]; t[45] = p[109] + z[109]; t[46] = p[110] + z[110]; t[47] = p[111] + z[111]; t[48] = p[112] + z[112]; t[49] = p[113] + z[113]; t[50] = p[114] + z[114]; t[51] = p[115] + z[115]; t[52] = p[116] + z[116]; t[53] = p[117] + z[117]; t[54] = p[118] + z[118]; t[55] = p[119] + z[119]; t[56] = p[120] + z[120]; t[57] = p[121] + z[121]; t[58] = p[122] + z[122]; t[59] = p[123] + z[123]; t[60] = p[124] + z[124]; t[61] = p[125] + z[125]; t[62] = p[126] + z[126]; t[63] = p[127] + z[127]; // take care of the carry for the addition above (i.e check for "overflows") // for (u32 i = 1; i < 128; i++) t[i] += t[i - 1] < p[i - 1]; // t[ 1] += t[ 0] < p[ 0]; // t[ 2] += t[ 1] < p[ 1]; // t[ 3] += t[ 2] < p[ 2]; // t[ 4] += t[ 3] < p[ 3]; // t[ 5] += t[ 4] < p[ 4]; // t[ 6] += t[ 5] < p[ 5]; // t[ 7] += t[ 6] < p[ 6]; // t[ 8] += t[ 7] < p[ 7]; // t[ 9] += t[ 8] < p[ 8]; // t[ 10] += t[ 9] < p[ 9]; // t[ 11] += t[ 10] < p[ 10]; // t[ 12] += t[ 11] < p[ 11]; // t[ 13] += t[ 12] < p[ 12]; // t[ 14] += t[ 13] < p[ 13]; // t[ 15] += t[ 14] < p[ 14]; // t[ 16] += t[ 15] < p[ 15]; // t[ 17] += t[ 16] < p[ 16]; // t[ 18] += t[ 17] < p[ 17]; // t[ 19] += t[ 18] < p[ 18]; // t[ 20] += t[ 19] < p[ 19]; // t[ 21] += t[ 20] < p[ 20]; // t[ 22] += t[ 21] < p[ 21]; // t[ 23] += t[ 22] < p[ 22]; // t[ 24] += t[ 23] < p[ 23]; // t[ 25] += t[ 24] < p[ 24]; // t[ 26] += t[ 25] < p[ 25]; // t[ 27] += t[ 26] < p[ 26]; // t[ 28] += t[ 27] < p[ 27]; // t[ 29] += t[ 28] < p[ 28]; // t[ 30] += t[ 29] < p[ 29]; // t[ 31] += t[ 30] < p[ 30]; // t[ 32] += t[ 31] < p[ 31]; // t[ 33] += t[ 32] < p[ 32]; // t[ 34] += t[ 33] < p[ 33]; // t[ 35] += t[ 34] < p[ 34]; // t[ 36] += t[ 35] < p[ 35]; // t[ 37] += t[ 36] < p[ 36]; // t[ 38] += t[ 37] < p[ 37]; // t[ 39] += t[ 38] < p[ 38]; // t[ 40] += t[ 39] < p[ 39]; // t[ 41] += t[ 40] < p[ 40]; // t[ 42] += t[ 41] < p[ 41]; // t[ 43] += t[ 42] < p[ 42]; // t[ 44] += t[ 43] < p[ 43]; // t[ 45] += t[ 44] < p[ 44]; // t[ 46] += t[ 45] < p[ 45]; // t[ 47] += t[ 46] < p[ 46]; // t[ 48] += t[ 47] < p[ 47]; // t[ 49] += t[ 48] < p[ 48]; // t[ 50] += t[ 49] < p[ 49]; // t[ 51] += t[ 50] < p[ 50]; // t[ 52] += t[ 51] < p[ 51]; // t[ 53] += t[ 52] < p[ 52]; // t[ 54] += t[ 53] < p[ 53]; // t[ 55] += t[ 54] < p[ 54]; // t[ 56] += t[ 55] < p[ 55]; // t[ 57] += t[ 56] < p[ 56]; // t[ 58] += t[ 57] < p[ 57]; // t[ 59] += t[ 58] < p[ 58]; // t[ 60] += t[ 59] < p[ 59]; // t[ 61] += t[ 60] < p[ 60]; // t[ 62] += t[ 61] < p[ 61]; // t[ 63] += t[ 62] < p[ 62]; // t[ 64] += t; // we know that it overflows (due to the way Montgomery works) // t[ 65] += t[ 64] < p[ 64]; // t[ 66] += t[ 65] < p[ 65]; // t[ 67] += t[ 66] < p[ 66]; // t[ 68] += t[ 67] < p[ 67]; // t[ 69] += t[ 68] < p[ 68]; // t[ 70] += t[ 69] < p[ 69]; // t[ 71] += t[ 70] < p[ 70]; // t[ 72] += t[ 71] < p[ 71]; // t[ 73] += t[ 72] < p[ 72]; // t[ 74] += t[ 73] < p[ 73]; // t[ 75] += t[ 74] < p[ 74]; // t[ 76] += t[ 75] < p[ 75]; // t[ 77] += t[ 76] < p[ 76]; // t[ 78] += t[ 77] < p[ 77]; // t[ 79] += t[ 78] < p[ 78]; // t[ 80] += t[ 79] < p[ 79]; // t[ 81] += t[ 80] < p[ 80]; // t[ 82] += t[ 81] < p[ 81]; // t[ 83] += t[ 82] < p[ 82]; // t[ 84] += t[ 83] < p[ 83]; // t[ 85] += t[ 84] < p[ 84]; // t[ 86] += t[ 85] < p[ 85]; // t[ 87] += t[ 86] < p[ 86]; // t[ 88] += t[ 87] < p[ 87]; // t[ 89] += t[ 88] < p[ 88]; // t[ 90] += t[ 89] < p[ 89]; // t[ 91] += t[ 90] < p[ 90]; // t[ 92] += t[ 91] < p[ 91]; // t[ 93] += t[ 92] < p[ 92]; // t[ 94] += t[ 93] < p[ 93]; // t[ 95] += t[ 94] < p[ 94]; // t[ 96] += t[ 95] < p[ 95]; // t[ 97] += t[ 96] < p[ 96]; // t[ 98] += t[ 97] < p[ 97]; // t[ 99] += t[ 98] < p[ 98]; // t[100] += t[ 99] < p[ 99]; // t[101] += t[100] < p[100]; // t[102] += t[101] < p[101]; // t[103] += t[102] < p[102]; // t[104] += t[103] < p[103]; // t[105] += t[104] < p[104]; // t[106] += t[105] < p[105]; // t[107] += t[106] < p[106]; // t[108] += t[107] < p[107]; // t[109] += t[108] < p[108]; // t[110] += t[109] < p[109]; // t[111] += t[110] < p[110]; // t[112] += t[111] < p[111]; // t[113] += t[112] < p[112]; // t[114] += t[113] < p[113]; // t[115] += t[114] < p[114]; // t[116] += t[115] < p[115]; // t[117] += t[116] < p[116]; // t[118] += t[117] < p[117]; // t[119] += t[118] < p[118]; // t[120] += t[119] < p[119]; // t[121] += t[120] < p[120]; // t[122] += t[121] < p[121]; // t[123] += t[122] < p[122]; // t[124] += t[123] < p[123]; // t[125] += t[124] < p[124]; // t[126] += t[125] < p[125]; // t[127] += t[126] < p[126]; t[ 0] += 1; // we know that it overflows (due to the way Montgomery works) // for (u32 i = 1; i < 64; i++) t[i] += t[i - 1] < p[i + 63]; t[ 1] += t[ 0] < p[ 64]; t[ 2] += t[ 1] < p[ 65]; t[ 3] += t[ 2] < p[ 66]; t[ 4] += t[ 3] < p[ 67]; t[ 5] += t[ 4] < p[ 68]; t[ 6] += t[ 5] < p[ 69]; t[ 7] += t[ 6] < p[ 70]; t[ 8] += t[ 7] < p[ 71]; t[ 9] += t[ 8] < p[ 72]; t[10] += t[ 9] < p[ 73]; t[11] += t[10] < p[ 74]; t[12] += t[11] < p[ 75]; t[13] += t[12] < p[ 76]; t[14] += t[13] < p[ 77]; t[15] += t[14] < p[ 78]; t[16] += t[15] < p[ 79]; t[17] += t[16] < p[ 80]; t[18] += t[17] < p[ 81]; t[19] += t[18] < p[ 82]; t[20] += t[19] < p[ 83]; t[21] += t[20] < p[ 84]; t[22] += t[21] < p[ 85]; t[23] += t[22] < p[ 86]; t[24] += t[23] < p[ 87]; t[25] += t[24] < p[ 88]; t[26] += t[25] < p[ 89]; t[27] += t[26] < p[ 90]; t[28] += t[27] < p[ 91]; t[29] += t[28] < p[ 92]; t[30] += t[29] < p[ 93]; t[31] += t[30] < p[ 94]; t[32] += t[31] < p[ 95]; t[33] += t[32] < p[ 96]; t[34] += t[33] < p[ 97]; t[35] += t[34] < p[ 98]; t[36] += t[35] < p[ 99]; t[37] += t[36] < p[100]; t[38] += t[37] < p[101]; t[39] += t[38] < p[102]; t[40] += t[39] < p[103]; t[41] += t[40] < p[104]; t[42] += t[41] < p[105]; t[43] += t[42] < p[106]; t[44] += t[43] < p[107]; t[45] += t[44] < p[108]; t[46] += t[45] < p[109]; t[47] += t[46] < p[110]; t[48] += t[47] < p[111]; t[49] += t[48] < p[112]; t[50] += t[49] < p[113]; t[51] += t[50] < p[114]; t[52] += t[51] < p[115]; t[53] += t[52] < p[116]; t[54] += t[53] < p[117]; t[55] += t[54] < p[118]; t[56] += t[55] < p[119]; t[57] += t[56] < p[120]; t[58] += t[57] < p[121]; t[59] += t[58] < p[122]; t[60] += t[59] < p[123]; t[61] += t[60] < p[124]; t[62] += t[61] < p[125]; t[63] += t[62] < p[126]; // VERY IMPORTANT: if we have an overflow at the highest u32, we need to do the substraction const u32 c = t[63] < p[127]; // carry / overflow // x = t // (x is actually already our result, but it's possible that we need to do the modulo/substract) // for (u32 i = 0; i < 64; i++) x[i] = t[i]; x[ 0] = t[ 0]; x[ 1] = t[ 1]; x[ 2] = t[ 2]; x[ 3] = t[ 3]; x[ 4] = t[ 4]; x[ 5] = t[ 5]; x[ 6] = t[ 6]; x[ 7] = t[ 7]; x[ 8] = t[ 8]; x[ 9] = t[ 9]; x[10] = t[10]; x[11] = t[11]; x[12] = t[12]; x[13] = t[13]; x[14] = t[14]; x[15] = t[15]; x[16] = t[16]; x[17] = t[17]; x[18] = t[18]; x[19] = t[19]; x[20] = t[20]; x[21] = t[21]; x[22] = t[22]; x[23] = t[23]; x[24] = t[24]; x[25] = t[25]; x[26] = t[26]; x[27] = t[27]; x[28] = t[28]; x[29] = t[29]; x[30] = t[30]; x[31] = t[31]; x[32] = t[32]; x[33] = t[33]; x[34] = t[34]; x[35] = t[35]; x[36] = t[36]; x[37] = t[37]; x[38] = t[38]; x[39] = t[39]; x[40] = t[40]; x[41] = t[41]; x[42] = t[42]; x[43] = t[43]; x[44] = t[44]; x[45] = t[45]; x[46] = t[46]; x[47] = t[47]; x[48] = t[48]; x[49] = t[49]; x[50] = t[50]; x[51] = t[51]; x[52] = t[52]; x[53] = t[53]; x[54] = t[54]; x[55] = t[55]; x[56] = t[56]; x[57] = t[57]; x[58] = t[58]; x[59] = t[59]; x[60] = t[60]; x[61] = t[61]; x[62] = t[62]; x[63] = t[63]; // if (x >= m) x -= m // (check if we need to substract, or do a "fast modulo") u32 sub_needed = 1; if (c == 0) { for (int i = 63; i >= 0; i--) { if (x[i] < m[i]) // FAIL case { sub_needed = 0; break; } else if (x[i] > m[i]) // definitely a SUCCESS case (otherwise continue to check if equal) { break; } } } if (sub_needed == 1) { // x -= m // for (u32 i = 0; i < 64; i++) x[i] -= m[i]; x[ 0] -= m[ 0]; x[ 1] -= m[ 1]; x[ 2] -= m[ 2]; x[ 3] -= m[ 3]; x[ 4] -= m[ 4]; x[ 5] -= m[ 5]; x[ 6] -= m[ 6]; x[ 7] -= m[ 7]; x[ 8] -= m[ 8]; x[ 9] -= m[ 9]; x[10] -= m[10]; x[11] -= m[11]; x[12] -= m[12]; x[13] -= m[13]; x[14] -= m[14]; x[15] -= m[15]; x[16] -= m[16]; x[17] -= m[17]; x[18] -= m[18]; x[19] -= m[19]; x[20] -= m[20]; x[21] -= m[21]; x[22] -= m[22]; x[23] -= m[23]; x[24] -= m[24]; x[25] -= m[25]; x[26] -= m[26]; x[27] -= m[27]; x[28] -= m[28]; x[29] -= m[29]; x[30] -= m[30]; x[31] -= m[31]; x[32] -= m[32]; x[33] -= m[33]; x[34] -= m[34]; x[35] -= m[35]; x[36] -= m[36]; x[37] -= m[37]; x[38] -= m[38]; x[39] -= m[39]; x[40] -= m[40]; x[41] -= m[41]; x[42] -= m[42]; x[43] -= m[43]; x[44] -= m[44]; x[45] -= m[45]; x[46] -= m[46]; x[47] -= m[47]; x[48] -= m[48]; x[49] -= m[49]; x[50] -= m[50]; x[51] -= m[51]; x[52] -= m[52]; x[53] -= m[53]; x[54] -= m[54]; x[55] -= m[55]; x[56] -= m[56]; x[57] -= m[57]; x[58] -= m[58]; x[59] -= m[59]; x[60] -= m[60]; x[61] -= m[61]; x[62] -= m[62]; x[63] -= m[63]; // take care of the "borrow": // for (u32 i = 0; i < 63; i++) if (x[i] > t[i]) x[i + 1]--; // if (x[ 0] > t[ 0]) x[ 1]--; // if (x[ 1] > t[ 1]) x[ 2]--; // if (x[ 2] > t[ 2]) x[ 3]--; // if (x[ 3] > t[ 3]) x[ 4]--; // if (x[ 4] > t[ 4]) x[ 5]--; // if (x[ 5] > t[ 5]) x[ 6]--; // if (x[ 6] > t[ 6]) x[ 7]--; // if (x[ 7] > t[ 7]) x[ 8]--; // if (x[ 8] > t[ 8]) x[ 9]--; // if (x[ 9] > t[ 9]) x[ 10]--; // if (x[ 10] > t[ 10]) x[ 11]--; // if (x[ 11] > t[ 11]) x[ 12]--; // if (x[ 12] > t[ 12]) x[ 13]--; // if (x[ 13] > t[ 13]) x[ 14]--; // if (x[ 14] > t[ 14]) x[ 15]--; // if (x[ 15] > t[ 15]) x[ 16]--; // if (x[ 16] > t[ 16]) x[ 17]--; // if (x[ 17] > t[ 17]) x[ 18]--; // if (x[ 18] > t[ 18]) x[ 19]--; // if (x[ 19] > t[ 19]) x[ 20]--; // if (x[ 20] > t[ 20]) x[ 21]--; // if (x[ 21] > t[ 21]) x[ 22]--; // if (x[ 22] > t[ 22]) x[ 23]--; // if (x[ 23] > t[ 23]) x[ 24]--; // if (x[ 24] > t[ 24]) x[ 25]--; // if (x[ 25] > t[ 25]) x[ 26]--; // if (x[ 26] > t[ 26]) x[ 27]--; // if (x[ 27] > t[ 27]) x[ 28]--; // if (x[ 28] > t[ 28]) x[ 29]--; // if (x[ 29] > t[ 29]) x[ 30]--; // if (x[ 30] > t[ 30]) x[ 31]--; // if (x[ 31] > t[ 31]) x[ 32]--; // if (x[ 32] > t[ 32]) x[ 33]--; // if (x[ 33] > t[ 33]) x[ 34]--; // if (x[ 34] > t[ 34]) x[ 35]--; // if (x[ 35] > t[ 35]) x[ 36]--; // if (x[ 36] > t[ 36]) x[ 37]--; // if (x[ 37] > t[ 37]) x[ 38]--; // if (x[ 38] > t[ 38]) x[ 39]--; // if (x[ 39] > t[ 39]) x[ 40]--; // if (x[ 40] > t[ 40]) x[ 41]--; // if (x[ 41] > t[ 41]) x[ 42]--; // if (x[ 42] > t[ 42]) x[ 43]--; // if (x[ 43] > t[ 43]) x[ 44]--; // if (x[ 44] > t[ 44]) x[ 45]--; // if (x[ 45] > t[ 45]) x[ 46]--; // if (x[ 46] > t[ 46]) x[ 47]--; // if (x[ 47] > t[ 47]) x[ 48]--; // if (x[ 48] > t[ 48]) x[ 49]--; // if (x[ 49] > t[ 49]) x[ 50]--; // if (x[ 50] > t[ 50]) x[ 51]--; // if (x[ 51] > t[ 51]) x[ 52]--; // if (x[ 52] > t[ 52]) x[ 53]--; // if (x[ 53] > t[ 53]) x[ 54]--; // if (x[ 54] > t[ 54]) x[ 55]--; // if (x[ 55] > t[ 55]) x[ 56]--; // if (x[ 56] > t[ 56]) x[ 57]--; // if (x[ 57] > t[ 57]) x[ 58]--; // if (x[ 58] > t[ 58]) x[ 59]--; // if (x[ 59] > t[ 59]) x[ 60]--; // if (x[ 60] > t[ 60]) x[ 61]--; // if (x[ 61] > t[ 61]) x[ 62]--; // if (x[ 62] > t[ 62]) x[ 63]--; // for (u32 i = 1; i < 64; i++) x[i] -= x[i - 1] > t[i - 1]; x[ 1] -= x[ 0] > t[ 0]; x[ 2] -= x[ 1] > t[ 1]; x[ 3] -= x[ 2] > t[ 2]; x[ 4] -= x[ 3] > t[ 3]; x[ 5] -= x[ 4] > t[ 4]; x[ 6] -= x[ 5] > t[ 5]; x[ 7] -= x[ 6] > t[ 6]; x[ 8] -= x[ 7] > t[ 7]; x[ 9] -= x[ 8] > t[ 8]; x[10] -= x[ 9] > t[ 9]; x[11] -= x[10] > t[10]; x[12] -= x[11] > t[11]; x[13] -= x[12] > t[12]; x[14] -= x[13] > t[13]; x[15] -= x[14] > t[14]; x[16] -= x[15] > t[15]; x[17] -= x[16] > t[16]; x[18] -= x[17] > t[17]; x[19] -= x[18] > t[18]; x[20] -= x[19] > t[19]; x[21] -= x[20] > t[20]; x[22] -= x[21] > t[21]; x[23] -= x[22] > t[22]; x[24] -= x[23] > t[23]; x[25] -= x[24] > t[24]; x[26] -= x[25] > t[25]; x[27] -= x[26] > t[26]; x[28] -= x[27] > t[27]; x[29] -= x[28] > t[28]; x[30] -= x[29] > t[29]; x[31] -= x[30] > t[30]; x[32] -= x[31] > t[31]; x[33] -= x[32] > t[32]; x[34] -= x[33] > t[33]; x[35] -= x[34] > t[34]; x[36] -= x[35] > t[35]; x[37] -= x[36] > t[36]; x[38] -= x[37] > t[37]; x[39] -= x[38] > t[38]; x[40] -= x[39] > t[39]; x[41] -= x[40] > t[40]; x[42] -= x[41] > t[41]; x[43] -= x[42] > t[42]; x[44] -= x[43] > t[43]; x[45] -= x[44] > t[44]; x[46] -= x[45] > t[45]; x[47] -= x[46] > t[46]; x[48] -= x[47] > t[47]; x[49] -= x[48] > t[48]; x[50] -= x[49] > t[49]; x[51] -= x[50] > t[50]; x[52] -= x[51] > t[51]; x[53] -= x[52] > t[52]; x[54] -= x[53] > t[53]; x[55] -= x[54] > t[54]; x[56] -= x[55] > t[55]; x[57] -= x[56] > t[56]; x[58] -= x[57] > t[57]; x[59] -= x[58] > t[58]; x[60] -= x[59] > t[59]; x[61] -= x[60] > t[60]; x[62] -= x[61] > t[61]; x[63] -= x[62] > t[62]; } } // r [ 64], input (reducer % m) and at the same time output, r = (y ^ x) % m // u32 b_pre[10240], precomputed base powers (160 powers for each bit of SHA1 * 64 bytes) // y [ 5], exponent (in standard form, not Montgomery) // m [ 128], modulo // fact [ 64], our m' (actually it is fact[65]) DECLSPEC void pow_mod_precomp_g (PRIVATE_AS u32 *r, PRIVATE_AS const u32 *b_pre, PRIVATE_AS const u32 *y, PRIVATE_AS const u32 *m, PRIVATE_AS const u32 *fact) { for (u32 i = 0; i < 160; i++) { const u32 div = i / 32; const u32 mod = i % 32; // & 31 const u32 bit_set = (y[div] >> mod) & 1; if (bit_set == 1) mul_mod128 (r, b_pre + i * 64, m, fact); } } // r [ 64], input (reducer % m) and at the same time output, r = (y ^ x) % m // x [ 64], our main Montgomery number (base, generator) // y [ 5], our SHA1 vector, exponent (in standard form, not Montgomery) // m [128], modulo // fact[ 64], our m' (actually it is fact[65]) // we replaced this with pow_mod_precomp_g () DECLSPEC void pow_mod (PRIVATE_AS u32 *r, PRIVATE_AS u32 *x, PRIVATE_AS const u32 *y, PRIVATE_AS const u32 *m, PRIVATE_AS const u32 *fact) { u32 highest_bit = 0; for (highest_bit = 159; highest_bit >= 1; highest_bit--) { const u32 div = highest_bit / 32; const u32 mod = highest_bit % 32; // & 31 // if we find a bit that is set to 1: const u32 bit_set = (y[div] >> mod) & 1; if (bit_set == 1) break; } for (u32 i = 0; i <= highest_bit; i++) { const u32 div = i / 32; const u32 mod = i % 32; // & 31 const u32 bit_set = (y[div] >> mod) & 1; if (bit_set == 1) mul_mod128 (r, x, m, fact); mul_mod128 (x, x, m, fact); } } // u [ 64], rinv (r') output // v [ 65], fact (m') output, we only set the first 256 bytes, but we need 1 extra u32 (or byte) // m [128], modulo DECLSPEC void simple_euclidean_gcd (PRIVATE_AS u32 *u, PRIVATE_AS u32 *v, PRIVATE_AS const u32 *m) { // outputs u and v must be initialized to ALL zeros u[0] = 1; // v[0] = 0; // we skip this next step, since we know "r" in advance: // u32 r[65] = { 0 }; // r[64] = 1; // // // t = r: // // u32 t[65] = { 0 }; // // for (u32 i = 0; i < 65; i++) t[i] = r[i]; // // t[ 0] = r[ 0]; t[ 1] = r[ 1]; t[ 2] = r[ 2]; t[ 3] = r[ 3]; // t[ 4] = r[ 4]; t[ 5] = r[ 5]; t[ 6] = r[ 6]; t[ 7] = r[ 7]; // t[ 8] = r[ 8]; t[ 9] = r[ 9]; t[10] = r[10]; t[11] = r[11]; // t[12] = r[12]; t[13] = r[13]; t[14] = r[14]; t[15] = r[15]; // t[16] = r[16]; t[17] = r[17]; t[18] = r[18]; t[19] = r[19]; // t[20] = r[20]; t[21] = r[21]; t[22] = r[22]; t[23] = r[23]; // t[24] = r[24]; t[25] = r[25]; t[26] = r[26]; t[27] = r[27]; // t[28] = r[28]; t[29] = r[29]; t[30] = r[30]; t[31] = r[31]; // t[32] = r[32]; t[33] = r[33]; t[34] = r[34]; t[35] = r[35]; // t[36] = r[36]; t[37] = r[37]; t[38] = r[38]; t[39] = r[39]; // t[40] = r[40]; t[41] = r[41]; t[42] = r[42]; t[43] = r[43]; // t[44] = r[44]; t[45] = r[45]; t[46] = r[46]; t[47] = r[47]; // t[48] = r[48]; t[49] = r[49]; t[50] = r[50]; t[51] = r[51]; // t[52] = r[52]; t[53] = r[53]; t[54] = r[54]; t[55] = r[55]; // t[56] = r[56]; t[57] = r[57]; t[58] = r[58]; t[59] = r[59]; // t[60] = r[60]; t[61] = r[61]; t[62] = r[62]; t[63] = r[63]; // t[64] = r[64]; // // while ((t[ 0] != 0) || (t[ 1] != 0) || (t[ 2] != 0) || (t[ 3] != 0) || // (t[ 4] != 0) || (t[ 5] != 0) || (t[ 6] != 0) || (t[ 7] != 0) || // (t[ 8] != 0) || (t[ 9] != 0) || (t[10] != 0) || (t[11] != 0) || // (t[12] != 0) || (t[13] != 0) || (t[14] != 0) || (t[15] != 0) || // (t[16] != 0) || (t[17] != 0) || (t[18] != 0) || (t[19] != 0) || // (t[20] != 0) || (t[21] != 0) || (t[22] != 0) || (t[23] != 0) || // (t[24] != 0) || (t[25] != 0) || (t[26] != 0) || (t[27] != 0) || // (t[28] != 0) || (t[29] != 0) || (t[30] != 0) || (t[31] != 0) || // (t[32] != 0) || (t[33] != 0) || (t[34] != 0) || (t[35] != 0) || // (t[36] != 0) || (t[37] != 0) || (t[38] != 0) || (t[39] != 0) || // (t[40] != 0) || (t[41] != 0) || (t[42] != 0) || (t[43] != 0) || // (t[44] != 0) || (t[45] != 0) || (t[46] != 0) || (t[47] != 0) || // (t[48] != 0) || (t[49] != 0) || (t[50] != 0) || (t[51] != 0) || // (t[52] != 0) || (t[53] != 0) || (t[54] != 0) || (t[55] != 0) || // (t[56] != 0) || (t[57] != 0) || (t[58] != 0) || (t[59] != 0) || // (t[60] != 0) || (t[61] != 0) || (t[62] != 0) || (t[63] != 0) || // (t[64] != 0)) // { // // t >>= 1: // // t[ 0] = (t[ 1] << 31) | (t[ 0] >> 1); // t[ 1] = (t[ 2] << 31) | (t[ 1] >> 1); // t[ 2] = (t[ 3] << 31) | (t[ 2] >> 1); // t[ 3] = (t[ 4] << 31) | (t[ 3] >> 1); // t[ 4] = (t[ 5] << 31) | (t[ 4] >> 1); // t[ 5] = (t[ 6] << 31) | (t[ 5] >> 1); // t[ 6] = (t[ 7] << 31) | (t[ 6] >> 1); // t[ 7] = (t[ 8] << 31) | (t[ 7] >> 1); // t[ 8] = (t[ 9] << 31) | (t[ 8] >> 1); // t[ 9] = (t[ 10] << 31) | (t[ 9] >> 1); // t[ 10] = (t[ 11] << 31) | (t[ 10] >> 1); // t[ 11] = (t[ 12] << 31) | (t[ 11] >> 1); // t[ 12] = (t[ 13] << 31) | (t[ 12] >> 1); // t[ 13] = (t[ 14] << 31) | (t[ 13] >> 1); // t[ 14] = (t[ 15] << 31) | (t[ 14] >> 1); // t[ 15] = (t[ 16] << 31) | (t[ 15] >> 1); // t[ 16] = (t[ 17] << 31) | (t[ 16] >> 1); // t[ 17] = (t[ 18] << 31) | (t[ 17] >> 1); // t[ 18] = (t[ 19] << 31) | (t[ 18] >> 1); // t[ 19] = (t[ 20] << 31) | (t[ 19] >> 1); // t[ 20] = (t[ 21] << 31) | (t[ 20] >> 1); // t[ 21] = (t[ 22] << 31) | (t[ 21] >> 1); // t[ 22] = (t[ 23] << 31) | (t[ 22] >> 1); // t[ 23] = (t[ 24] << 31) | (t[ 23] >> 1); // t[ 24] = (t[ 25] << 31) | (t[ 24] >> 1); // t[ 25] = (t[ 26] << 31) | (t[ 25] >> 1); // t[ 26] = (t[ 27] << 31) | (t[ 26] >> 1); // t[ 27] = (t[ 28] << 31) | (t[ 27] >> 1); // t[ 28] = (t[ 29] << 31) | (t[ 28] >> 1); // t[ 29] = (t[ 30] << 31) | (t[ 29] >> 1); // t[ 30] = (t[ 31] << 31) | (t[ 30] >> 1); // t[ 31] = (t[ 32] << 31) | (t[ 31] >> 1); // t[ 32] = (t[ 33] << 31) | (t[ 32] >> 1); // t[ 33] = (t[ 34] << 31) | (t[ 33] >> 1); // t[ 34] = (t[ 35] << 31) | (t[ 34] >> 1); // t[ 35] = (t[ 36] << 31) | (t[ 35] >> 1); // t[ 36] = (t[ 37] << 31) | (t[ 36] >> 1); // t[ 37] = (t[ 38] << 31) | (t[ 37] >> 1); // t[ 38] = (t[ 39] << 31) | (t[ 38] >> 1); // t[ 39] = (t[ 40] << 31) | (t[ 39] >> 1); // t[ 40] = (t[ 41] << 31) | (t[ 40] >> 1); // t[ 41] = (t[ 42] << 31) | (t[ 41] >> 1); // t[ 42] = (t[ 43] << 31) | (t[ 42] >> 1); // t[ 43] = (t[ 44] << 31) | (t[ 43] >> 1); // t[ 44] = (t[ 45] << 31) | (t[ 44] >> 1); // t[ 45] = (t[ 46] << 31) | (t[ 45] >> 1); // t[ 46] = (t[ 47] << 31) | (t[ 46] >> 1); // t[ 47] = (t[ 48] << 31) | (t[ 47] >> 1); // t[ 48] = (t[ 49] << 31) | (t[ 48] >> 1); // t[ 49] = (t[ 50] << 31) | (t[ 49] >> 1); // t[ 50] = (t[ 51] << 31) | (t[ 50] >> 1); // t[ 51] = (t[ 52] << 31) | (t[ 51] >> 1); // t[ 52] = (t[ 53] << 31) | (t[ 52] >> 1); // t[ 53] = (t[ 54] << 31) | (t[ 53] >> 1); // t[ 54] = (t[ 55] << 31) | (t[ 54] >> 1); // t[ 55] = (t[ 56] << 31) | (t[ 55] >> 1); // t[ 56] = (t[ 57] << 31) | (t[ 56] >> 1); // t[ 57] = (t[ 58] << 31) | (t[ 57] >> 1); // t[ 58] = (t[ 59] << 31) | (t[ 58] >> 1); // t[ 59] = (t[ 60] << 31) | (t[ 59] >> 1); // t[ 60] = (t[ 61] << 31) | (t[ 60] >> 1); // t[ 61] = (t[ 62] << 31) | (t[ 61] >> 1); // t[ 62] = (t[ 63] << 31) | (t[ 62] >> 1); // t[ 63] = (t[ 64] << 31) | (t[ 63] >> 1); // t[ 64] = (t[ 64] >> 1); // // ... // } // we use this optimization (we know "r" in advance, hard-coded/fixed) for (u32 i = 0; i < 2049; i++) { if ((u[0] & 1) == 0) { // u >>= 1: // for (u32 i = 0; i < 63; i++) u[i] = (u[i + 1] << 31) | (u[i] >> 1); // u[63] >>= 1; u[ 0] = (u[ 1] << 31) | (u[ 0] >> 1); u[ 1] = (u[ 2] << 31) | (u[ 1] >> 1); u[ 2] = (u[ 3] << 31) | (u[ 2] >> 1); u[ 3] = (u[ 4] << 31) | (u[ 3] >> 1); u[ 4] = (u[ 5] << 31) | (u[ 4] >> 1); u[ 5] = (u[ 6] << 31) | (u[ 5] >> 1); u[ 6] = (u[ 7] << 31) | (u[ 6] >> 1); u[ 7] = (u[ 8] << 31) | (u[ 7] >> 1); u[ 8] = (u[ 9] << 31) | (u[ 8] >> 1); u[ 9] = (u[ 10] << 31) | (u[ 9] >> 1); u[ 10] = (u[ 11] << 31) | (u[ 10] >> 1); u[ 11] = (u[ 12] << 31) | (u[ 11] >> 1); u[ 12] = (u[ 13] << 31) | (u[ 12] >> 1); u[ 13] = (u[ 14] << 31) | (u[ 13] >> 1); u[ 14] = (u[ 15] << 31) | (u[ 14] >> 1); u[ 15] = (u[ 16] << 31) | (u[ 15] >> 1); u[ 16] = (u[ 17] << 31) | (u[ 16] >> 1); u[ 17] = (u[ 18] << 31) | (u[ 17] >> 1); u[ 18] = (u[ 19] << 31) | (u[ 18] >> 1); u[ 19] = (u[ 20] << 31) | (u[ 19] >> 1); u[ 20] = (u[ 21] << 31) | (u[ 20] >> 1); u[ 21] = (u[ 22] << 31) | (u[ 21] >> 1); u[ 22] = (u[ 23] << 31) | (u[ 22] >> 1); u[ 23] = (u[ 24] << 31) | (u[ 23] >> 1); u[ 24] = (u[ 25] << 31) | (u[ 24] >> 1); u[ 25] = (u[ 26] << 31) | (u[ 25] >> 1); u[ 26] = (u[ 27] << 31) | (u[ 26] >> 1); u[ 27] = (u[ 28] << 31) | (u[ 27] >> 1); u[ 28] = (u[ 29] << 31) | (u[ 28] >> 1); u[ 29] = (u[ 30] << 31) | (u[ 29] >> 1); u[ 30] = (u[ 31] << 31) | (u[ 30] >> 1); u[ 31] = (u[ 32] << 31) | (u[ 31] >> 1); u[ 32] = (u[ 33] << 31) | (u[ 32] >> 1); u[ 33] = (u[ 34] << 31) | (u[ 33] >> 1); u[ 34] = (u[ 35] << 31) | (u[ 34] >> 1); u[ 35] = (u[ 36] << 31) | (u[ 35] >> 1); u[ 36] = (u[ 37] << 31) | (u[ 36] >> 1); u[ 37] = (u[ 38] << 31) | (u[ 37] >> 1); u[ 38] = (u[ 39] << 31) | (u[ 38] >> 1); u[ 39] = (u[ 40] << 31) | (u[ 39] >> 1); u[ 40] = (u[ 41] << 31) | (u[ 40] >> 1); u[ 41] = (u[ 42] << 31) | (u[ 41] >> 1); u[ 42] = (u[ 43] << 31) | (u[ 42] >> 1); u[ 43] = (u[ 44] << 31) | (u[ 43] >> 1); u[ 44] = (u[ 45] << 31) | (u[ 44] >> 1); u[ 45] = (u[ 46] << 31) | (u[ 45] >> 1); u[ 46] = (u[ 47] << 31) | (u[ 46] >> 1); u[ 47] = (u[ 48] << 31) | (u[ 47] >> 1); u[ 48] = (u[ 49] << 31) | (u[ 48] >> 1); u[ 49] = (u[ 50] << 31) | (u[ 49] >> 1); u[ 50] = (u[ 51] << 31) | (u[ 50] >> 1); u[ 51] = (u[ 52] << 31) | (u[ 51] >> 1); u[ 52] = (u[ 53] << 31) | (u[ 52] >> 1); u[ 53] = (u[ 54] << 31) | (u[ 53] >> 1); u[ 54] = (u[ 55] << 31) | (u[ 54] >> 1); u[ 55] = (u[ 56] << 31) | (u[ 55] >> 1); u[ 56] = (u[ 57] << 31) | (u[ 56] >> 1); u[ 57] = (u[ 58] << 31) | (u[ 57] >> 1); u[ 58] = (u[ 59] << 31) | (u[ 58] >> 1); u[ 59] = (u[ 60] << 31) | (u[ 59] >> 1); u[ 60] = (u[ 61] << 31) | (u[ 60] >> 1); u[ 61] = (u[ 62] << 31) | (u[ 61] >> 1); u[ 62] = (u[ 63] << 31) | (u[ 62] >> 1); u[ 63] = (u[ 63] >> 1); // v >>= 1 // for (u32 i = 0; i < 64; i++) v[i] = (v[i + 1] << 31) | (v[i] >> 1); // v[64] >>= 1; v[ 0] = (v[ 1] << 31) | (v[ 0] >> 1); v[ 1] = (v[ 2] << 31) | (v[ 1] >> 1); v[ 2] = (v[ 3] << 31) | (v[ 2] >> 1); v[ 3] = (v[ 4] << 31) | (v[ 3] >> 1); v[ 4] = (v[ 5] << 31) | (v[ 4] >> 1); v[ 5] = (v[ 6] << 31) | (v[ 5] >> 1); v[ 6] = (v[ 7] << 31) | (v[ 6] >> 1); v[ 7] = (v[ 8] << 31) | (v[ 7] >> 1); v[ 8] = (v[ 9] << 31) | (v[ 8] >> 1); v[ 9] = (v[ 10] << 31) | (v[ 9] >> 1); v[ 10] = (v[ 11] << 31) | (v[ 10] >> 1); v[ 11] = (v[ 12] << 31) | (v[ 11] >> 1); v[ 12] = (v[ 13] << 31) | (v[ 12] >> 1); v[ 13] = (v[ 14] << 31) | (v[ 13] >> 1); v[ 14] = (v[ 15] << 31) | (v[ 14] >> 1); v[ 15] = (v[ 16] << 31) | (v[ 15] >> 1); v[ 16] = (v[ 17] << 31) | (v[ 16] >> 1); v[ 17] = (v[ 18] << 31) | (v[ 17] >> 1); v[ 18] = (v[ 19] << 31) | (v[ 18] >> 1); v[ 19] = (v[ 20] << 31) | (v[ 19] >> 1); v[ 20] = (v[ 21] << 31) | (v[ 20] >> 1); v[ 21] = (v[ 22] << 31) | (v[ 21] >> 1); v[ 22] = (v[ 23] << 31) | (v[ 22] >> 1); v[ 23] = (v[ 24] << 31) | (v[ 23] >> 1); v[ 24] = (v[ 25] << 31) | (v[ 24] >> 1); v[ 25] = (v[ 26] << 31) | (v[ 25] >> 1); v[ 26] = (v[ 27] << 31) | (v[ 26] >> 1); v[ 27] = (v[ 28] << 31) | (v[ 27] >> 1); v[ 28] = (v[ 29] << 31) | (v[ 28] >> 1); v[ 29] = (v[ 30] << 31) | (v[ 29] >> 1); v[ 30] = (v[ 31] << 31) | (v[ 30] >> 1); v[ 31] = (v[ 32] << 31) | (v[ 31] >> 1); v[ 32] = (v[ 33] << 31) | (v[ 32] >> 1); v[ 33] = (v[ 34] << 31) | (v[ 33] >> 1); v[ 34] = (v[ 35] << 31) | (v[ 34] >> 1); v[ 35] = (v[ 36] << 31) | (v[ 35] >> 1); v[ 36] = (v[ 37] << 31) | (v[ 36] >> 1); v[ 37] = (v[ 38] << 31) | (v[ 37] >> 1); v[ 38] = (v[ 39] << 31) | (v[ 38] >> 1); v[ 39] = (v[ 40] << 31) | (v[ 39] >> 1); v[ 40] = (v[ 41] << 31) | (v[ 40] >> 1); v[ 41] = (v[ 42] << 31) | (v[ 41] >> 1); v[ 42] = (v[ 43] << 31) | (v[ 42] >> 1); v[ 43] = (v[ 44] << 31) | (v[ 43] >> 1); v[ 44] = (v[ 45] << 31) | (v[ 44] >> 1); v[ 45] = (v[ 46] << 31) | (v[ 45] >> 1); v[ 46] = (v[ 47] << 31) | (v[ 46] >> 1); v[ 47] = (v[ 48] << 31) | (v[ 47] >> 1); v[ 48] = (v[ 49] << 31) | (v[ 48] >> 1); v[ 49] = (v[ 50] << 31) | (v[ 49] >> 1); v[ 50] = (v[ 51] << 31) | (v[ 50] >> 1); v[ 51] = (v[ 52] << 31) | (v[ 51] >> 1); v[ 52] = (v[ 53] << 31) | (v[ 52] >> 1); v[ 53] = (v[ 54] << 31) | (v[ 53] >> 1); v[ 54] = (v[ 55] << 31) | (v[ 54] >> 1); v[ 55] = (v[ 56] << 31) | (v[ 55] >> 1); v[ 56] = (v[ 57] << 31) | (v[ 56] >> 1); v[ 57] = (v[ 58] << 31) | (v[ 57] >> 1); v[ 58] = (v[ 59] << 31) | (v[ 58] >> 1); v[ 59] = (v[ 60] << 31) | (v[ 59] >> 1); v[ 60] = (v[ 61] << 31) | (v[ 60] >> 1); v[ 61] = (v[ 62] << 31) | (v[ 61] >> 1); v[ 62] = (v[ 63] << 31) | (v[ 62] >> 1); v[ 63] = (v[ 64] << 31) | (v[ 63] >> 1); v[ 64] = (v[ 64] >> 1); } else { // s = u ^ m u32 s[64]; // for (u32 i = 0; i < 64; i++) s[i] = u[i] ^ m[i]; s[ 0] = u[ 0] ^ m[ 0]; s[ 1] = u[ 1] ^ m[ 1]; s[ 2] = u[ 2] ^ m[ 2]; s[ 3] = u[ 3] ^ m[ 3]; s[ 4] = u[ 4] ^ m[ 4]; s[ 5] = u[ 5] ^ m[ 5]; s[ 6] = u[ 6] ^ m[ 6]; s[ 7] = u[ 7] ^ m[ 7]; s[ 8] = u[ 8] ^ m[ 8]; s[ 9] = u[ 9] ^ m[ 9]; s[10] = u[10] ^ m[10]; s[11] = u[11] ^ m[11]; s[12] = u[12] ^ m[12]; s[13] = u[13] ^ m[13]; s[14] = u[14] ^ m[14]; s[15] = u[15] ^ m[15]; s[16] = u[16] ^ m[16]; s[17] = u[17] ^ m[17]; s[18] = u[18] ^ m[18]; s[19] = u[19] ^ m[19]; s[20] = u[20] ^ m[20]; s[21] = u[21] ^ m[21]; s[22] = u[22] ^ m[22]; s[23] = u[23] ^ m[23]; s[24] = u[24] ^ m[24]; s[25] = u[25] ^ m[25]; s[26] = u[26] ^ m[26]; s[27] = u[27] ^ m[27]; s[28] = u[28] ^ m[28]; s[29] = u[29] ^ m[29]; s[30] = u[30] ^ m[30]; s[31] = u[31] ^ m[31]; s[32] = u[32] ^ m[32]; s[33] = u[33] ^ m[33]; s[34] = u[34] ^ m[34]; s[35] = u[35] ^ m[35]; s[36] = u[36] ^ m[36]; s[37] = u[37] ^ m[37]; s[38] = u[38] ^ m[38]; s[39] = u[39] ^ m[39]; s[40] = u[40] ^ m[40]; s[41] = u[41] ^ m[41]; s[42] = u[42] ^ m[42]; s[43] = u[43] ^ m[43]; s[44] = u[44] ^ m[44]; s[45] = u[45] ^ m[45]; s[46] = u[46] ^ m[46]; s[47] = u[47] ^ m[47]; s[48] = u[48] ^ m[48]; s[49] = u[49] ^ m[49]; s[50] = u[50] ^ m[50]; s[51] = u[51] ^ m[51]; s[52] = u[52] ^ m[52]; s[53] = u[53] ^ m[53]; s[54] = u[54] ^ m[54]; s[55] = u[55] ^ m[55]; s[56] = u[56] ^ m[56]; s[57] = u[57] ^ m[57]; s[58] = u[58] ^ m[58]; s[59] = u[59] ^ m[59]; s[60] = u[60] ^ m[60]; s[61] = u[61] ^ m[61]; s[62] = u[62] ^ m[62]; s[63] = u[63] ^ m[63]; // s >>= 1 // for (u32 i = 0; i < 63; i++) s[i] = (s[i + 1] << 31) | (s[i] >> 1); // s[63] >>= 1; s[ 0] = (s[ 1] << 31) | (s[ 0] >> 1); s[ 1] = (s[ 2] << 31) | (s[ 1] >> 1); s[ 2] = (s[ 3] << 31) | (s[ 2] >> 1); s[ 3] = (s[ 4] << 31) | (s[ 3] >> 1); s[ 4] = (s[ 5] << 31) | (s[ 4] >> 1); s[ 5] = (s[ 6] << 31) | (s[ 5] >> 1); s[ 6] = (s[ 7] << 31) | (s[ 6] >> 1); s[ 7] = (s[ 8] << 31) | (s[ 7] >> 1); s[ 8] = (s[ 9] << 31) | (s[ 8] >> 1); s[ 9] = (s[ 10] << 31) | (s[ 9] >> 1); s[ 10] = (s[ 11] << 31) | (s[ 10] >> 1); s[ 11] = (s[ 12] << 31) | (s[ 11] >> 1); s[ 12] = (s[ 13] << 31) | (s[ 12] >> 1); s[ 13] = (s[ 14] << 31) | (s[ 13] >> 1); s[ 14] = (s[ 15] << 31) | (s[ 14] >> 1); s[ 15] = (s[ 16] << 31) | (s[ 15] >> 1); s[ 16] = (s[ 17] << 31) | (s[ 16] >> 1); s[ 17] = (s[ 18] << 31) | (s[ 17] >> 1); s[ 18] = (s[ 19] << 31) | (s[ 18] >> 1); s[ 19] = (s[ 20] << 31) | (s[ 19] >> 1); s[ 20] = (s[ 21] << 31) | (s[ 20] >> 1); s[ 21] = (s[ 22] << 31) | (s[ 21] >> 1); s[ 22] = (s[ 23] << 31) | (s[ 22] >> 1); s[ 23] = (s[ 24] << 31) | (s[ 23] >> 1); s[ 24] = (s[ 25] << 31) | (s[ 24] >> 1); s[ 25] = (s[ 26] << 31) | (s[ 25] >> 1); s[ 26] = (s[ 27] << 31) | (s[ 26] >> 1); s[ 27] = (s[ 28] << 31) | (s[ 27] >> 1); s[ 28] = (s[ 29] << 31) | (s[ 28] >> 1); s[ 29] = (s[ 30] << 31) | (s[ 29] >> 1); s[ 30] = (s[ 31] << 31) | (s[ 30] >> 1); s[ 31] = (s[ 32] << 31) | (s[ 31] >> 1); s[ 32] = (s[ 33] << 31) | (s[ 32] >> 1); s[ 33] = (s[ 34] << 31) | (s[ 33] >> 1); s[ 34] = (s[ 35] << 31) | (s[ 34] >> 1); s[ 35] = (s[ 36] << 31) | (s[ 35] >> 1); s[ 36] = (s[ 37] << 31) | (s[ 36] >> 1); s[ 37] = (s[ 38] << 31) | (s[ 37] >> 1); s[ 38] = (s[ 39] << 31) | (s[ 38] >> 1); s[ 39] = (s[ 40] << 31) | (s[ 39] >> 1); s[ 40] = (s[ 41] << 31) | (s[ 40] >> 1); s[ 41] = (s[ 42] << 31) | (s[ 41] >> 1); s[ 42] = (s[ 43] << 31) | (s[ 42] >> 1); s[ 43] = (s[ 44] << 31) | (s[ 43] >> 1); s[ 44] = (s[ 45] << 31) | (s[ 44] >> 1); s[ 45] = (s[ 46] << 31) | (s[ 45] >> 1); s[ 46] = (s[ 47] << 31) | (s[ 46] >> 1); s[ 47] = (s[ 48] << 31) | (s[ 47] >> 1); s[ 48] = (s[ 49] << 31) | (s[ 48] >> 1); s[ 49] = (s[ 50] << 31) | (s[ 49] >> 1); s[ 50] = (s[ 51] << 31) | (s[ 50] >> 1); s[ 51] = (s[ 52] << 31) | (s[ 51] >> 1); s[ 52] = (s[ 53] << 31) | (s[ 52] >> 1); s[ 53] = (s[ 54] << 31) | (s[ 53] >> 1); s[ 54] = (s[ 55] << 31) | (s[ 54] >> 1); s[ 55] = (s[ 56] << 31) | (s[ 55] >> 1); s[ 56] = (s[ 57] << 31) | (s[ 56] >> 1); s[ 57] = (s[ 58] << 31) | (s[ 57] >> 1); s[ 58] = (s[ 59] << 31) | (s[ 58] >> 1); s[ 59] = (s[ 60] << 31) | (s[ 59] >> 1); s[ 60] = (s[ 61] << 31) | (s[ 60] >> 1); s[ 61] = (s[ 62] << 31) | (s[ 61] >> 1); s[ 62] = (s[ 63] << 31) | (s[ 62] >> 1); s[ 63] = (s[ 63] >> 1); // u &= m // for (u32 i = 0; i < 64; i++) u[i] &= m[i]; u[ 0] &= m[ 0]; u[ 1] &= m[ 1]; u[ 2] &= m[ 2]; u[ 3] &= m[ 3]; u[ 4] &= m[ 4]; u[ 5] &= m[ 5]; u[ 6] &= m[ 6]; u[ 7] &= m[ 7]; u[ 8] &= m[ 8]; u[ 9] &= m[ 9]; u[10] &= m[10]; u[11] &= m[11]; u[12] &= m[12]; u[13] &= m[13]; u[14] &= m[14]; u[15] &= m[15]; u[16] &= m[16]; u[17] &= m[17]; u[18] &= m[18]; u[19] &= m[19]; u[20] &= m[20]; u[21] &= m[21]; u[22] &= m[22]; u[23] &= m[23]; u[24] &= m[24]; u[25] &= m[25]; u[26] &= m[26]; u[27] &= m[27]; u[28] &= m[28]; u[29] &= m[29]; u[30] &= m[30]; u[31] &= m[31]; u[32] &= m[32]; u[33] &= m[33]; u[34] &= m[34]; u[35] &= m[35]; u[36] &= m[36]; u[37] &= m[37]; u[38] &= m[38]; u[39] &= m[39]; u[40] &= m[40]; u[41] &= m[41]; u[42] &= m[42]; u[43] &= m[43]; u[44] &= m[44]; u[45] &= m[45]; u[46] &= m[46]; u[47] &= m[47]; u[48] &= m[48]; u[49] &= m[49]; u[50] &= m[50]; u[51] &= m[51]; u[52] &= m[52]; u[53] &= m[53]; u[54] &= m[54]; u[55] &= m[55]; u[56] &= m[56]; u[57] &= m[57]; u[58] &= m[58]; u[59] &= m[59]; u[60] &= m[60]; u[61] &= m[61]; u[62] &= m[62]; u[63] &= m[63]; // t = u (to have the original u) u32 t[64]; // 65 would be needed for "r" (but we know "r" in advance) // for (u32 i = 0; i < 64; i++) t[i] = u[i]; t[ 0] = u[ 0]; t[ 1] = u[ 1]; t[ 2] = u[ 2]; t[ 3] = u[ 3]; t[ 4] = u[ 4]; t[ 5] = u[ 5]; t[ 6] = u[ 6]; t[ 7] = u[ 7]; t[ 8] = u[ 8]; t[ 9] = u[ 9]; t[10] = u[10]; t[11] = u[11]; t[12] = u[12]; t[13] = u[13]; t[14] = u[14]; t[15] = u[15]; t[16] = u[16]; t[17] = u[17]; t[18] = u[18]; t[19] = u[19]; t[20] = u[20]; t[21] = u[21]; t[22] = u[22]; t[23] = u[23]; t[24] = u[24]; t[25] = u[25]; t[26] = u[26]; t[27] = u[27]; t[28] = u[28]; t[29] = u[29]; t[30] = u[30]; t[31] = u[31]; t[32] = u[32]; t[33] = u[33]; t[34] = u[34]; t[35] = u[35]; t[36] = u[36]; t[37] = u[37]; t[38] = u[38]; t[39] = u[39]; t[40] = u[40]; t[41] = u[41]; t[42] = u[42]; t[43] = u[43]; t[44] = u[44]; t[45] = u[45]; t[46] = u[46]; t[47] = u[47]; t[48] = u[48]; t[49] = u[49]; t[50] = u[50]; t[51] = u[51]; t[52] = u[52]; t[53] = u[53]; t[54] = u[54]; t[55] = u[55]; t[56] = u[56]; t[57] = u[57]; t[58] = u[58]; t[59] = u[59]; t[60] = u[60]; t[61] = u[61]; t[62] = u[62]; t[63] = u[63]; // u += s // for (u32 i = 0; i < 64; i++) u[i] += s[i]; u[ 0] += s[ 0]; u[ 1] += s[ 1]; u[ 2] += s[ 2]; u[ 3] += s[ 3]; u[ 4] += s[ 4]; u[ 5] += s[ 5]; u[ 6] += s[ 6]; u[ 7] += s[ 7]; u[ 8] += s[ 8]; u[ 9] += s[ 9]; u[10] += s[10]; u[11] += s[11]; u[12] += s[12]; u[13] += s[13]; u[14] += s[14]; u[15] += s[15]; u[16] += s[16]; u[17] += s[17]; u[18] += s[18]; u[19] += s[19]; u[20] += s[20]; u[21] += s[21]; u[22] += s[22]; u[23] += s[23]; u[24] += s[24]; u[25] += s[25]; u[26] += s[26]; u[27] += s[27]; u[28] += s[28]; u[29] += s[29]; u[30] += s[30]; u[31] += s[31]; u[32] += s[32]; u[33] += s[33]; u[34] += s[34]; u[35] += s[35]; u[36] += s[36]; u[37] += s[37]; u[38] += s[38]; u[39] += s[39]; u[40] += s[40]; u[41] += s[41]; u[42] += s[42]; u[43] += s[43]; u[44] += s[44]; u[45] += s[45]; u[46] += s[46]; u[47] += s[47]; u[48] += s[48]; u[49] += s[49]; u[50] += s[50]; u[51] += s[51]; u[52] += s[52]; u[53] += s[53]; u[54] += s[54]; u[55] += s[55]; u[56] += s[56]; u[57] += s[57]; u[58] += s[58]; u[59] += s[59]; u[60] += s[60]; u[61] += s[61]; u[62] += s[62]; u[63] += s[63]; // take care of the carry for the addition above (i.e check for "overflows") // for (u32 i = 0; i < 63; i++) if (u[i] < t[i]) u[i + 1]++; // if (u[ 0] < t[ 0]) u[ 1]++; // if (u[ 1] < t[ 1]) u[ 2]++; // if (u[ 2] < t[ 2]) u[ 3]++; // if (u[ 3] < t[ 3]) u[ 4]++; // if (u[ 4] < t[ 4]) u[ 5]++; // if (u[ 5] < t[ 5]) u[ 6]++; // if (u[ 6] < t[ 6]) u[ 7]++; // if (u[ 7] < t[ 7]) u[ 8]++; // if (u[ 8] < t[ 8]) u[ 9]++; // if (u[ 9] < t[ 9]) u[10]++; // if (u[10] < t[10]) u[11]++; // if (u[11] < t[11]) u[12]++; // if (u[12] < t[12]) u[13]++; // if (u[13] < t[13]) u[14]++; // if (u[14] < t[14]) u[15]++; // if (u[15] < t[15]) u[16]++; // if (u[16] < t[16]) u[17]++; // if (u[17] < t[17]) u[18]++; // if (u[18] < t[18]) u[19]++; // if (u[19] < t[19]) u[20]++; // if (u[20] < t[20]) u[21]++; // if (u[21] < t[21]) u[22]++; // if (u[22] < t[22]) u[23]++; // if (u[23] < t[23]) u[24]++; // if (u[24] < t[24]) u[25]++; // if (u[25] < t[25]) u[26]++; // if (u[26] < t[26]) u[27]++; // if (u[27] < t[27]) u[28]++; // if (u[28] < t[28]) u[29]++; // if (u[29] < t[29]) u[30]++; // if (u[30] < t[30]) u[31]++; // if (u[31] < t[31]) u[32]++; // if (u[32] < t[32]) u[33]++; // if (u[33] < t[33]) u[34]++; // if (u[34] < t[34]) u[35]++; // if (u[35] < t[35]) u[36]++; // if (u[36] < t[36]) u[37]++; // if (u[37] < t[37]) u[38]++; // if (u[38] < t[38]) u[39]++; // if (u[39] < t[39]) u[40]++; // if (u[40] < t[40]) u[41]++; // if (u[41] < t[41]) u[42]++; // if (u[42] < t[42]) u[43]++; // if (u[43] < t[43]) u[44]++; // if (u[44] < t[44]) u[45]++; // if (u[45] < t[45]) u[46]++; // if (u[46] < t[46]) u[47]++; // if (u[47] < t[47]) u[48]++; // if (u[48] < t[48]) u[49]++; // if (u[49] < t[49]) u[50]++; // if (u[50] < t[50]) u[51]++; // if (u[51] < t[51]) u[52]++; // if (u[52] < t[52]) u[53]++; // if (u[53] < t[53]) u[54]++; // if (u[54] < t[54]) u[55]++; // if (u[55] < t[55]) u[56]++; // if (u[56] < t[56]) u[57]++; // if (u[57] < t[57]) u[58]++; // if (u[58] < t[58]) u[59]++; // if (u[59] < t[59]) u[60]++; // if (u[60] < t[60]) u[61]++; // if (u[61] < t[61]) u[62]++; // if (u[62] < t[62]) u[63]++; // for (u32 i = 1; i < 64; i++) u[i] += u[i - 1] < t[i - 1]; u[ 1] += u[ 0] < t[ 0]; u[ 2] += u[ 1] < t[ 1]; u[ 3] += u[ 2] < t[ 2]; u[ 4] += u[ 3] < t[ 3]; u[ 5] += u[ 4] < t[ 4]; u[ 6] += u[ 5] < t[ 5]; u[ 7] += u[ 6] < t[ 6]; u[ 8] += u[ 7] < t[ 7]; u[ 9] += u[ 8] < t[ 8]; u[10] += u[ 9] < t[ 9]; u[11] += u[10] < t[10]; u[12] += u[11] < t[11]; u[13] += u[12] < t[12]; u[14] += u[13] < t[13]; u[15] += u[14] < t[14]; u[16] += u[15] < t[15]; u[17] += u[16] < t[16]; u[18] += u[17] < t[17]; u[19] += u[18] < t[18]; u[20] += u[19] < t[19]; u[21] += u[20] < t[20]; u[22] += u[21] < t[21]; u[23] += u[22] < t[22]; u[24] += u[23] < t[23]; u[25] += u[24] < t[24]; u[26] += u[25] < t[25]; u[27] += u[26] < t[26]; u[28] += u[27] < t[27]; u[29] += u[28] < t[28]; u[30] += u[29] < t[29]; u[31] += u[30] < t[30]; u[32] += u[31] < t[31]; u[33] += u[32] < t[32]; u[34] += u[33] < t[33]; u[35] += u[34] < t[34]; u[36] += u[35] < t[35]; u[37] += u[36] < t[36]; u[38] += u[37] < t[37]; u[39] += u[38] < t[38]; u[40] += u[39] < t[39]; u[41] += u[40] < t[40]; u[42] += u[41] < t[41]; u[43] += u[42] < t[42]; u[44] += u[43] < t[43]; u[45] += u[44] < t[44]; u[46] += u[45] < t[45]; u[47] += u[46] < t[46]; u[48] += u[47] < t[47]; u[49] += u[48] < t[48]; u[50] += u[49] < t[49]; u[51] += u[50] < t[50]; u[52] += u[51] < t[51]; u[53] += u[52] < t[52]; u[54] += u[53] < t[53]; u[55] += u[54] < t[54]; u[56] += u[55] < t[55]; u[57] += u[56] < t[56]; u[58] += u[57] < t[57]; u[59] += u[58] < t[58]; u[60] += u[59] < t[59]; u[61] += u[60] < t[60]; u[62] += u[61] < t[61]; u[63] += u[62] < t[62]; // v >>= 1 // for (u32 i = 0; i < 64; i++) v[i] = (v[i + 1] << 31) | (v[i] >> 1); // v[64] >>= 1; v[ 0] = (v[ 1] << 31) | (v[ 0] >> 1); v[ 1] = (v[ 2] << 31) | (v[ 1] >> 1); v[ 2] = (v[ 3] << 31) | (v[ 2] >> 1); v[ 3] = (v[ 4] << 31) | (v[ 3] >> 1); v[ 4] = (v[ 5] << 31) | (v[ 4] >> 1); v[ 5] = (v[ 6] << 31) | (v[ 5] >> 1); v[ 6] = (v[ 7] << 31) | (v[ 6] >> 1); v[ 7] = (v[ 8] << 31) | (v[ 7] >> 1); v[ 8] = (v[ 9] << 31) | (v[ 8] >> 1); v[ 9] = (v[ 10] << 31) | (v[ 9] >> 1); v[ 10] = (v[ 11] << 31) | (v[ 10] >> 1); v[ 11] = (v[ 12] << 31) | (v[ 11] >> 1); v[ 12] = (v[ 13] << 31) | (v[ 12] >> 1); v[ 13] = (v[ 14] << 31) | (v[ 13] >> 1); v[ 14] = (v[ 15] << 31) | (v[ 14] >> 1); v[ 15] = (v[ 16] << 31) | (v[ 15] >> 1); v[ 16] = (v[ 17] << 31) | (v[ 16] >> 1); v[ 17] = (v[ 18] << 31) | (v[ 17] >> 1); v[ 18] = (v[ 19] << 31) | (v[ 18] >> 1); v[ 19] = (v[ 20] << 31) | (v[ 19] >> 1); v[ 20] = (v[ 21] << 31) | (v[ 20] >> 1); v[ 21] = (v[ 22] << 31) | (v[ 21] >> 1); v[ 22] = (v[ 23] << 31) | (v[ 22] >> 1); v[ 23] = (v[ 24] << 31) | (v[ 23] >> 1); v[ 24] = (v[ 25] << 31) | (v[ 24] >> 1); v[ 25] = (v[ 26] << 31) | (v[ 25] >> 1); v[ 26] = (v[ 27] << 31) | (v[ 26] >> 1); v[ 27] = (v[ 28] << 31) | (v[ 27] >> 1); v[ 28] = (v[ 29] << 31) | (v[ 28] >> 1); v[ 29] = (v[ 30] << 31) | (v[ 29] >> 1); v[ 30] = (v[ 31] << 31) | (v[ 30] >> 1); v[ 31] = (v[ 32] << 31) | (v[ 31] >> 1); v[ 32] = (v[ 33] << 31) | (v[ 32] >> 1); v[ 33] = (v[ 34] << 31) | (v[ 33] >> 1); v[ 34] = (v[ 35] << 31) | (v[ 34] >> 1); v[ 35] = (v[ 36] << 31) | (v[ 35] >> 1); v[ 36] = (v[ 37] << 31) | (v[ 36] >> 1); v[ 37] = (v[ 38] << 31) | (v[ 37] >> 1); v[ 38] = (v[ 39] << 31) | (v[ 38] >> 1); v[ 39] = (v[ 40] << 31) | (v[ 39] >> 1); v[ 40] = (v[ 41] << 31) | (v[ 40] >> 1); v[ 41] = (v[ 42] << 31) | (v[ 41] >> 1); v[ 42] = (v[ 43] << 31) | (v[ 42] >> 1); v[ 43] = (v[ 44] << 31) | (v[ 43] >> 1); v[ 44] = (v[ 45] << 31) | (v[ 44] >> 1); v[ 45] = (v[ 46] << 31) | (v[ 45] >> 1); v[ 46] = (v[ 47] << 31) | (v[ 46] >> 1); v[ 47] = (v[ 48] << 31) | (v[ 47] >> 1); v[ 48] = (v[ 49] << 31) | (v[ 48] >> 1); v[ 49] = (v[ 50] << 31) | (v[ 49] >> 1); v[ 50] = (v[ 51] << 31) | (v[ 50] >> 1); v[ 51] = (v[ 52] << 31) | (v[ 51] >> 1); v[ 52] = (v[ 53] << 31) | (v[ 52] >> 1); v[ 53] = (v[ 54] << 31) | (v[ 53] >> 1); v[ 54] = (v[ 55] << 31) | (v[ 54] >> 1); v[ 55] = (v[ 56] << 31) | (v[ 55] >> 1); v[ 56] = (v[ 57] << 31) | (v[ 56] >> 1); v[ 57] = (v[ 58] << 31) | (v[ 57] >> 1); v[ 58] = (v[ 59] << 31) | (v[ 58] >> 1); v[ 59] = (v[ 60] << 31) | (v[ 59] >> 1); v[ 60] = (v[ 61] << 31) | (v[ 60] >> 1); v[ 61] = (v[ 62] << 31) | (v[ 61] >> 1); v[ 62] = (v[ 63] << 31) | (v[ 62] >> 1); v[ 63] = (v[ 64] << 31) | (v[ 63] >> 1); v[ 64] = (v[ 64] >> 1); // t = v // // t[ 0] = v[ 0]; t[ 1] = v[ 1]; t[ 2] = v[ 2]; t[ 3] = v[ 3]; // t[ 4] = v[ 4]; t[ 5] = v[ 5]; t[ 6] = v[ 6]; t[ 7] = v[ 7]; // t[ 8] = v[ 8]; t[ 9] = v[ 9]; t[10] = v[10]; t[11] = v[11]; // t[12] = v[12]; t[13] = v[13]; t[14] = v[14]; t[15] = v[15]; // t[16] = v[16]; t[17] = v[17]; t[18] = v[18]; t[19] = v[19]; // t[20] = v[20]; t[21] = v[21]; t[22] = v[22]; t[23] = v[23]; // t[24] = v[24]; t[25] = v[25]; t[26] = v[26]; t[27] = v[27]; // t[28] = v[28]; t[29] = v[29]; t[30] = v[30]; t[31] = v[31]; // t[32] = v[32]; t[33] = v[33]; t[34] = v[34]; t[35] = v[35]; // t[36] = v[36]; t[37] = v[37]; t[38] = v[38]; t[39] = v[39]; // t[40] = v[40]; t[41] = v[41]; t[42] = v[42]; t[43] = v[43]; // t[44] = v[44]; t[45] = v[45]; t[46] = v[46]; t[47] = v[47]; // t[48] = v[48]; t[49] = v[49]; t[50] = v[50]; t[51] = v[51]; // t[52] = v[52]; t[53] = v[53]; t[54] = v[54]; t[55] = v[55]; // t[56] = v[56]; t[57] = v[57]; t[58] = v[58]; t[59] = v[59]; // t[60] = v[60]; t[61] = v[61]; t[62] = v[62]; t[63] = v[63]; // t[60] = v[60]; t[61] = v[61]; t[62] = v[62]; t[63] = v[63]; // t[64] = v[64]; // v += r (only r[64] has the value "1") // we can skip the sum with r[x], since most are set to 0 // v[ 0] += r[ 0]; v[ 1] += r[ 1]; v[ 2] += r[ 2]; v[ 3] += r[ 3]; // v[ 4] += r[ 4]; v[ 5] += r[ 5]; v[ 6] += r[ 6]; v[ 7] += r[ 7]; // v[ 8] += r[ 8]; v[ 9] += r[ 9]; v[10] += r[10]; v[11] += r[11]; // v[12] += r[12]; v[13] += r[13]; v[14] += r[14]; v[15] += r[15]; // v[16] += r[16]; v[17] += r[17]; v[18] += r[18]; v[19] += r[19]; // v[20] += r[20]; v[21] += r[21]; v[22] += r[22]; v[23] += r[23]; // v[24] += r[24]; v[25] += r[25]; v[26] += r[26]; v[27] += r[27]; // v[28] += r[28]; v[29] += r[29]; v[30] += r[30]; v[31] += r[31]; // v[32] += r[32]; v[33] += r[33]; v[34] += r[34]; v[35] += r[35]; // v[36] += r[36]; v[37] += r[37]; v[38] += r[38]; v[39] += r[39]; // v[40] += r[40]; v[41] += r[41]; v[42] += r[42]; v[43] += r[43]; // v[44] += r[44]; v[45] += r[45]; v[46] += r[46]; v[47] += r[47]; // v[48] += r[48]; v[49] += r[49]; v[50] += r[50]; v[51] += r[51]; // v[52] += r[52]; v[53] += r[53]; v[54] += r[54]; v[55] += r[55]; // v[56] += r[56]; v[57] += r[57]; v[58] += r[58]; v[59] += r[59]; // v[60] += r[60]; v[61] += r[61]; v[62] += r[62]; v[63] += r[63]; // v[64] += r[64]; v[64] += 1; // hard-coded "r" value (r[64]) // take care of the carry for the addition above (i.e check for "overflows") // for (u32 i = 1; i < 65; i++) v[i] += v[i - 1] < t[i - 1]; // v[ 1] += v[ 0] < t[ 0]; // v[ 2] += v[ 1] < t[ 1]; // v[ 3] += v[ 2] < t[ 2]; // v[ 4] += v[ 3] < t[ 3]; // v[ 5] += v[ 4] < t[ 4]; // v[ 6] += v[ 5] < t[ 5]; // v[ 7] += v[ 6] < t[ 6]; // v[ 8] += v[ 7] < t[ 7]; // v[ 9] += v[ 8] < t[ 8]; // v[10] += v[ 9] < t[ 9]; // v[11] += v[10] < t[10]; // v[12] += v[11] < t[11]; // v[13] += v[12] < t[12]; // v[14] += v[13] < t[13]; // v[15] += v[14] < t[14]; // v[16] += v[15] < t[15]; // v[17] += v[16] < t[16]; // v[18] += v[17] < t[17]; // v[19] += v[18] < t[18]; // v[20] += v[19] < t[19]; // v[21] += v[20] < t[20]; // v[22] += v[21] < t[21]; // v[23] += v[22] < t[22]; // v[24] += v[23] < t[23]; // v[25] += v[24] < t[24]; // v[26] += v[25] < t[25]; // v[27] += v[26] < t[26]; // v[28] += v[27] < t[27]; // v[29] += v[28] < t[28]; // v[30] += v[29] < t[29]; // v[31] += v[30] < t[30]; // v[32] += v[31] < t[31]; // v[33] += v[32] < t[32]; // v[34] += v[33] < t[33]; // v[35] += v[34] < t[34]; // v[36] += v[35] < t[35]; // v[37] += v[36] < t[36]; // v[38] += v[37] < t[37]; // v[39] += v[38] < t[38]; // v[40] += v[39] < t[39]; // v[41] += v[40] < t[40]; // v[42] += v[41] < t[41]; // v[43] += v[42] < t[42]; // v[44] += v[43] < t[43]; // v[45] += v[44] < t[44]; // v[46] += v[45] < t[45]; // v[47] += v[46] < t[46]; // v[48] += v[47] < t[47]; // v[49] += v[48] < t[48]; // v[50] += v[49] < t[49]; // v[51] += v[50] < t[50]; // v[52] += v[51] < t[51]; // v[53] += v[52] < t[52]; // v[54] += v[53] < t[53]; // v[55] += v[54] < t[54]; // v[56] += v[55] < t[55]; // v[57] += v[56] < t[56]; // v[58] += v[57] < t[57]; // v[59] += v[58] < t[58]; // v[60] += v[59] < t[59]; // v[61] += v[60] < t[60]; // v[62] += v[61] < t[61]; // v[63] += v[62] < t[62]; // v[64] += v[63] < t[63]; } } // v is fact and we skip v[64] in output ??? v[64] = 0; } // r[ 64], the result, r = (a << bits) % m // a[ 64], the 256 byte number we want to convert // m[128], modulo DECLSPEC void to_montgomery (PRIVATE_AS u32 *r, PRIVATE_AS const u32 *a, PRIVATE_AS const u32 *m) { u32 t[128] = { 0 }; // shift by "bits" bits, i.e. 256 bytes (64 u32) // for (u32 i = 0; i < 64; i++) t[i + 64] = a[i]; t[ 64] = a[ 0]; t[ 65] = a[ 1]; t[ 66] = a[ 2]; t[ 67] = a[ 3]; t[ 68] = a[ 4]; t[ 69] = a[ 5]; t[ 70] = a[ 6]; t[ 71] = a[ 7]; t[ 72] = a[ 8]; t[ 73] = a[ 9]; t[ 74] = a[10]; t[ 75] = a[11]; t[ 76] = a[12]; t[ 77] = a[13]; t[ 78] = a[14]; t[ 79] = a[15]; t[ 80] = a[16]; t[ 81] = a[17]; t[ 82] = a[18]; t[ 83] = a[19]; t[ 84] = a[20]; t[ 85] = a[21]; t[ 86] = a[22]; t[ 87] = a[23]; t[ 88] = a[24]; t[ 89] = a[25]; t[ 90] = a[26]; t[ 91] = a[27]; t[ 92] = a[28]; t[ 93] = a[29]; t[ 94] = a[30]; t[ 95] = a[31]; t[ 96] = a[32]; t[ 97] = a[33]; t[ 98] = a[34]; t[ 99] = a[35]; t[100] = a[36]; t[101] = a[37]; t[102] = a[38]; t[103] = a[39]; t[104] = a[40]; t[105] = a[41]; t[106] = a[42]; t[107] = a[43]; t[108] = a[44]; t[109] = a[45]; t[110] = a[46]; t[111] = a[47]; t[112] = a[48]; t[113] = a[49]; t[114] = a[50]; t[115] = a[51]; t[116] = a[52]; t[117] = a[53]; t[118] = a[54]; t[119] = a[55]; t[120] = a[56]; t[121] = a[57]; t[122] = a[58]; t[123] = a[59]; t[124] = a[60]; t[125] = a[61]; t[126] = a[62]; t[127] = a[63]; mod_4096 (t, m); // for (u32 i = 0; i < 64; i++) r[i] = t[i]; r[ 0] = t[ 0]; r[ 1] = t[ 1]; r[ 2] = t[ 2]; r[ 3] = t[ 3]; r[ 4] = t[ 4]; r[ 5] = t[ 5]; r[ 6] = t[ 6]; r[ 7] = t[ 7]; r[ 8] = t[ 8]; r[ 9] = t[ 9]; r[10] = t[10]; r[11] = t[11]; r[12] = t[12]; r[13] = t[13]; r[14] = t[14]; r[15] = t[15]; r[16] = t[16]; r[17] = t[17]; r[18] = t[18]; r[19] = t[19]; r[20] = t[20]; r[21] = t[21]; r[22] = t[22]; r[23] = t[23]; r[24] = t[24]; r[25] = t[25]; r[26] = t[26]; r[27] = t[27]; r[28] = t[28]; r[29] = t[29]; r[30] = t[30]; r[31] = t[31]; r[32] = t[32]; r[33] = t[33]; r[34] = t[34]; r[35] = t[35]; r[36] = t[36]; r[37] = t[37]; r[38] = t[38]; r[39] = t[39]; r[40] = t[40]; r[41] = t[41]; r[42] = t[42]; r[43] = t[43]; r[44] = t[44]; r[45] = t[45]; r[46] = t[46]; r[47] = t[47]; r[48] = t[48]; r[49] = t[49]; r[50] = t[50]; r[51] = t[51]; r[52] = t[52]; r[53] = t[53]; r[54] = t[54]; r[55] = t[55]; r[56] = t[56]; r[57] = t[57]; r[58] = t[58]; r[59] = t[59]; r[60] = t[60]; r[61] = t[61]; r[62] = t[62]; r[63] = t[63]; } // r [ 64], result, r = a * (rinv * 2) % m // a [ 64], the 256 byte number we want to convert back // m [128], modulo // rinv[ 64], r', our euclidean inverse r DECLSPEC void from_montgomery (PRIVATE_AS u32 *r, PRIVATE_AS const u32* a, PRIVATE_AS const u32 *m, PRIVATE_AS const u32 *rinv) { // (a * (rinv * 2)) % m = (a * rinv2) % m // rinv2 = 2 * rinv (or rinv << 1) u32 rinv2[128] = { 0 }; // rinv2[64] = rinv[63] >> 31; // for (int i = 63; i > 0; i--) rinv2[i] = (rinv[i - 1] >> 31) | (rinv[i] << 1); // rinv2[0] = rinv[0] << 1; rinv2[64] = (rinv[63] >> 31); rinv2[63] = (rinv[62] >> 31) | (rinv[63] << 1); rinv2[62] = (rinv[61] >> 31) | (rinv[62] << 1); rinv2[61] = (rinv[60] >> 31) | (rinv[61] << 1); rinv2[60] = (rinv[59] >> 31) | (rinv[60] << 1); rinv2[59] = (rinv[58] >> 31) | (rinv[59] << 1); rinv2[58] = (rinv[57] >> 31) | (rinv[58] << 1); rinv2[57] = (rinv[56] >> 31) | (rinv[57] << 1); rinv2[56] = (rinv[55] >> 31) | (rinv[56] << 1); rinv2[55] = (rinv[54] >> 31) | (rinv[55] << 1); rinv2[54] = (rinv[53] >> 31) | (rinv[54] << 1); rinv2[53] = (rinv[52] >> 31) | (rinv[53] << 1); rinv2[52] = (rinv[51] >> 31) | (rinv[52] << 1); rinv2[51] = (rinv[50] >> 31) | (rinv[51] << 1); rinv2[50] = (rinv[49] >> 31) | (rinv[50] << 1); rinv2[49] = (rinv[48] >> 31) | (rinv[49] << 1); rinv2[48] = (rinv[47] >> 31) | (rinv[48] << 1); rinv2[47] = (rinv[46] >> 31) | (rinv[47] << 1); rinv2[46] = (rinv[45] >> 31) | (rinv[46] << 1); rinv2[45] = (rinv[44] >> 31) | (rinv[45] << 1); rinv2[44] = (rinv[43] >> 31) | (rinv[44] << 1); rinv2[43] = (rinv[42] >> 31) | (rinv[43] << 1); rinv2[42] = (rinv[41] >> 31) | (rinv[42] << 1); rinv2[41] = (rinv[40] >> 31) | (rinv[41] << 1); rinv2[40] = (rinv[39] >> 31) | (rinv[40] << 1); rinv2[39] = (rinv[38] >> 31) | (rinv[39] << 1); rinv2[38] = (rinv[37] >> 31) | (rinv[38] << 1); rinv2[37] = (rinv[36] >> 31) | (rinv[37] << 1); rinv2[36] = (rinv[35] >> 31) | (rinv[36] << 1); rinv2[35] = (rinv[34] >> 31) | (rinv[35] << 1); rinv2[34] = (rinv[33] >> 31) | (rinv[34] << 1); rinv2[33] = (rinv[32] >> 31) | (rinv[33] << 1); rinv2[32] = (rinv[31] >> 31) | (rinv[32] << 1); rinv2[31] = (rinv[30] >> 31) | (rinv[31] << 1); rinv2[30] = (rinv[29] >> 31) | (rinv[30] << 1); rinv2[29] = (rinv[28] >> 31) | (rinv[29] << 1); rinv2[28] = (rinv[27] >> 31) | (rinv[28] << 1); rinv2[27] = (rinv[26] >> 31) | (rinv[27] << 1); rinv2[26] = (rinv[25] >> 31) | (rinv[26] << 1); rinv2[25] = (rinv[24] >> 31) | (rinv[25] << 1); rinv2[24] = (rinv[23] >> 31) | (rinv[24] << 1); rinv2[23] = (rinv[22] >> 31) | (rinv[23] << 1); rinv2[22] = (rinv[21] >> 31) | (rinv[22] << 1); rinv2[21] = (rinv[20] >> 31) | (rinv[21] << 1); rinv2[20] = (rinv[19] >> 31) | (rinv[20] << 1); rinv2[19] = (rinv[18] >> 31) | (rinv[19] << 1); rinv2[18] = (rinv[17] >> 31) | (rinv[18] << 1); rinv2[17] = (rinv[16] >> 31) | (rinv[17] << 1); rinv2[16] = (rinv[15] >> 31) | (rinv[16] << 1); rinv2[15] = (rinv[14] >> 31) | (rinv[15] << 1); rinv2[14] = (rinv[13] >> 31) | (rinv[14] << 1); rinv2[13] = (rinv[12] >> 31) | (rinv[13] << 1); rinv2[12] = (rinv[11] >> 31) | (rinv[12] << 1); rinv2[11] = (rinv[10] >> 31) | (rinv[11] << 1); rinv2[10] = (rinv[ 9] >> 31) | (rinv[10] << 1); rinv2[ 9] = (rinv[ 8] >> 31) | (rinv[ 9] << 1); rinv2[ 8] = (rinv[ 7] >> 31) | (rinv[ 8] << 1); rinv2[ 7] = (rinv[ 6] >> 31) | (rinv[ 7] << 1); rinv2[ 6] = (rinv[ 5] >> 31) | (rinv[ 6] << 1); rinv2[ 5] = (rinv[ 4] >> 31) | (rinv[ 5] << 1); rinv2[ 4] = (rinv[ 3] >> 31) | (rinv[ 4] << 1); rinv2[ 3] = (rinv[ 2] >> 31) | (rinv[ 3] << 1); rinv2[ 2] = (rinv[ 1] >> 31) | (rinv[ 2] << 1); rinv2[ 1] = (rinv[ 0] >> 31) | (rinv[ 1] << 1); rinv2[ 0] = (rinv[ 0] << 1); mod_4096 (rinv2, m); // t = a * rinv2 u32 t[128] = { 0 }; mul (t, a, rinv2); // t %= m mod_4096 (t, m); // for (u32 i = 0; i < 64; i++) r[i] = t[i]; r[ 0] = t[ 0]; r[ 1] = t[ 1]; r[ 2] = t[ 2]; r[ 3] = t[ 3]; r[ 4] = t[ 4]; r[ 5] = t[ 5]; r[ 6] = t[ 6]; r[ 7] = t[ 7]; r[ 8] = t[ 8]; r[ 9] = t[ 9]; r[10] = t[10]; r[11] = t[11]; r[12] = t[12]; r[13] = t[13]; r[14] = t[14]; r[15] = t[15]; r[16] = t[16]; r[17] = t[17]; r[18] = t[18]; r[19] = t[19]; r[20] = t[20]; r[21] = t[21]; r[22] = t[22]; r[23] = t[23]; r[24] = t[24]; r[25] = t[25]; r[26] = t[26]; r[27] = t[27]; r[28] = t[28]; r[29] = t[29]; r[30] = t[30]; r[31] = t[31]; r[32] = t[32]; r[33] = t[33]; r[34] = t[34]; r[35] = t[35]; r[36] = t[36]; r[37] = t[37]; r[38] = t[38]; r[39] = t[39]; r[40] = t[40]; r[41] = t[41]; r[42] = t[42]; r[43] = t[43]; r[44] = t[44]; r[45] = t[45]; r[46] = t[46]; r[47] = t[47]; r[48] = t[48]; r[49] = t[49]; r[50] = t[50]; r[51] = t[51]; r[52] = t[52]; r[53] = t[53]; r[54] = t[54]; r[55] = t[55]; r[56] = t[56]; r[57] = t[57]; r[58] = t[58]; r[59] = t[59]; r[60] = t[60]; r[61] = t[61]; r[62] = t[62]; r[63] = t[63]; }