Skip to content

Commit 4d2f63f

Browse files
Jack L Crawfordfaberga
authored andcommitted
*= operator for Ctxt for constant multiplication (#259)
1 parent e9f84fa commit 4d2f63f

File tree

5 files changed

+140
-4
lines changed

5 files changed

+140
-4
lines changed

include/helib/Ctxt.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) 2012-2019 IBM Corp.
1+
/* Copyright (C) 2012-2020 IBM Corp.
22
* This program is Licensed under the Apache License, Version 2.0
33
* (the "License"); you may not use this file except in compliance
44
* with the License. You may obtain a copy of the License at
@@ -357,7 +357,7 @@ class Ctxt {
357357
///@{
358358
void negate();
359359

360-
// Add/subtract aonther ciphertext
360+
// Add/subtract another ciphertext
361361
Ctxt& operator+=(const Ctxt& other) { addCtxt(other); return *this; }
362362
Ctxt& operator-=(const Ctxt& other) { addCtxt(other,true); return *this; }
363363
void addCtxt(const Ctxt& other, bool negative=false);
@@ -424,6 +424,20 @@ class Ctxt {
424424
**/
425425
Ctxt& operator*=(const helib::Ptxt<helib::CKKS>& other);
426426

427+
/**
428+
* @brief Times equals operator with a `ZZX`.
429+
* @param poly Element by which to multiply.
430+
* @return Reference to `*this` post multiplication.
431+
**/
432+
Ctxt& operator*=(const NTL::ZZX& poly);
433+
434+
/**
435+
* @brief Times equals oeprator with a `long`.
436+
* @param scalar Constant by which to multiply.
437+
* @return Reference to `*this` post multiplication.
438+
**/
439+
Ctxt& operator*=(const long scalar);
440+
427441
//! Add a constant polynomial.
428442
//! If provided, size should be a high-probability bound
429443
//! on the L-infty norm of the canonical embedding

