Finished project
This commit is contained in:
573
main.cpp
Normal file
573
main.cpp
Normal file
@@ -0,0 +1,573 @@
|
||||
#include <cstdlib>
|
||||
# include<iostream>
|
||||
# include<string>
|
||||
# include<random>
|
||||
# include<cmath>
|
||||
# include<array>
|
||||
using namespace std;
|
||||
|
||||
typedef long long int Lint; // 64 bits
|
||||
typedef double Ldouble;
|
||||
struct security {
|
||||
int num_shares;
|
||||
int num_required;
|
||||
};
|
||||
|
||||
struct shareStruct {
|
||||
Lint y;
|
||||
int x;
|
||||
};
|
||||
|
||||
bool isPrime(Lint n) {
|
||||
int flag = 0;
|
||||
for (int i = 2; i <= n / i; ++i) {
|
||||
if (n % i == 0) {
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag == 0) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
Lint genRandInt(int n) {
|
||||
// Returns a random number
|
||||
// between 2**(n-1)+1 and 2**n-1
|
||||
//long max = (long)powl(2, n) - 1;
|
||||
//long min = (long)powl(2, n - 1) + 1;
|
||||
long max = (long)pow(2, n) - 1;
|
||||
long min = (long)pow(2, n - 1) + 1;
|
||||
Lint result = min + (rand() % ( max - min + 1 ) );
|
||||
//cout << "Random num: " << result << endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
Lint genPrime() {
|
||||
Lint prime = 10;
|
||||
|
||||
while (isPrime(prime) == false) {
|
||||
int complexity = 50;
|
||||
prime = genRandInt(complexity);
|
||||
}
|
||||
return prime;
|
||||
}
|
||||
|
||||
Lint getSecret() {
|
||||
int secret;
|
||||
Lint total = 1;
|
||||
string total_string = "";
|
||||
string secret_text;
|
||||
|
||||
cout << "Enter share secret:";
|
||||
cin.ignore();
|
||||
getline(cin, secret_text);
|
||||
cout << endl;
|
||||
|
||||
for (int i=0; i < size(secret_text); i++) {
|
||||
char character = secret_text[i];
|
||||
string character_value = to_string(int(character));
|
||||
|
||||
int append_size = 3 - size(character_value);
|
||||
string append_string = "";
|
||||
for (int i=0; i<append_size; i++) {
|
||||
cout << "in for" << endl;
|
||||
append_string = append_string + "0";
|
||||
}
|
||||
|
||||
character_value = append_string + character_value;
|
||||
total_string = total_string + character_value;
|
||||
}
|
||||
cout << "total string: " << total_string << endl;
|
||||
secret = total;
|
||||
|
||||
return secret;
|
||||
}
|
||||
|
||||
int* encodeSecret(int* poly, const int secret, const int num_required) {
|
||||
poly[num_required-1] = secret;
|
||||
return poly;
|
||||
}
|
||||
|
||||
security getSecurity() {
|
||||
int num_shares = 0;
|
||||
int num_required = 1;
|
||||
while ((num_required > num_shares) and (num_required < 7)) {
|
||||
cout << "Enter the number of shares required (2-6): ";
|
||||
cin >> num_required;
|
||||
cout << endl << "Enter the number of shares to be created: ";
|
||||
cin >> num_shares;
|
||||
cout << endl;
|
||||
}
|
||||
security securityOptions;
|
||||
securityOptions.num_shares = num_shares;
|
||||
securityOptions.num_required = num_required;
|
||||
|
||||
return securityOptions;
|
||||
}
|
||||
|
||||
Lint getPolyY(const int* poly, int poly_len, int poly_x, const Lint prime) {
|
||||
Lint total = 0;
|
||||
Lint poly_y = 0;
|
||||
|
||||
for (int i=0; i<poly_len+1; i++) {
|
||||
int power = poly_len - i;
|
||||
int coefficient = poly[i];
|
||||
poly_y = coefficient * pow(poly_x, power);
|
||||
total = total + poly_y;
|
||||
|
||||
//cout << endl << "--- next share ---" << endl;
|
||||
//cout << "In getPolyY: total: " << total << endl;
|
||||
//cout << "In getPolyY: poly_y: " << poly_y << endl;
|
||||
//cout << "In getPolyY: power: " << power << endl;
|
||||
//cout << "In getPolyY: pow(poly_x, power): " << pow(poly_x, power) << endl;
|
||||
//cout << "In getPolyY: poly_x: " << poly_x << endl;
|
||||
//cout << "In getPolyY: coefficient: " << coefficient << endl;
|
||||
//cout << endl;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
shareStruct* genShares(int num_shares, int num_required, const int* poly, const Lint prime){
|
||||
shareStruct* shares = new shareStruct[num_shares];
|
||||
for (int i=1; i<=num_shares; i++) {
|
||||
shareStruct share;
|
||||
share.x = i;
|
||||
share.y = getPolyY(poly, num_required-1, share.x, prime);
|
||||
shares[i-1] = share;
|
||||
}
|
||||
return shares;
|
||||
}
|
||||
|
||||
int* genPoly(int degree, const Lint prime, const Lint secret) {
|
||||
int* poly = new int[degree];
|
||||
|
||||
for (int i = 0; i < degree; i++) {
|
||||
int random_num = genRandInt(10);
|
||||
poly[i] = prime % random_num;
|
||||
}
|
||||
return poly;
|
||||
}
|
||||
|
||||
void outputShares(shareStruct* shares, int num_shares) {
|
||||
bool pretty = true;
|
||||
cout << "Shares: " << endl;
|
||||
for (int i = 0; i<num_shares; i++) {
|
||||
if (pretty == false) {
|
||||
cout << "(" << shares[i].x << ", " << shares[i].y << "), ";
|
||||
}
|
||||
else {
|
||||
cout << "Share " << shares[i].x << ": " << shares[i].y << " | ";
|
||||
}
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// RBP
|
||||
void outputPoly(const int* poly, Lint secret, int poly_len) {
|
||||
string cof = "";
|
||||
for (int i=0; i<poly_len-1; i++) {
|
||||
int power = poly_len - i - 1;
|
||||
cof = cof + to_string(poly[i]) + "x^" + to_string(power) + " + ";
|
||||
}
|
||||
cout << "Poly: " << cof << secret << endl;
|
||||
}
|
||||
// RBP
|
||||
|
||||
void newSecret() {
|
||||
cout << "----- Create a new secret -----" << endl;
|
||||
security securityOptions = getSecurity();
|
||||
const int num_shares = securityOptions.num_shares;
|
||||
const int num_required = securityOptions.num_required;
|
||||
|
||||
const Lint prime = genPrime();
|
||||
|
||||
Lint secret = getSecret();
|
||||
// RBP
|
||||
secret = 520;
|
||||
// RBP
|
||||
|
||||
int* poly = genPoly(num_required-1, prime, secret);
|
||||
|
||||
poly = encodeSecret(poly, secret, num_required);
|
||||
|
||||
shareStruct* shares = genShares(num_shares, num_required, poly, prime);
|
||||
outputShares(shares, num_shares);
|
||||
}
|
||||
|
||||
// solving polynomials
|
||||
struct inputStruct {
|
||||
int required;
|
||||
shareStruct* shares;
|
||||
};
|
||||
|
||||
inputStruct getInfo() {
|
||||
inputStruct inputs;
|
||||
|
||||
int required;
|
||||
cout << "Enter number of shares required: ";
|
||||
// RBP
|
||||
required = 3;
|
||||
// RBP
|
||||
cin >> required;
|
||||
cout << endl;
|
||||
|
||||
shareStruct* shares = new shareStruct[required];
|
||||
for (int i = 0; i < required; i++) {
|
||||
cout << "Enter number of next share: ";
|
||||
shareStruct share;
|
||||
// RBP
|
||||
share.x = 1;
|
||||
// RBP
|
||||
cin >> share.x;
|
||||
|
||||
cout << "Enter the share secret: ";
|
||||
// RBP
|
||||
share.y = 3;
|
||||
// RBP
|
||||
cin >> share.y;
|
||||
cout << endl;
|
||||
|
||||
shares[i] = share;
|
||||
}
|
||||
|
||||
inputs.shares = shares;
|
||||
inputs.required = required;
|
||||
return inputs;
|
||||
}
|
||||
|
||||
struct polyTerm {
|
||||
Lint coefficient;
|
||||
int power;
|
||||
};
|
||||
|
||||
struct linearEquation {
|
||||
shareStruct point;
|
||||
polyTerm* terms;
|
||||
};
|
||||
|
||||
linearEquation* constructEquations(const int required, shareStruct shares[]) {
|
||||
linearEquation* equations = new linearEquation[required];
|
||||
shareStruct share;
|
||||
polyTerm term;
|
||||
|
||||
for (int i = 0; i < required; i++) {
|
||||
share = shares[i];
|
||||
linearEquation equation;
|
||||
polyTerm* terms = new polyTerm[required];
|
||||
|
||||
for (int j = 0; j < required; j++) {
|
||||
term.power = required - 1 - j;
|
||||
terms[j] = term;
|
||||
}
|
||||
|
||||
equation.terms = terms;
|
||||
equation.point.x = share.x;
|
||||
equation.point.y = share.y;
|
||||
|
||||
// RBP
|
||||
//cout << "y: " << equation.point.y << endl;
|
||||
//cout << "x: " << equation.point.x << endl;
|
||||
//cout << "i: " << i << endl;
|
||||
// RBP
|
||||
|
||||
equations[i] = equation;
|
||||
// dont delete terms from memory as its referanced in equations
|
||||
}
|
||||
return equations;
|
||||
}
|
||||
|
||||
struct matrix{
|
||||
Lint** matrix;
|
||||
int dimension_x;
|
||||
int dimension_y;
|
||||
};
|
||||
struct matrix_system {
|
||||
matrix A;
|
||||
matrix B;
|
||||
matrix X;
|
||||
};
|
||||
|
||||
matrix_system formMatrix(const linearEquation* equations, int required) {
|
||||
Lint** matrixA = new Lint*[required];
|
||||
Lint** matrixB = new Lint*[required];
|
||||
|
||||
for (int i=0; i < required; i++) {
|
||||
linearEquation equation = equations[i];
|
||||
Lint* lineA = new Lint[required];
|
||||
for (int j=0; j < required; j++) {
|
||||
lineA[j] = pow(equation.point.x, equation.terms[j].power);
|
||||
}
|
||||
matrixA[i] = lineA;
|
||||
|
||||
Lint* lineB = new Lint[1];
|
||||
lineB[0] = equation.point.y;
|
||||
matrixB[i] = lineB;
|
||||
}
|
||||
|
||||
matrix matrixA_data; matrix matrixB_data;
|
||||
matrixA_data.matrix = matrixA; matrixB_data.matrix = matrixB;
|
||||
|
||||
matrixA_data.dimension_x = required; matrixB_data.dimension_x = 1;
|
||||
matrixA_data.dimension_y = required; matrixB_data.dimension_y = required;
|
||||
|
||||
matrix_system matricies;
|
||||
matricies.A = matrixA_data; matricies.B = matrixB_data;
|
||||
|
||||
return matricies;
|
||||
}
|
||||
|
||||
Lint** findMinor(Lint** matrixA, const int dimension, const int pos_x, const int pos_y) {
|
||||
Lint** matrixB = new Lint*[dimension-1];
|
||||
int matrixB_pos_x = 0; int matrixB_pos_y = 0;
|
||||
|
||||
for (int i=0; i<dimension; i++) {
|
||||
Lint* line = new Lint[dimension-1];
|
||||
for (int j=0; j<dimension; j++) {
|
||||
if (i != pos_y and j != pos_x) {
|
||||
line[matrixB_pos_x] = matrixA[i][j];
|
||||
matrixB_pos_x++;
|
||||
}
|
||||
}
|
||||
if (matrixB_pos_x != 0) {
|
||||
matrixB[matrixB_pos_y] = line;
|
||||
matrixB_pos_y++;
|
||||
}
|
||||
else {
|
||||
delete[] line;
|
||||
}
|
||||
matrixB_pos_x = 0;
|
||||
}
|
||||
|
||||
return matrixB;
|
||||
}
|
||||
|
||||
Lint findDet(Lint** matrixA, const int dimension) {
|
||||
Lint det = 0;
|
||||
if (dimension == 0) {
|
||||
det = 1;
|
||||
}
|
||||
else if (dimension == 1) {
|
||||
det = matrixA[0][0];
|
||||
}
|
||||
else if (dimension == 2) {
|
||||
det = matrixA[0][0] * matrixA[1][1] - matrixA[0][1] * matrixA[1][0];
|
||||
}
|
||||
else {
|
||||
for (int i=0; i<dimension; i++) {
|
||||
// reuse form matrix? pottentially split it up into formMatrixA and formMatrixB?
|
||||
Lint** matrixB = findMinor(matrixA, dimension, i, 0);
|
||||
Lint matrixB_det = findDet(matrixB, dimension-1);
|
||||
Lint term = matrixA[0][i] * matrixB_det;
|
||||
|
||||
if ((i+1)%2 == 0) {
|
||||
term = 0-term;
|
||||
}
|
||||
det = det + term;
|
||||
}
|
||||
}
|
||||
|
||||
return det;
|
||||
}
|
||||
|
||||
matrix formMatrixCofactors(Lint** matrixA, const int dimension) {
|
||||
Lint** matrixB = new Lint*[dimension];
|
||||
|
||||
for (int i=0; i<dimension; i++) {
|
||||
Lint* line = new Lint[dimension];
|
||||
|
||||
int sign = 1;
|
||||
if ((i+1)%2 == 0) {
|
||||
sign = -1;
|
||||
}
|
||||
for (int j=0; j<dimension; j++) {
|
||||
Lint** minor = findMinor(matrixA, dimension, j, i);
|
||||
Lint cofactor = findDet(minor, dimension-1) * sign;
|
||||
sign = -sign;
|
||||
line[j] = cofactor;
|
||||
}
|
||||
matrixB[i] = line;
|
||||
}
|
||||
|
||||
matrix matrix_data; matrix_data.matrix = matrixB;
|
||||
matrix_data.dimension_x = dimension; matrix_data.dimension_y = dimension;
|
||||
return matrix_data;
|
||||
}
|
||||
|
||||
matrix transposeMatrix(Lint** cofactors, const int dimension) {
|
||||
Lint** matrixB = new Lint*[dimension];
|
||||
|
||||
for (int i=0; i<dimension; i++) {
|
||||
Lint* line = new Lint[dimension];
|
||||
for (int j=0; j<dimension; j++) {
|
||||
line[j] = cofactors[j][i];
|
||||
}
|
||||
matrixB[i] = line;
|
||||
}
|
||||
|
||||
matrix matrixB_data; matrixB_data.matrix = matrixB;
|
||||
matrixB_data.dimension_x = dimension; matrixB_data.dimension_y = dimension;
|
||||
return matrixB_data;
|
||||
}
|
||||
|
||||
struct float_matrix{
|
||||
Ldouble** matrix;
|
||||
int dimension_x;
|
||||
int dimension_y;
|
||||
};
|
||||
struct float_matrix_system {
|
||||
matrix A;
|
||||
matrix B;
|
||||
matrix X;
|
||||
};
|
||||
|
||||
float_matrix multiplyConstant(matrix matrixA_data, const int dimension, const Lint det) {
|
||||
Ldouble** matrixB = new Ldouble*[dimension];
|
||||
Lint** matrixA = matrixA_data.matrix;
|
||||
|
||||
for (int i=0; i<dimension; i++) {
|
||||
Ldouble* line = new Ldouble[dimension];
|
||||
for (int j=0; j<dimension; j++) {
|
||||
line[j] = (1.0/det) * matrixA[i][j];
|
||||
}
|
||||
matrixB[i] = line;
|
||||
}
|
||||
float_matrix matrixB_data; matrixB_data.matrix = matrixB;
|
||||
matrixB_data.dimension_x = matrixA_data.dimension_x; matrixB_data.dimension_y = matrixA_data.dimension_y;
|
||||
|
||||
return matrixB_data;
|
||||
}
|
||||
|
||||
float_matrix multiplyMatricies(float_matrix inverseA_data, matrix matrixB_data) {
|
||||
int dimension_x = inverseA_data.dimension_x;
|
||||
int dimension_y = inverseA_data.dimension_y;
|
||||
|
||||
Ldouble** matrixC = new Ldouble*[matrixB_data.dimension_y];
|
||||
Ldouble** inverseA = inverseA_data.matrix;
|
||||
Lint** matrixB = matrixB_data.matrix;
|
||||
|
||||
for (int i=0; i<dimension_y; i++) {
|
||||
Ldouble* line = new Ldouble[0];
|
||||
Ldouble result = 0;
|
||||
for (int j=0; j<dimension_x; j++) {
|
||||
result = result + inverseA[i][j] * matrixB[j][0];
|
||||
}
|
||||
line[0] = result;
|
||||
matrixC[i] = line;
|
||||
}
|
||||
float_matrix matrixC_data; matrixC_data.matrix = matrixC;
|
||||
matrixC_data.dimension_x = matrixB_data.dimension_x; matrixC_data.dimension_y = matrixB_data.dimension_y;
|
||||
|
||||
return matrixC_data;
|
||||
}
|
||||
|
||||
void solve() {
|
||||
cout << "----- Get secrect -----" << endl;
|
||||
inputStruct inputs = getInfo();
|
||||
|
||||
linearEquation* equations = new linearEquation[inputs.required];
|
||||
equations = constructEquations(inputs.required, inputs.shares);
|
||||
|
||||
matrix_system matricies = formMatrix(equations, inputs.required);
|
||||
delete[] equations;
|
||||
Lint det = findDet(matricies.A.matrix, matricies.A.dimension_x);
|
||||
|
||||
matrix cofactors = formMatrixCofactors(matricies.A.matrix, matricies.A.dimension_x);
|
||||
matrix transposition = transposeMatrix(cofactors.matrix, cofactors.dimension_x);
|
||||
|
||||
float_matrix inverseA = multiplyConstant(transposition, transposition.dimension_x, det);
|
||||
float_matrix matrixC = multiplyMatricies(inverseA, matricies.B);
|
||||
|
||||
Lint secret = matrixC.matrix[matrixC.dimension_y-1][0];
|
||||
|
||||
string display;
|
||||
cout << "Type 'show me' to see the secret, anyother input will cancel the process: ";
|
||||
cin.ignore(); getline(cin, display);
|
||||
if (display == "show me") {
|
||||
cout << "The secrect is: " << secret << endl;
|
||||
}
|
||||
else {
|
||||
cout << "Cancelled: clearing memory..."; cout << " done" << endl;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void outputMenu() {
|
||||
cout << "--- Menu ---" << endl;
|
||||
string items[4] = {"Get secret", "Create new secret", "Test", "Exit"};
|
||||
for (int i = 0; i<(sizeof(items)/32); i++) {
|
||||
int opt_num = i+1;
|
||||
if (items[i] == "Exit") {
|
||||
int opt_num = 99;
|
||||
}
|
||||
cout << opt_num << ". " << items[i] << endl;
|
||||
}
|
||||
cout << endl << "select your option by inputting its corresponding letter: ";
|
||||
}
|
||||
|
||||
|
||||
void solveInternal(shareStruct* shares, int required) {
|
||||
inputStruct inputs;
|
||||
inputs.shares = shares;
|
||||
inputs.required = required;
|
||||
|
||||
linearEquation* equations = new linearEquation[inputs.required];
|
||||
equations = constructEquations(inputs.required, inputs.shares);
|
||||
|
||||
matrix_system matricies = formMatrix(equations, inputs.required);
|
||||
delete[] equations;
|
||||
Lint det = findDet(matricies.A.matrix, matricies.A.dimension_x);
|
||||
|
||||
matrix cofactors = formMatrixCofactors(matricies.A.matrix, matricies.A.dimension_x);
|
||||
matrix transposition = transposeMatrix(cofactors.matrix, cofactors.dimension_x);
|
||||
|
||||
float_matrix inverseA = multiplyConstant(transposition, transposition.dimension_x, det);
|
||||
float_matrix matrixC = multiplyMatricies(inverseA, matricies.B);
|
||||
|
||||
Lint secret = matrixC.matrix[matrixC.dimension_y-1][0];
|
||||
cout << "The secrect is: " << secret << endl << endl;
|
||||
}
|
||||
|
||||
void newSecretInternal(const int num_shares, const int num_required) {
|
||||
const Lint prime = genPrime();
|
||||
|
||||
Lint secret = 538;
|
||||
int* poly = genPoly(num_required-1, prime, secret);
|
||||
|
||||
poly = encodeSecret(poly, secret, num_required);
|
||||
|
||||
shareStruct* shares = genShares(num_shares, num_required, poly, prime);
|
||||
outputShares(shares, num_shares);
|
||||
solveInternal(shares, num_required);
|
||||
outputPoly(poly, secret, num_required);
|
||||
}
|
||||
|
||||
void internalTest() {
|
||||
newSecretInternal(8, 6);
|
||||
newSecretInternal(12, 6);
|
||||
newSecretInternal(12, 6);
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
bool exit = false;
|
||||
int selection;
|
||||
while (exit == false) {
|
||||
outputMenu();
|
||||
cin >> selection;
|
||||
cout << endl;
|
||||
if (selection == 1) {
|
||||
solve();
|
||||
}
|
||||
else if (selection == 2) {
|
||||
newSecret();
|
||||
}
|
||||
else if (selection == 3) {
|
||||
internalTest();
|
||||
}
|
||||
else {
|
||||
exit = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
46
versions/001/old.cpp
Normal file
46
versions/001/old.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
# include<iostream>
|
||||
# include<string>
|
||||
# include<random>
|
||||
# include<cmath>
|
||||
using namespace std;
|
||||
|
||||
int genRandInt(int range_start, int range_end) {
|
||||
random_device dev;
|
||||
mt19937 rng(dev());
|
||||
uniform_int_distribution<mt19937::result_type> dist6(range_start, range_end);
|
||||
return dist6(rng);
|
||||
}
|
||||
|
||||
int genPolyPoints(int poly_func) {
|
||||
}
|
||||
|
||||
int genPoly(int degree) {
|
||||
int poly[degree+1];
|
||||
|
||||
for (int i = 0; i < degree+1; i++) {
|
||||
int random_num = genRandInt(1, 99999999999999999);
|
||||
poly[i] = random_num;
|
||||
}
|
||||
|
||||
return poly;
|
||||
}
|
||||
|
||||
void genSecret(string secret, int shares, int required=shares) {
|
||||
int poly_degree = required - 1;
|
||||
int poly_func = genPoly(poly_degree);
|
||||
int points = genPolyPoints(poly_func)
|
||||
}
|
||||
|
||||
void getShares(int num_shares) {
|
||||
string shares[num_shares];
|
||||
cout << "Enter share secret:\n"
|
||||
cin >> share;
|
||||
cout << "\n"
|
||||
}
|
||||
|
||||
void encodeSecret(string secret) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user