Skip to content

Commit d894a96

Browse files
A plus bc mod q redo (#274)
* Update how a_plus_bc_mod_q is calling the big number package. Use 256 bit routines rather than 4096 routines. * Add benchmark test for a_plus_bc_mod_q * Use the abstraction layer. * Should have been using the constant. Co-authored-by: Jeff <[email protected]>
1 parent 84f21f7 commit d894a96

File tree

2 files changed

+34
-24
lines changed

2 files changed

+34
-24
lines changed

src/electionguard/group.cpp

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -755,38 +755,31 @@ namespace electionguard
755755
unique_ptr<ElementModQ> a_plus_bc_mod_q(const ElementModQ &a, const ElementModQ &b,
756756
const ElementModQ &c)
757757
{
758-
// since the result of b*c can be larger than Q's 256,
759-
// use P's length and 4096 Hacl for rest of calculation
760-
761-
uint64_t resultBC[MAX_P_LEN] = {}; // init to MAX_P_LEN
758+
// multiply b * c and the result will be twice Q in size
759+
uint64_t bc[MAX_Q_LEN_DOUBLE] = {};
762760
Bignum256::mul(const_cast<ElementModQ &>(b).get(), const_cast<ElementModQ &>(c).get(),
763-
static_cast<uint64_t *>(resultBC));
764-
765-
auto bc_as_p = make_unique<ElementModP>(resultBC, true);
766-
auto a_as_p = a.toElementModP();
767-
768-
uint64_t a_plus_bc_result[MAX_P_LEN_DOUBLE] = {};
769-
uint64_t carry =
770-
Bignum4096::add(a_as_p->get(), bc_as_p->get(), static_cast<uint64_t *>(a_plus_bc_result));
761+
bc);
771762

772-
// we should never overflow P space since our max size
773-
// is resultBC[MAX_Q_LEN_DOUBLE] + a[MAX_Q_LEN]
774-
if (carry > 0) {
775-
throw overflow_error("a_plus_bc_mod_q add operation out of bounds");
763+
// perform the mod operation on bc
764+
uint64_t bc_mod_q[MAX_Q_LEN] = {};
765+
const auto &q = Q();
766+
bool modSuccess = Bignum256::mod(q.get(), bc, bc_mod_q);
767+
if (!modSuccess) {
768+
throw runtime_error("a_plus_bc_mod_q mod operation failed");
776769
}
777770

778-
const auto &q = Q();
779-
auto q_as_p = q.toElementModP();
780-
uint64_t resModQ[MAX_P_LEN] = {};
781-
bool modSuccess = Bignum4096::mod(q_as_p->get(), static_cast<uint64_t *>(a_plus_bc_result),
782-
static_cast<uint64_t *>(resModQ));
771+
uint64_t a_plus_bc[MAX_Q_LEN_DOUBLE] = {};
772+
uint64_t carry = Bignum256::add(const_cast<ElementModQ &>(a).get(), bc_mod_q, a_plus_bc);
773+
// put the carry in
774+
a_plus_bc[MAX_Q_LEN] = carry;
775+
776+
uint64_t res[MAX_Q_LEN] = {};
777+
modSuccess = Bignum256::mod(q.get(), a_plus_bc, res);
783778
if (!modSuccess) {
784779
throw runtime_error("a_plus_bc_mod_q mod operation failed");
785780
}
786-
uint64_t result[MAX_Q_LEN] = {};
787-
memcpy(static_cast<uint64_t *>(result), resModQ, MAX_Q_SIZE);
788781

789-
return make_unique<ElementModQ>(result, true);
782+
return make_unique<ElementModQ>(res, true);
790783
}
791784

792785
unique_ptr<ElementModQ> sub_from_q(const ElementModQ &a)

test/electionguard/benchmark/bench_group.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ class GroupElementFixture : public benchmark::Fixture
3333

3434
auto array_size = sizeof(LARGE_P_ARRAY_1) / sizeof(uint64_t);
3535
p1_vector.assign(&LARGE_P_ARRAY_1[0], &LARGE_P_ARRAY_1[array_size]);
36+
37+
a = rand_q();
38+
b = rand_q();
39+
c = rand_q();
40+
3641
}
3742

3843
void TearDown(const ::benchmark::State &state) {}
@@ -43,6 +48,9 @@ class GroupElementFixture : public benchmark::Fixture
4348
unique_ptr<ElementModQ> q1;
4449
unique_ptr<ElementModQ> q2;
4550
vector<uint64_t> p1_vector;
51+
unique_ptr<ElementModQ> a;
52+
unique_ptr<ElementModQ> b;
53+
unique_ptr<ElementModQ> c;
4654
};
4755

4856
BENCHMARK_DEFINE_F(GroupElementFixture, ElementModP_fromArray)(benchmark::State &state)
@@ -216,3 +224,12 @@ BENCHMARK_DEFINE_F(GroupElementFixture, add_mod_q_overflow)(benchmark::State &st
216224
}
217225

218226
BENCHMARK_REGISTER_F(GroupElementFixture, add_mod_q_overflow)->Unit(benchmark::kMillisecond);
227+
228+
BENCHMARK_DEFINE_F(GroupElementFixture, a_plus_bc_mod_q)(benchmark::State &state)
229+
{
230+
for (auto _ : state) {
231+
auto r = a_plus_bc_mod_q(*a, *b, *c);
232+
}
233+
}
234+
235+
BENCHMARK_REGISTER_F(GroupElementFixture, a_plus_bc_mod_q)->Unit(benchmark::kMillisecond);

0 commit comments

Comments
 (0)