include/helib/Ptxt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) 2019 IBM Corp.
1+
/* Copyright (C) 2019-2020 IBM Corp.
22
* This program is Licensed under the Apache License, Version 2.0
33
* (the "License"); you may not use this file except in compliance
44
* with the License. You may obtain a copy of the License at

src/Ctxt.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) 2012-2019 IBM Corp.
1+
/* Copyright (C) 2012-2020 IBM Corp.
22
* This program is Licensed under the Apache License, Version 2.0
33
* (the "License"); you may not use this file except in compliance
44
* with the License. You may obtain a copy of the License at
@@ -863,6 +863,20 @@ Ctxt& Ctxt::operator*=(const helib::Ptxt<helib::CKKS>& other)
863863
return *this;
864864
}
865865

866+
Ctxt& Ctxt::operator*=(const NTL::ZZX& poly)
867+
{
868+
if(isCKKS())
869+
multByConstantCKKS(poly);
870+
else
871+
multByConstant(poly);
872+
return *this;
873+
}
874+
875+
Ctxt& Ctxt::operator*=(const long scalar)
876+
{
877+
return *this *= NTL::ZZX(scalar);
878+
}
879+
866880
void Ctxt::addConstantCKKS(const std::vector<std::complex<double>>& other)
867881
{
868882
NTL::ZZX poly;

tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(GTEST_SRC
77
"TestArgMap.cpp"
88
"TestBootstrappingWithMultiplications.cpp"
99
"TestContext.cpp"
10+
"TestCtxt.cpp"
1011
"TestPolyMod.cpp"
1112
"TestPtxt.cpp"
1213
"TestPolyModRing.cpp")
@@ -72,6 +73,7 @@ set(TEST_NAMES
7273
"TestArgMap"
7374
"TestCKKS"
7475
"TestContext"
76+
"TestCtxt"
7577
"TestErrorHandling"
7678
"TestFatBootstrappingWithMultiplications"
7779
"TestThinBootstrappingWithMultiplications"

tests/TestCtxt.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* Copyright (C) 2020 IBM Corp.
2+
* This program is Licensed under the Apache License, Version 2.0
3+
* (the "License"); you may not use this file except in compliance
4+
* with the License. You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License. See accompanying LICENSE file.
11+
*/
12+
13+
// This test file does not fully cover Ctxt, and is intended as a starting
14+
// point for testing new functionality of Ctxt going forward.
15+
// The older tests with more extensive coverage can be found in the files
16+
// with names matching "GTest*".
17+
18+
#include <helib/helib.h>
19+
20+
#include "test_common.h"
21+
#include "gtest/gtest.h"
22+
23+
namespace {
24+
25+
struct BGVParameters
26+
{
27+
BGVParameters(unsigned m, unsigned p, unsigned r, unsigned bits) :
28+
m(m),
29+
p(p),
30+
r(r),
31+
bits(bits){};
32+
33+
const unsigned m;
34+
const unsigned p;
35+
const unsigned r;
36+
const unsigned bits;
37+
38+
friend std::ostream& operator<<(std::ostream& os, const BGVParameters& params)
39+
{
40+
return os << "{"
41+
<< "m = " << params.m << ", "
42+
<< "p = " << params.p << ", "
43+
<< "r = " << params.r << ", "
44+
<< "bits = " << params.bits << "}";
45+
}
46+
};
47+
48+
class TestCtxt : public ::testing::TestWithParam<BGVParameters>
49+
{
50+
protected:
51+
const unsigned long m;
52+
const unsigned long p;
53+
const unsigned long r;
54+
const unsigned long bits;
55+
helib::Context context;
56+
helib::SecKey secretKey;
57+
helib::PubKey publicKey;
58+
const helib::EncryptedArray& ea;
59+
60+
TestCtxt() :
61+
m(GetParam().m),
62+
p(GetParam().p),
63+
r(GetParam().r),
64+
bits(GetParam().bits),
65+
context(m, p, r),
66+
secretKey((buildModChain(context, bits), context)),
67+
publicKey((secretKey.GenSecKey(), secretKey)),
68+
ea(*(context.ea))
69+
{}
70+
};
71+
72+
TEST_P(TestCtxt, timesEqualsWithLongWorks)
73+
{
74+
helib::Ptxt<helib::BGV> ptxt(context, std::vector<long>(ea.size(), 5));
75+
helib::Ctxt ctxt(publicKey);
76+
publicKey.Encrypt(ctxt, ptxt);
77+
ctxt *= 2l;
78+
79+
helib::Ptxt<helib::BGV> expected_result(context,
80+
std::vector<long>(ea.size(), 10));
81+
helib::Ptxt<helib::BGV> decrypted_result(context);
82+
secretKey.Decrypt(decrypted_result, ctxt);
83+
84+
EXPECT_EQ(decrypted_result, expected_result);
85+
}
86+
87+
TEST_P(TestCtxt, timesEqualsWithZZXWorks)
88+
{
89+
helib::Ptxt<helib::BGV> ptxt(context, std::vector<long>(ea.size(), 5));
90+
helib::Ctxt ctxt(publicKey);
91+
publicKey.Encrypt(ctxt, ptxt);
92+
ctxt *= NTL::ZZX(2l);
93+
94+
helib::Ptxt<helib::BGV> expected_result(context,
95+
std::vector<long>(ea.size(), 10));
96+
helib::Ptxt<helib::BGV> decrypted_result(context);
97+
secretKey.Decrypt(decrypted_result, ctxt);
98+
99+
EXPECT_EQ(decrypted_result, expected_result);
100+
}
101+
102+
INSTANTIATE_TEST_SUITE_P(variousParameters,
103+
TestCtxt,
104+
::testing::Values(BGVParameters(17, 2, 1, 100)));
105+
106+
} // namespace

0 commit comments

Comments
 (0)