57 const size_t num_precompute_rows = num_rows_per_scalar * ecc_muls.size() + 1;
67 for (size_t j = start; j < end; j++) {
68 const auto& entry = ecc_muls[j];
69 const auto& slices = entry.wnaf_digits;
70 uint256_t scalar_sum = 0;
72 for (size_t i = 0; i < num_rows_per_scalar; ++i) {
73 PointTablePrecomputationRow row;
74 const int slice0 = slices[i * WNAF_DIGITS_PER_ROW];
75 const int slice1 = slices[i * WNAF_DIGITS_PER_ROW + 1];
76 const int slice2 = slices[i * WNAF_DIGITS_PER_ROW + 2];
77 const int slice3 = slices[i * WNAF_DIGITS_PER_ROW + 3];
80 const int slice0base2 = (slice0 + 15) / 2;
81 const int slice1base2 = (slice1 + 15) / 2;
82 const int slice2base2 = (slice2 + 15) / 2;
83 const int slice3base2 = (slice3 + 15) / 2;
86 row.s1 = slice0base2 >> 2;
87 row.s2 = slice0base2 & 3;
88 row.s3 = slice1base2 >> 2;
89 row.s4 = slice1base2 & 3;
90 row.s5 = slice2base2 >> 2;
91 row.s6 = slice2base2 & 3;
92 row.s7 = slice3base2 >> 2;
93 row.s8 = slice3base2 & 3;
94 bool last_row = (i == num_rows_per_scalar - 1);
96 row.skew = last_row ? entry.wnaf_skew : false;
98 row.scalar_sum = scalar_sum;
102 const int row_chunk = slice3 + slice2 * (1 << 4) + slice1 * (1 << 8) + slice0 * (1 << 12);
104 bool chunk_negative = row_chunk < 0;
106 scalar_sum = scalar_sum << (NUM_WNAF_DIGIT_BITS * WNAF_DIGITS_PER_ROW);
107 if (chunk_negative) {
108 scalar_sum -= static_cast<uint64_t>(-row_chunk);
110 scalar_sum += static_cast<uint64_t>(row_chunk);
112 row.round = static_cast<uint32_t>(i);
113 row.point_transition = last_row;
117 ASSERT(scalar_sum - entry.wnaf_skew, entry.scalar);
120 row.precompute_double = entry.precomputed_table[bb::eccvm::POINT_TABLE_SIZE];
125 row.precompute_accumulator = entry.precomputed_table[bb::eccvm::POINT_TABLE_SIZE - 1 - i];
126 precompute_state[j * num_rows_per_scalar + i + 1] = (row);
130 return precompute_state;