Skip to content
Snippets Groups Projects
Commit 3dbab27b authored by Bouillaguet Charles's avatar Bouillaguet Charles
Browse files

update + pre_validator + step2.py + strengthening

parent 93b21ffe
Branches
No related tags found
No related merge requests found
......@@ -7,7 +7,7 @@ import random
k = 64
known_up = 6
known_low = 11
known_low = 13
a = 2549297995355413924 * 2**64 + 4865540595714422341
nbiter = 5
nboutput = 40
......@@ -198,7 +198,7 @@ def findDS(rot, W0, WC): #OK!
for i in range(nboutput):
rotprim.append((rot[i] - ((powA[i] * W0 + polA[i] * WC) >> 122)) % 64)
tmp = tuple([(rotprim[i+1] - rotprim[i]) << (122 - known_low) for i in range(nboutput - 1)])
return fpylll.CVP.closest_vector(Greduite2, tmp)
return fpylll.CVP.closest_vector(Greduite2, tmp, method = "proved")
def findDSdebug(rot, W0, WC): #OK!
"""
......@@ -218,73 +218,58 @@ def findDSdebug(rot, W0, WC): #OK!
rotprim[1] = (rotprim[1] - 1) % 64
# fin différence
tmp = tuple([(rotprim[i+1] - rotprim[i]) << (122 - known_low) for i in range(nboutput - 1)])
return fpylll.CVP.closest_vector(Greduite2, tmp)
return fpylll.CVP.closest_vector(Greduite2, tmp, method = "proved")
if __name__ == '__main__':
cpt = {}
cpt[False, False] = 0
cpt[False, True] = 0
cpt[True, False] = 0
cpt[True, True] = 0
cptrotfail = 0
n = 1000
total_output_size = 0
for _ in range(n):
try:
X, S, c = sortiesGenerateur()
# génère ce qu'on est pas censé connaître, et que le gros calcul doit retrouver
W0 = S[0] % LOW
WC = c % LOW
rot = []
for i in range(nboutput):
rot.append(S[i] >> 122)
def full_DS(W0, WC, rots):
uX = unrotateX(X,rot)
DS64, Y0 = FindDS64(uX, rot, W0, WC)#OK!
# refait la partie qui trouve DS64.
# Y = [((S[i] - (powA[i] * W0 + polA[i] * WC)) >> known_low) % (1 << (128 - known_low)) for i in range(nboutput)]
# cheat_DS = [(Y[i + 1] - Y[i]) % (1 << (128 - known_low)) for i in range(nboutput - 1)]
# if cheat_DS[0] % (1 << 64) != DS64[0]:
# raise ValueError("DS64 incorrect ; cannot proceed further")
# calcule toutes les rotations futures à partir de DS64
tabrot = FindRot(DS64[0], X, Y0, W0, WC) #a l'air OK!
listrot = list(product(*tabrot))
test_a = False
test_b = False
output = set()
# vérifie qu'on a bien trouvé un des bon DS complet.
listDS = [findDS(rot, W0, WC) for rot in listrot]
output.update(listDS)
for DS in listDS:
Sprim = [(S[i] - polA[i] * WC - powA[i] * W0) % N for i in range(nboutput)]
if DS[0] == ((Sprim[1] - Sprim[0]) >> known_low):
test_a = True
listDS = [findDSdebug(rot, W0, WC) for rot in listrot]
output.update(listDS)
for DS in listDS:
Sprim = [(S[i] - polA[i] * WC - powA[i] * W0) % N for i in range(nboutput)]
if DS[0] == ((Sprim[1] - Sprim[0]) >> known_low):
test_b = True
return output
cpt[test_a, test_b] += 1
total_output_size += len(output)
if not (test_a or test_b):
raise TypeError("both approaches failed")
if __name__ == '__main__':
# teste la proba de succès des algorithmes
n = 1000
success = 0
for _ in range(n):
try:
X, S, c = sortiesGenerateur()
# génère ce qu'on est pas censé connaître, et que le gros calcul doit retrouver
W0 = S[0] % LOW
WC = c % LOW
rot = []
for i in range(nboutput):
rot.append(S[i] >> 122)
listDS = full_DS(W0, WC, rot)
test = False
for DS in listDS:
true_DS = ((DS[0] << known_low) + (a-1) * W0 + WC) % N
if true_DS == (S[1] - S[0]) % N:
test = True
if not test:
raise TypeError("full_DS failed")
success += 1
except ValueError as e:
print(repr(e))
print(n)
print("cpt:")
print(cpt)
print("total output size = {}".format(total_output_size))
print("success: {} / {}".format(success, n))
\ No newline at end of file
# coding: utf-8
import time
import random as r
import fpylll as f
......@@ -6,7 +7,7 @@ from itertools import product
k = 64
known_up = 6
known_low = 13
known_low = 12
a = 2549297995355413924 * 2^64 + 4865540595714422341
nbiter = 5
nboutput = 40
......@@ -71,7 +72,7 @@ print("Vecteur réputé court de taille : 2^{:.1f}".format(float(log(Greduite2[0
def sortiesGenerateur():#OK !
c = (r.randint(0, 1<<(2 * k)) * 2 + 1) % 1<<(2 * k) #c est impair
c = r.randrange(2**128) | 1
S=[r.randint(0,1<<(k * 2))]
#c=6364136223846793005 * 2^64 + 1442695040888963407#increment par defaut de pcg (connu)
#S=[8487854484825256858 + 11929896274893053136 * 2^64]
......@@ -151,7 +152,7 @@ def FindRot(DS640,X, Y0, W0, WC): #OK !
return []
return tabrot
def findDS(rot, Greduite, cheat_DS, DS64): #OK!
def findDS(rot, W0, WC): #OK!
rotprim = []
for i in range(nboutput):
rotprim.append((rot[i] - ((powA[i] * W0 + polA[i] * WC) >> (2 * k - known_up))) % (1<<known_up))
......@@ -163,12 +164,12 @@ def findDS(rot, Greduite, cheat_DS, DS64): #OK!
print(dec2bin(tmp[i]))
print((cheat_DS[i] - tmp[i])>>(2 * k - known_up - known_low))'''
G = f.IntegerMatrix.from_matrix(Greduite)
G = f.IntegerMatrix.from_matrix(Greduite2)
return f.CVP.closest_vector(G,tuple(tmp))
'''cvp = f.CVP.closest_vector(G,tuple(shifted_tmp))
return vector([((cvp[i] << k) + DS64[0] * powA[i]) % (1 << (128 - known_low)) for i in range(nboutput-1)])'''
def findDSdebug(rot, Greduite, cheat_S, DS64): #OK!
def findDSdebug(rot, W0, WC): #OK!
rotprim = []
for i in range(nboutput):
rotprim.append((rot[i] - ((powA[i] * W0 + polA[i] * WC) >> (2 * k - known_up))) % (1<<known_up))
......@@ -190,52 +191,81 @@ def findDSdebug(rot, Greduite, cheat_S, DS64): #OK!
# print(dec2bin(tmp[i]))
# print((cheat_DS[i] - tmp[i])>>(2 * k - known_up - known_low))
G = f.IntegerMatrix.from_matrix(Greduite)
G = f.IntegerMatrix.from_matrix(Greduite2)
return f.CVP.closest_vector(G,tuple(tmp))
cpt = 0
cpt = {}
cpt[False, False] = 0
cpt[False, True] = 0
cpt[True, False] = 0
cpt[True, True] = 0
cptrotfail = 0
n = 10000
n = 1000
total_output_size = 0
#recupDonnees()
for blabla in range(n):
X, S, c = sortiesGenerateur()
# génère ce qu'on est pas censé connaître, et que le gros calcul doit retrouver
W0 = S[0] % (1 << known_low)
WC = c % (1 << known_low)
rot = []
for i in range(nboutput):
rot.append(S[i] >> (2 * k - 6))
# refait la partie qui trouve DS64.
Y = [((S[i] - (powA[i] * W0 + polA[i] * WC)) >> known_low) % (1 << (2*k - known_low)) for i in range(nboutput)]
cheat_DS = [(Y[i + 1] - Y[i]) % (1 << (2*k - known_low)) for i in range(nboutput - 1)]
assert vector(cheat_DS) in matrix(Greduite2).image()
uX = unrotateX(X,rot)
DS64, Y0 = FindDS64(uX, rot, W0, WC, Greduite1)#OK!
# vérifie que DS64 est correct
assert cheat_DS[0] % (1 << 64) == DS64[0]
# calcule toutes les rotations futures à partir de DS64
tabrot = FindRot(DS64[0], X, Y0, W0, WC) #a l'air OK!
test = 0
listrot = list(product(*tabrot))
#for rot in listrot:
# for i in range(len(S)):
# print((S[i] >> (2 * k - 6)) - rot[i])
listDS = [findDS(rot, Greduite2, S, DS64) for rot in listrot]
# pour chaque jeu de rotations trouvées, calcule DS complet
test_a = False
test_b = False
output = set()
# vérifie qu'on a bien trouvé un des bon DS complet.
listDS = [findDS(rot, W0, WC) for rot in listrot]
output.update(listDS)
for DS in listDS:
Sprim = [(S[i] - polA[i] * (c % 1<<known_low) - powA[i] * (S[0] % 2^known_low)) % 2^128 for i in range(nboutput)]
if(DS[0] == ((Sprim[1] - Sprim[0]) >> known_low)):
test = 1
test_a = True
#if blabla < 3 :
# print('############### NOUVEAU SAMPLE #################')
# listDS = [findDSdebug(rot, Greduite2, S, DS64) for rot in listrot]
if not test :
print('############### NOUVEAU CAS QUI MARCHE PAS #################')
listDS = [findDSdebug(rot, Greduite2, S, DS64) for rot in listrot]
#if not test :
#print('############### NOUVEAU CAS QUI MARCHE PAS #################')
listDS = [findDSdebug(rot, W0, WC) for rot in listrot]
output.update(listDS)
for DS in listDS:
Sprim = [(S[i] - polA[i] * (c % 1<<known_low) - powA[i] * (S[0] % 2^known_low)) % 2^128 for i in range(nboutput)]
if(DS[0] == ((Sprim[1] - Sprim[0]) >> known_low)):
test = 1
cpt += test
test_b = True
cpt[test_a, test_b] += 1
total_output_size += len(output)
print(n)
print("cpt:")
print(cpt)
print("total output size = {}".format(total_output_size))
......@@ -8,7 +8,7 @@ CFLAGS = -O3 -Wall -Wextra -Werror -march=native -mtune=native -fopenmp -g
LDFLAGS = -fopenmp
LDLIBS = -lm
all: main benchmark test test_falsenegative benchmark_omp
all: main pre_validator
main.o: CC=mpicc
main: CC=mpicc
......@@ -16,25 +16,14 @@ main: CC=mpicc
fonctions.o: fonctions.h
fonctions_bonus.o: fonctions.h
main.o: fonctions.h pcg_setseq.h
test.o: fonctions.h pcg_setseq.h
test_falsenegative.o: fonctions.h pcg_setseq.h
benchmark.o: fonctions.h pcg_setseq.h
benchmark_omp.o: fonctions.h pcg_setseq.h
main: fonctions.o main.o
benchmark: fonctions.o benchmark.o
benchmark_omp: fonctions.o benchmark_omp.o
test: fonctions.o test.o fonctions_bonus.o
test_falsenegative: fonctions.o test_falsenegative.o
pre_validator: fonctions.o pre_validator.o
.PHONY: clean check
clean:
rm -rf *.o main test test_falsenegative benchmark
rm -rf *.o main test test_falsenegative benchmark benchmark_omp pre_validator
check: test test_falsenegative
prove -v ./test ./test_falsenegative
bench: benchmark benchmark_omp
./benchmark
./benchmark_omp
\ No newline at end of file
......@@ -70,12 +70,12 @@ static inline void setbit(char *goodY, int i, u64 Y, int v)
goodY[j] &= ~(1 << l);
}
void getGoodY(char* goodY, const u64* X, const u64* lowSumPol, int v)
void getGoodY(char* goodY, const u64 (*X)[nboutput], const u64* lowSumPol, int v)
{
for (int i = 0 ; i < nbtest ; i++){
u64 Wi = lowSumPol[nbiter + i] % (1 << known_low);
for (int j = 0 ; j < k ; j++){
u64 Xij = unrotate(X[i + nbiter], j);
u64 Xij = unrotate((*X)[i + nbiter], j);
u64 goodYi1 = (((Xij % (1 << known_low)) ^ Wi) << known_up) ^ (j ^ (Xij >> (k - known_up)));
u64 goodYi2 = (goodYi1 - 1) % (1 << (known_low + known_up));
setbit(goodY, i, goodYi1, v);
......@@ -95,6 +95,7 @@ static inline int checkY(const char* goodY, int i, u64 Y)
return (goodY[j] >> l) & 1;
}
/* THIS is also time-critical */
static inline bool confirm(u64 Y0, u64 DS640, const struct task_t *task)
{
/**** Confirmation du DS640 ****/
......@@ -126,7 +127,7 @@ static inline long long light_crazy_round(double x)
return magic.l;
}
/* THIS is the time-critical function */
bool solve_isgood(const struct task_t *task)
{
/**** Recherche du DS640 ****/
......@@ -207,7 +208,7 @@ void init_task(struct task_t *t)
t->goodY[y] = 0;
}
void prepare_task(const u64 *X, u64 W0, u64 WC, struct task_t *t)
void prepare_task(const u64 (*X)[nboutput], u64 W0, u64 WC, struct task_t *t)
{
for (int i = 0 ; i < nbiter ; i++) {
t->lowSumPol[i] = (W0 * ((u64) powA[i]) + WC * ((u64) polA[i]));
......@@ -223,7 +224,7 @@ void prepare_task(const u64 *X, u64 W0, u64 WC, struct task_t *t)
// getTabTmp(t->tabTmp, X, t->lowSumPol, t->sumPolY);
for (int i = 0 ; i < k ; i++) {
for (int j = 0 ; j < nbiter ; j++) {
u64 uX = unrotate(X[j], i);
u64 uX = unrotate((*X)[j], i);
t->tabTmp[i * nbiter + j] = (((t->lowSumPol[j] % (1 << known_low)) ^ (uX % (1 << known_low))) << known_up) + (i ^ (uX >> (k - known_up))) - t->sumPolY[j];
}
}
......@@ -232,7 +233,7 @@ void prepare_task(const u64 *X, u64 W0, u64 WC, struct task_t *t)
t->rot[i] = 0;
}
void finish_task(const u64 *X, struct task_t *t)
void finish_task(const u64 (*X)[nboutput], struct task_t *t)
{
getGoodY(t->goodY, X, t->lowSumPol, 0);
}
\ No newline at end of file
......@@ -37,8 +37,8 @@ struct task_t {
/***** Fonctions *****/
void init_var_globales();
void init_task(struct task_t *t);
void prepare_task(const u64 *X, u64 W0, u64 WC, struct task_t *t);
void finish_task(const u64 *X, struct task_t *t);
void prepare_task(const u64 (*X)[nboutput], u64 W0, u64 WC, struct task_t *t);
void finish_task(const u64 (*X)[nboutput], struct task_t *t);
double wtime();
bool solve_isgood(const struct task_t *task);
void solve(const struct task_t *task, u64* DS640, u64* Y0);
......
......@@ -10,12 +10,13 @@
static const bool VERBOSE = false;
enum chkpt_status {GOOD_CHECKPOINT, NO_CHECKPOINT, BAD_CHECKPOINT};
struct checkpoint_t {
u64 known_bits;
u64 X[nbiter];
u64 X[nboutput];
};
u64 X[12];
enum task_status_t {READY, SENT, DONE};
int tag_hello = 0;
int tag_task = 1;
......@@ -24,7 +25,7 @@ int tag_result = 3;
const char * journal_filename = "journal.log";
enum chkpt_status load_journal(enum task_status_t *tasks)
enum chkpt_status load_journal(const u64 (*X)[nboutput], enum task_status_t *tasks)
{
/* try to load checkpoint file */
FILE *f = fopen(journal_filename, "r");
......@@ -45,9 +46,9 @@ enum chkpt_status load_journal(enum task_status_t *tasks)
printf("Guessed bits mismatch. Now=%d, in checkpoint=%lld.\n", known_low, chkpt.known_bits);
return BAD_CHECKPOINT;
}
for (int i = 0; i < nbiter; i++)
if (X[i] != chkpt.X[i]) {
printf("X[%d] mismatch. Now=%llx, in checkpoint=%llx.\n", i, X[i], chkpt.X[i]);
for (int i = 0; i < nboutput; i++)
if ((*X)[i] != chkpt.X[i]) {
printf("X[%d] mismatch. Now=%llx, in checkpoint=%llx.\n", i, (*X)[i], chkpt.X[i]);
return BAD_CHECKPOINT;
}
......@@ -75,7 +76,7 @@ enum chkpt_status load_journal(enum task_status_t *tasks)
}
void save_journal_header()
void save_journal_header(const u64 (*X)[nboutput])
{
struct checkpoint_t chkpt;
int size;
......@@ -83,8 +84,8 @@ void save_journal_header()
/* prepare checkpoint data */
chkpt.known_bits = known_low;
for (int i = 0; i < nbiter; i++)
chkpt.X[i] = X[i];
for (int i = 0; i < nboutput; i++)
chkpt.X[i] = (*X)[i];
/* try to open journal file */
FILE *f = fopen(journal_filename, "w");
......@@ -101,7 +102,7 @@ void save_journal_header()
}
void result_found(const u64 *X, u64 W0, u64 WC, u64 r)
void result_found(const u64 (*X)[nboutput], u64 W0, u64 WC, u64 r)
{
/* we print it just in case something goes wrong... */
printf("solution found : W_0 = %04llx / W_c = %04llx / r = %08llx\n", W0, WC, r);
......@@ -113,14 +114,14 @@ void result_found(const u64 *X, u64 W0, u64 WC, u64 r)
if (f == NULL)
err(1, "cannot open solution file");
for (int i = 0; i < nbiter; i++)
fprintf(f, "X[%d] = %llx\n", i, X[i]);
fprintf(f, "X[%d] = %llx\n", i, (*X)[i]);
fprintf(f, "W_0 = %04llx / W_c = %04llx / r = %08llx\n", W0, WC, r);
fprintf(f, "==============================================\n");
fclose(f);
}
void do_task(u64 current, struct task_t *task, const u64 *X)
void do_task(u64 current, struct task_t *task, const u64 (*X)[nboutput])
{
double start = MPI_Wtime();
u64 W0 = current >> (known_low - 1);
......@@ -164,7 +165,7 @@ void do_task(u64 current, struct task_t *task, const u64 *X)
* Observed 6750 task/h on one node.
* So we need 310 node-hours (we will be billed 12.4K cpu-hours).
*/
void master()
void master(const u64 (*X)[nboutput])
{
int n_tasks = 1 << (2 * known_low - 1);
enum task_status_t *tasks = malloc(sizeof(*tasks) * n_tasks);
......@@ -176,24 +177,26 @@ void master()
tasks[i] = READY;
int task_ptr = 0;
enum chkpt_status status = load_journal(tasks);
enum chkpt_status status = load_journal(X, tasks);
switch (status) {
case BAD_CHECKPOINT:
printf("BAD CHECKPOINT. Refusing to start. Please clean up the mess\n");
exit(EXIT_FAILURE);
case NO_CHECKPOINT:
printf("COLD START.\n");
save_journal_header();
save_journal_header(X);
break;
case GOOD_CHECKPOINT:
printf("WARM START.\n");
break;
}
#if 0
/* DEBUG */
// W_0 = 0x01ec
// W_c = 0x040b
// task_ptr = (0x01ec << (known_low - 1)) + (0x040b - 1) / 2;
int W_0 = 0x01d0;
int W_c = 0x035b;
task_ptr = (W_0 << (known_low - 1)) + (W_c - 1) / 2;
#endif
FILE *journal_file = fopen(journal_filename, "a");
if (journal_file == NULL)
......@@ -252,7 +255,7 @@ void master()
* OK, so a bug in Intel's MPI library prevents us from using one MPI rank
* per hyperthread, so here we cheat.
*/
void slave()
void slave(const u64 (*X)[nboutput])
{
int T = omp_get_max_threads();
for (int i = 0; i < T; i++)
......@@ -301,23 +304,21 @@ int main(int argc, char **argv)
init_var_globales();
// X[ 0] = 0xe60f77ceac8f6cd9; // W_0 = 00ed
X[ 0] = 0xa21bd9d52bb064fa; // W_0 = 01ec
X[ 1] = 0xde3e78a8e09e5d29; // W_0 = 00a7
X[ 2] = 0xdbbe7755775e52ac; // W_0 = 030e
X[ 3] = 0xe553b06143b2e108; // W_0 = 02d1
X[ 4] = 0x4d99972ab762dae8; // W_0 = 0460
X[ 5] = 0x27af5ab26f846d1d; // W_0 = 01eb
X[ 6] = 0xd360f68fcc697b33; // W_0 = 0262
X[ 7] = 0x746b18d4b67a4e61; // W_0 = 0475
X[ 8] = 0x9be7410a83ddc14a; // W_0 = 0594
X[ 9] = 0x6c2b07bed5b9fe0b; // W_0 = 04ef
X[10] = 0x2fc807378a7bff2b; // W_0 = 0276
u64 X[nboutput];
X[ 0] = 0xd4166f4c3e02d10a;
X[ 1] = 0x1d1ceb21e7737101;
X[ 2] = 0xf8b90f473a5426d3;
X[ 3] = 0xe3a3b7babb2ad9ca;
X[ 4] = 0x0077f2c80987dd13;
X[ 5] = 0xf8ddaf2431548a13;
X[ 6] = 0x80935e041bbab85a;
X[ 7] = 0xbe0fde3939201c50;
X[ 8] = 0xe9604fdf6b2177b7;
if (rank == 0)
master();
master(&X);
else
slave();
slave(&X);
MPI_Finalize();
return 0;
......
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <string.h>
#include <time.h>
#include "fonctions.h"
void result_found(u64 W0, u64 WC, u64 r)
{
/* we print it just in case something goes wrong... */
printf("solution found : W_0 = %04llx / W_c = %04llx / r = %08llx\n", W0, WC, r);
}
void do_task(u64 current, struct task_t *task, const u64 (*X)[nboutput])
{
u64 W0 = current >> (known_low - 1);
u64 WC = 1 + 2 * (current % (1 << (known_low - 1)));
printf("Doing task %llx (W_0=%04llx / W_c=%04llx)\n", current, W0, WC);
prepare_task(X, W0, WC, task);
for (u64 r = 0; r < 1 << (nbiter * known_up); r++) {
task->rot[0] = (task->rot[0] + 1) % k;
int i = 0;
while (task->rot[i] == 0 && i < nbiter) {
i++;
task->rot[i] = (task->rot[i] + 1) % k;
}
if (solve_isgood(task))
result_found(W0, WC, r);
}
finish_task(X, task);
}
int main()
{
init_var_globales();
u64 X[nboutput];
int W_c = 0x035b;
//X[ 0] = 0x2a33f0ac9ba281a3; int W_0 = 0x0271;
X[ 0] = 0xd4166f4c3e02d10a; int W_0 = 0x01d0;
X[ 1] = 0x1d1ceb21e7737101; // W_0 = 006b
X[ 2] = 0xf8b90f473a5426d3; // W_0 = 0232
X[ 3] = 0xe3a3b7babb2ad9ca; // W_0 = 06d5
X[ 4] = 0x0077f2c80987dd13; // W_0 = 00c4
X[ 5] = 0xf8ddaf2431548a13; // W_0 = 002f
X[ 6] = 0x80935e041bbab85a; // W_0 = 0206
X[ 7] = 0xbe0fde3939201c50; // W_0 = 02f9
X[ 8] = 0xe9604fdf6b2177b7; // W_0 = 0678
/* DEBUG */
u64 task_id = (W_0 << (known_low - 1)) + (W_c - 1) / 2;
struct task_t task;
init_task(&task);
do_task(task_id, &task, &X);
return 0;
}
\ No newline at end of file
import re
import time
import fpylll
import os
from itertools import product
from math import log
import random
k = 64
known_up = 6
known_low = 11
a = 2549297995355413924 * 2**64 + 4865540595714422341
nbiter = 5
nboutput = 40
N = 2**128
K = 2**64
LOW = 2**known_low
polA = [0];
powA = [1];
for i in range (1, nboutput):
polA.append((polA[i-1] + powA [i-1]) % N)
powA.append((powA[i-1] * a) % N)
def dec2bin(d,nb= 2 * k - known_low + 1):
"""Représentation d'un nombre entier en chaine binaire (nb: nombre de bits du mot)"""
if d == 0:
return "0".zfill(nb)
if d<0:
d += 1<<nb
b=""
while d != 0:
d, r = divmod(d, 2)
b = "01"[r] + b
return b.zfill(nb)
#### MATRIX ####
def getG(n, mod):
G = fpylll.IntegerMatrix(n, n)
G[0, 0] = 1
powA = a % mod
for i in range(1, n):
G[i, 0] = powA
powA = powA * a % mod
for j in range(1, n):
G[i, i] = mod
return G
def getGreduite(n, mod):
G = getG(n, mod)
G.transpose() # in place
fpylll.LLL.reduction(G) # in place
assert fpylll.LLL.is_reduced(G)
return G
Greduite1 = getGreduite(nbiter - 1, 2**64)
Greduite2 = getGreduite(nboutput - 1, 2**(128 - known_low))
#### Récupération des données ####
#def recupDonnees():
# listfiles = os.listdir('results')
# print(listfiles)
# listDonnees = []
# for i in range(listfiles):
# listDonnees.append[]
# f = open(listfiles[i], "r")
# while(1):
# s = f.readline()
def sortiesGenerateur():#OK !
c = random.randrange(N) | 1
S = [random.randrange(N)]
#c=6364136223846793005 * 2^64 + 1442695040888963407#increment par defaut de pcg (connu)
#S=[8487854484825256858 + 11929896274893053136 * 2^64]
for i in range (nboutput - 1):
S.append((S[i] * a + c) % N)
X = []
for i in range(nboutput):
x = (S[i] % K) ^ (S[i] >> 64)
rot = S[i] >> 122
X.append((x >> rot) | ((x << (64 - rot)) % K))
return X, S, c
## Unrotate
def rotateX(X, rot):#OK !
rX = [];
for i in range(nbiter):
rX.append((X[i] >> rot[i]) + ((X[i] << (64 - rot[i])) % K))
return rX
def unrotateX(X, rot):#OK !
rot2 = []
for i in range(nbiter):
rot2.append(64 - rot[i])
return rotateX(X, rot2)
def unrotate1(Xi):#OK !
return (Xi >> 63) | ((Xi << 1) % K)
###### Sous-fonctions de FindDS######
def getY(W0, WC, rot, uX):#OK !
"""Y contains bits [58:58+know_low] of the states.
>>> uX = [1644185799909158604, 17240438759649590578, 11978199211677924477, 5312027464555861226, 16472746463602985594]
>>> getY(5066, 5697, [35, 1, 55, 20, 50], uX)
[475558, 434298, 393054, 445126, 20235]
"""
Y = []
LOW = 2**known_low
for i in range(nbiter):
a = (powA[i] * W0 + polA[i] * WC) % LOW
y = (a ^ (uX[i] % LOW)) * 64 + (rot[i] ^ (uX[i] >> 58))
Y.append(y)
return Y
def getYprim(Y, WC, W0): #OK ! avec erreurs de retenues ~64bits (polC polW)
"""
>>> getYprim([334551, 344605, 20585, 258928, 328272], 3153, 3443)
[334551, 209941, 95413, 359500, 210406]
"""
Yprim=[(Y[i] - ((polA[i] * WC + powA[i]*W0) >> 58)) % 2**(known_up + known_low) for i in range(nbiter)]
return Yprim
def getDY(Y, WC, W0): #OK ! avec erreurs de retenues ~64bits (polC polW)
Yprim = getYprim(Y, WC, W0)
DY = [(Yprim[i+1] - Yprim[i]) % 2**(known_up + known_low) for i in range(nbiter-1)]
return DY
######FINDDS######
def FindDS64(uX, rot, W0, WC): #rajouter rot dans la version non test ? #OK! ~64bits
"""
>>> uX = [4176226900736828747, 9952865681489253366, 2688170825735170541, 1480864413810423309, 12311021560119210858]
>>> DS64, Y0 = FindDS64(uX, [54, 1, 4, 13, 17], 4995, 1897)
>>> DS64
(3143953020030867257, 10643623498242246749, 18015690067871096593, 6081360100074780053)
>>> Y0
373304
>>> (DS64[1] - a * DS64[0]) % (2**64)
0
>>> (DS64[3] - a**3 * DS64[0]) % (2**64)
0
"""
Y = getY(W0, WC, rot, uX)
DY = getDY(Y, WC, W0) #OK avec erreurs de retenues!
tmp = tuple([y << (58 - known_low) for y in DY])#on rajoute les zéros, recentrage impossible à cause des erreurs de retenues
DS64 = fpylll.CVP.closest_vector(Greduite1, tmp)
return DS64, Y[0]
######FINDROTI######
#DS64ij = ((polA[j] - polA[i])*DSmod0) % 2**k
def FindRoti(DS640, X, i, Y0, W0, WC): #OK !
LOW = (1 << known_low)
DS640i = (polA[i] * DS640) % K
DSmod0i = ((DS640i << known_low) + W0 * powA[i] + WC * polA[i] - WC - W0) % (1 << (k + known_low))
# Yi = vraiYi ou vraiYi - 1 à cause de la retenue
Yi1 = (Y0 + (DSmod0i >> 58)) % (1 << (known_low + 6)) #avec ou sans retenue
Yi2 = Yi1 + 1
Wi = (W0 * powA[i] + WC * polA[i]) % LOW
roti = []
for j in range(k):
test1 = (((X ^ (Yi1 >> known_up)) % LOW) == Wi) and ((j ^ (X >> 58)) == Yi1 % 64)
test2 = (((X ^ (Yi2 >> known_up)) % LOW) == Wi) and ((j ^ (X >> 58)) == Yi2 % 64)
if test1 or test2:
roti.append(j)
X = unrotate1(X)
return roti
def FindRot(DS640, X, Y0, W0, WC): #OK !
"""
>>> X = [7562813409073772899, 11417283543806325847, 12362888193759185837, 16903337852395683996, 14856662724370164170, 14353358590961859327, 1709017510603189214, 11112388053225929234, 16326783999071815356, 11265942744832116279, 1663761383601515443, 8264994773702130067, 9504586450162996576, 10071306062678369278, 17269754077915402502, 17284552641819218296, 7862210236782409543, 1173693182357848465, 8669989150777025119, 14483674533785677591, 11817711069368805698, 17652236263878993880, 10952708804218529727, 5546964202247030872, 3787337376045307491, 2463598675764221383, 5606708014410888418, 6875937051451039350, 8452423750630374467, 17961190178884696858, 5340192466979356088, 8233231102133794361, 12880144913541639341, 15509087343987396656, 18273038824920986967, 2620114879769493608, 2973201289203915946, 11220433026578214934, 12347822205906378923, 4161809839587283616]
>>> FindRot(4512847418431975849, X, 335296, 2791, 6689)
[[21], [43], [27], [49], [31], [36], [17], [7], [16], [12], [4], [41], [56], [57], [17], [21], [15], [51], [14], [62], [40], [3], [50], [50], [12], [21], [26], [48], [39], [20], [3], [6], [60], [50], [53], [28], [24], [33], [9], [50]]
"""
tabrot =[]
for i in range(nboutput):
tabrot.append(FindRoti(DS640, X[i], i, Y0, W0,WC))
if len(tabrot[i]) == 0:
raise ValueError("pas de rotations possibles")
return tabrot
def findDS(rot, W0, WC): #OK!
"""
>>> rot = (48, 13, 19, 55, 60, 17, 18, 25, 27, 7, 29, 62, 40, 26, 8, 43, 11, 33, 25, 47, 9, 24, 57, 57, 15, 61, 9, 12, 49, 42, 63, 44, 41, 21, 10, 34, 18, 31, 57, 56)
>>> DS = findDS(rot, 4975, 4063)
>>> DS
(-3911495036692940322621796134291199, -7279435059422484119362302816873659, -5980753107089600906205976366383207, 26501861599381476532331924531931709, -31630035624456443253911377653383055, 29213102710206694601105260826063989, -23281560453589451868529477218643575, 17888517654251431755244562532048877, 3228901960492265957430914842941665, 2313333816108045922019596861352613, -38216913742480012196731378496271239, 24068986573173657396568329560531613, -1898490002137598832998023266815407, -12376784405299621377499477592545835, 29039659037871761656409287413276777, -11120000896287372100511132327173555, -17733553412493159685771337165456191, -8741721083865437369382845282560507, 30558047682244154952554650584415577, 1357273502023295372192253817507581, -24843031240572301260463448405579727, -3299110994710694014154259362174155, -1487293042488303561252348415241399, -3759853676895093460585569200088915, 36340912119809025232203444281812129, -36471259272312409369956954296904347, 6259392443418117937466593286640185, 33078586047867229586889558846467933, -39185067306776146290022302686584303, 477254915511356870841557501691029, 14118492461907402245240001077094953, -1960793072427708660280495620799731, -9137193975787581074734956369964927, 14813477132465570555338375023945925, -18712543965827835408441644622214375, 14470108143760423276150009776702397, -789275610922086810087986631368719, 2450579317286955048107917366440437, -12618929602727743299982987170192119)
>>> (DS[1] - a * DS[0]) % (2**(128 - known_low))
0
>>> (DS[5] - a**5 * DS[0]) % (2**(128 - known_low))
0
"""
rotprim = []
for i in range(nboutput):
rotprim.append((rot[i] - ((powA[i] * W0 + polA[i] * WC) >> 122)) % 64)
tmp = tuple([(rotprim[i+1] - rotprim[i]) << (122 - known_low) for i in range(nboutput - 1)])
return fpylll.CVP.closest_vector(Greduite2, tmp, method = "proved")
def findDSdebug(rot, W0, WC): #OK!
"""
>>> rot = (36, 11, 26, 47, 27, 43, 40, 4, 6, 14, 46, 7, 26, 15, 29, 52, 5, 27, 59, 51, 50, 10, 18, 12, 20, 13, 41, 11, 33, 29, 11, 34, 57, 43, 57, 9, 4, 44, 5, 61)
>>> DS = findDSdebug(rot, 931, 4565)
>>> DS
(-2402491240055656244800996055138065, -12494820703177916317385412874753429, 16338193271580590973761587180847319, -15300585971148004077979215350754317, 21684776253948045125360273100268159, -27815550822220705053670430230538693, 11625224150341610375324286543409127, 17844093130120930863081999339086659, -380944688746118817409004598549745, -28522485004078932652170383056544501, 520732373288502378058486581798391, -3634819024663226032969760811575917, 2969698435142367696300086782333599, 28037325802964017993093991345016539, -10910817629932953951556521090665721, -5065536280883514534631998922589469, 22910033460594640618280890256081199, -2053703208298283961366229680604245, -29057244128546792360653529929160937, -3838864775261833707985232041974989, 30542591494432091311532645601492671, 422636935015451582314011290366843, -3834374215185520065523022262513113, -31730206033684723762666891971912061, 1605231086249882265091899797936975, 28745614588815424753948783543535179, 206839261025612279689680544465975, 5000213623392168998536915729513683, -13303445174387063160344871468669217, 16214267541652108868690966934029339, -36078096034273452443520370613514937, 37999702462501891126733863140871715, -13428983410411412751530034747362961, 5641457792955538248534388118420715, -29350387749398409235158943575343785, 21982279210625596709854366303937139, -12448157819225143628043984315675905, -11894269968695156406609582729527109, 8505931709653315845144709262926951)
>>> (DS[1] - a * DS[0]) % (2**(128 - known_low))
0
>>> (DS[5] - a**5 * DS[0]) % (2**(128 - known_low))
0
"""
rotprim = []
for i in range(nboutput):
rotprim.append((rot[i] - ((powA[i] * W0 + polA[i] * WC) >> 122)) % 64)
# différence ici !
rotprim[1] = (rotprim[1] - 1) % 64
# fin différence
tmp = tuple([(rotprim[i+1] - rotprim[i]) << (122 - known_low) for i in range(nboutput - 1)])
return fpylll.CVP.closest_vector(Greduite2, tmp, method = "proved")
def full_DS(X, W0, WC, rots):
uX = unrotateX(X,rot)
DS64, Y0 = FindDS64(uX, rot, W0, WC)#OK!
# calcule toutes les rotations futures à partir de DS64
tabrot = FindRot(DS64[0], X, Y0, W0, WC) #a l'air OK!
listrot = list(product(*tabrot))
output = set()
# vérifie qu'on a bien trouvé un des bon DS complet.
listDS = [findDS(rot, W0, WC) for rot in listrot]
output.update(listDS)
listDS = [findDSdebug(rot, W0, WC) for rot in listrot]
output.update(listDS)
return output
if __name__ == '__main__':
X = [0] * 48
X[ 1] = 0xd4166f4c3e02d10a;
X[ 2] = 0x1d1ceb21e7737101;
X[ 3] = 0xf8b90f473a5426d3;
X[ 4] = 0xe3a3b7babb2ad9ca;
X[ 5] = 0x0077f2c80987dd13;
X[ 6] = 0xf8ddaf2431548a13;
X[ 7] = 0x80935e041bbab85a;
X[ 8] = 0xbe0fde3939201c50;
X[ 9] = 0xe9604fdf6b2177b7;
X[10] = 0x95d9cf24a229cedf;
X[11] = 0x0434a85418759293;
X[12] = 0x04d230c1debe7999;
X[13] = 0x83a3cd257d4d04b0;
X[14] = 0x13990a23037c13c4;
X[15] = 0xfbfaea2e50411202;
X[16] = 0x421a394a36baebf8;
X[17] = 0x5a878c4594ea7221;
X[18] = 0xbd37307bdd522b9c;
X[19] = 0x39af06b3e9b3ae10;
X[20] = 0x1d21f1cee77b8e2e;
X[21] = 0xe4bddad0aacaf420;
X[22] = 0x1009ed344cd7f2f4;
X[23] = 0xff287c5797cceb71;
X[24] = 0x85e8968b0d8ab49b;
X[25] = 0x69a9b821830862cc;
X[26] = 0xf9fe65ed23740aea;
X[27] = 0x47669184bc43d948;
X[28] = 0xe3f19b31915ae6d3;
X[29] = 0x5f3945718b6dac44;
X[30] = 0x49bfacfe8056b33c;
X[31] = 0xf2b358ceb722628f;
X[32] = 0xb4d1bf17f2c57b71;
X[33] = 0xb4300000ad802deb;
X[34] = 0xe3125e8022de888d;
X[35] = 0x2c7f6d404196ed4d;
X[36] = 0xb10490274ecbe897;
X[37] = 0xb04da8a406da3814;
X[38] = 0xbc70124be9a196c9;
X[39] = 0xf81a244f765141e6;
X[40] = 0x20413cda8442a149;
X[41] = 0xf654f8084029c557;
X[42] = 0xa1677f2f18f8484c;
X[43] = 0x3ef4f6e355c53e70;
X[44] = 0x30cceccd8f73c567;
X[45] = 0xf22a193ded925cb6;
X[46] = 0xa9c0cba2f6abbd89;
X[47] = 0xf26c7311f52ededb;
del X[0]
regex = re.compile(r"W_0 = (?P<W0>[0-9a-f]+) / W_c = (?P<WC>[0-9a-f]+) / r = (?P<r>[0-9a-f]+)")
with open("../logs/solutions.txt") as f:
for line in f:
m = regex.match(line)
if not m:
continue
W0 = int(m['W0'], base=16)
WC = int(m['WC'], base=16)
r = int(m['r'], base=16)
r += 1
rot = []
for _ in range(nbiter):
x = r % 64
r = r // 64
rot.append(x)
try:
listDS = full_DS(X, W0, WC, rot)
for DS in listDS:
true_DS = ((DS[0] << known_low) + (a-1) * W0 + WC) % N
print("Got W_0 = {:04x}, W_c = {:04x}, DS = {:032x}".format(W0, WC, true_DS))
except ValueError as e:
pass
......@@ -34,7 +34,7 @@ int main()
}
printf("Predictor input:\n");
for (int i = 0; i < 32; i++) {
for (int i = 0; i < 48; i++) {
printf("X[%2d] = 0x%016" PRIx64 ";", i, pcg64_random_r(&rng));
if (DEBUG)
printf("\t // W_0 = %04llx", (unsigned long long) (rng.state % (1 << known_low)));
......@@ -42,7 +42,7 @@ int main()
}
printf("\n");
printf("Remaining of the sequence (predictor output, in principle):\n");
for (int i = 32; i < 48; i++)
for (int i = 48; i < 64; i++)
printf("X[%2d] = 0x%016" PRIx64 ";\n", i, pcg64_random_r(&rng));
return EXIT_SUCCESS;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment