|
@@ -33,7 +33,7 @@
|
|
|
|
|
|
|
|
// #define CHECK_RESULTS
|
|
// #define CHECK_RESULTS
|
|
|
|
|
|
|
|
-// #define VERBOSE
|
|
|
|
|
|
|
+ #define VERBOSE
|
|
|
|
|
|
|
|
// #include "cuPrintf.cu"
|
|
// #include "cuPrintf.cu"
|
|
|
|
|
|
|
@@ -475,10 +475,10 @@ void cuda_dl(const ZZ_p &base, const ZZ_p &target, const ZZ &order,
|
|
|
dim3 tpb(threadDimx, threadsPerBlock/threadDimx);
|
|
dim3 tpb(threadDimx, threadsPerBlock/threadDimx);
|
|
|
gettimeofday(&st, NULL);
|
|
gettimeofday(&st, NULL);
|
|
|
int launchcount = 0;
|
|
int launchcount = 0;
|
|
|
|
|
+ bool stop_computing = false;
|
|
|
#ifdef CHECK_RESULTS
|
|
#ifdef CHECK_RESULTS
|
|
|
- for (int ln=0; ln<nlaunch; ++ln)
|
|
|
|
|
|
|
+ for (int ln=0; ln<nlaunch && stop_computing == false; ++ln)
|
|
|
#else
|
|
#else
|
|
|
- bool stop_computing = false;
|
|
|
|
|
while(stop_computing == false)
|
|
while(stop_computing == false)
|
|
|
#endif
|
|
#endif
|
|
|
{
|
|
{
|
|
@@ -523,8 +523,8 @@ cout << i << ": " << l_Z[i] << " != " << l_z[i + t * WORDS] << "\n";
|
|
|
dump("d_z", l_Z, WORDS);
|
|
dump("d_z", l_Z, WORDS);
|
|
|
dump("l_z", l_z + t * WORDS, WORDS);
|
|
dump("l_z", l_z + t * WORDS, WORDS);
|
|
|
}
|
|
}
|
|
|
- ZZ ares = (to_ZZ(l_ts[t].a[1]) << 32) + to_ZZ(l_ts[t].a[0]);
|
|
|
|
|
- ZZ bres = (to_ZZ(l_ts[t].b[1]) << 32) + to_ZZ(l_ts[t].b[0]);
|
|
|
|
|
|
|
+ ZZ ares = (to_ZZ(l_ts[t].a[2]) << 64) + (to_ZZ(l_ts[t].a[1]) << 32) + to_ZZ(l_ts[t].a[0]);
|
|
|
|
|
+ ZZ bres = (to_ZZ(l_ts[t].b[2]) << 64) + (to_ZZ(l_ts[t].b[1]) << 32) + to_ZZ(l_ts[t].b[0]);
|
|
|
if (ares != aexp[t] || bres != bexp[t]) {
|
|
if (ares != aexp[t] || bres != bexp[t]) {
|
|
|
cerr << "ares = " << ares << "\n";
|
|
cerr << "ares = " << ares << "\n";
|
|
|
cerr << "aexp = " << aexp[t] << "\n";
|
|
cerr << "aexp = " << aexp[t] << "\n";
|
|
@@ -558,6 +558,78 @@ cout << i << ": " << l_Z[i] << " != " << l_z[i + t * WORDS] << "\n";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifdef TEST_CUDA
|
|
#ifdef TEST_CUDA
|
|
|
|
|
+
|
|
|
|
|
+string output_prefix("test_cuda");
|
|
|
|
|
+
|
|
|
|
|
+typedef map<std::string, pair<ZZ,ZZ> > DTable;
|
|
|
|
|
+
|
|
|
|
|
+struct CBData {
|
|
|
|
|
+ const ZZ_p &base;
|
|
|
|
|
+ const ZZ_p ⌖
|
|
|
|
|
+ const ZZ ℴ
|
|
|
|
|
+ unsigned long long numdp;
|
|
|
|
|
+ DTable dtable;
|
|
|
|
|
+ bool found_collision;
|
|
|
|
|
+ ZZ expon;
|
|
|
|
|
+
|
|
|
|
|
+ CBData(const ZZ_p &_base, const ZZ_p &_target, const ZZ &_order) :
|
|
|
|
|
+ base(_base), target(_target), order(_order), numdp(0),
|
|
|
|
|
+ found_collision(false) {}
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// This function is called from inside cuda_dl for each DP it encounters.
|
|
|
|
|
+// It calls the function named "dpcallback" directly. It would be
|
|
|
|
|
+// cleaner if this were passed as a function pointer to cuda_dl, but
|
|
|
|
|
+// that makes nvcc 3.1 segfault. :-p
|
|
|
|
|
+// dp points to an array of WORDS+7 unsigned ints:
|
|
|
|
|
+// - 1 word of threadID/blockID
|
|
|
|
|
+// - WORDS words of the dp value
|
|
|
|
|
+// - 3 words of a
|
|
|
|
|
+// - 3 words of b
|
|
|
|
|
+bool dpcallback(void *cbdata, unsigned int *dpwords)
|
|
|
|
|
+{
|
|
|
|
|
+ CBData *d = (CBData*)cbdata;
|
|
|
|
|
+ // WARNING: this assumes
|
|
|
|
|
+ // sizeof(unsigned long) == sizeof(unsigned long long) !
|
|
|
|
|
+ ZZ zz_a = to_ZZ(dpwords[WORDS+3]);
|
|
|
|
|
+ zz_a <<= 32;
|
|
|
|
|
+ zz_a += dpwords[WORDS+2];
|
|
|
|
|
+ zz_a <<= 32;
|
|
|
|
|
+ zz_a += dpwords[WORDS+1];
|
|
|
|
|
+ ZZ zz_b = to_ZZ(dpwords[WORDS+6]);
|
|
|
|
|
+ zz_b <<= 32;
|
|
|
|
|
+ zz_b += dpwords[WORDS+5];
|
|
|
|
|
+ zz_b <<= 32;
|
|
|
|
|
+ zz_b += dpwords[WORDS+4];
|
|
|
|
|
+
|
|
|
|
|
+ // ZZ_p dp = power(d->base, zz_a) * power(d->target, zz_b);
|
|
|
|
|
+ // cerr << zz_a << " " << zz_b << " " << dp << "\n";
|
|
|
|
|
+
|
|
|
|
|
+ // cerr << "DP " << ++(d->numdp) << "\r";
|
|
|
|
|
+ pair<ZZ,ZZ> ab(zz_a,zz_b);
|
|
|
|
|
+ pair<DTable::iterator, bool> res;
|
|
|
|
|
+ string x((const char *)(dpwords+1), WORDS*sizeof(unsigned int));
|
|
|
|
|
+
|
|
|
|
|
+ res = d->dtable.insert(DTable::value_type(x, ab));
|
|
|
|
|
+ if (!res.second) {
|
|
|
|
|
+ // Collision!
|
|
|
|
|
+ ZZ adiff = to_ZZ(res.first->second.first) - zz_a;
|
|
|
|
|
+ ZZ bdiff = zz_b - to_ZZ(res.first->second.second);
|
|
|
|
|
+ if (bdiff < 0) bdiff += d->order;
|
|
|
|
|
+ ZZ binv;
|
|
|
|
|
+ if (InvModStatus(binv, bdiff, d->order) == 0) {
|
|
|
|
|
+ d->expon = MulMod(binv, adiff, d->order);
|
|
|
|
|
+ d->found_collision = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (d->order > (1<<20)) {
|
|
|
|
|
+ cerr << "Unhelpful collision\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return d->found_collision;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
int main(int argc, char** argv)
|
|
int main(int argc, char** argv)
|
|
|
{
|
|
{
|
|
|
#ifdef DERANDOMIZE
|
|
#ifdef DERANDOMIZE
|
|
@@ -597,9 +669,10 @@ int main(int argc, char** argv)
|
|
|
|
|
|
|
|
// Try to find the DL_g of y
|
|
// Try to find the DL_g of y
|
|
|
cerr << "DL_" << g << "(" << y << ") mod " << p << "\n";
|
|
cerr << "DL_" << g << "(" << y << ") mod " << p << "\n";
|
|
|
- ZZ e = cuda_dl(g, y, pfvec[f], p);
|
|
|
|
|
- cerr << "e = " << e << "\n";
|
|
|
|
|
- cerr << ( (power(g,e) == y) ? "CORRECT!" : "INCORRECT!" ) << "\n";
|
|
|
|
|
|
|
+ CBData cbdata(g, y, pfvec[f]);
|
|
|
|
|
+ cuda_dl(g, y, pfvec[f], p, 4294967, &cbdata);
|
|
|
|
|
+ cerr << "e = " << cbdata.expon << "\n";
|
|
|
|
|
+ cerr << ( (power(g,cbdata.expon) == y) ? "CORRECT!" : "INCORRECT!" ) << "\n";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
return 0;
|