Updated Matrix class
- Implemented determinant function - Added more function overloads for convenience - Fixed some typing issues - Added semi-proper function chaining Changed how Vectors handle recieving arrays Fixed small issue with namespaces not being used Started structuring Galois class
This commit is contained in:
parent
fa54698850
commit
521cbe335f
@ -1,7 +1,41 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "BigInteger.h"
|
#include "BigInteger.h"
|
||||||
|
#include "Matrix.h"
|
||||||
|
|
||||||
|
using namespace CryptoCPP::Math;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
// Create a 2x2 matrix
|
||||||
|
// |1 2|
|
||||||
|
// |3 4|
|
||||||
|
Matrix * m = new Matrix(2, 2);
|
||||||
|
m->set_row
|
||||||
|
(new Vector(2, new long long[2]{ 1, 2 }), 0) WITH
|
||||||
|
(new Vector(2, new long long[2]{ 3, 4 }), 1);
|
||||||
|
|
||||||
|
// Create a 2x2 matrix
|
||||||
|
// |5 6|
|
||||||
|
// |7 8|
|
||||||
|
Matrix * m1 = new Matrix(2, 2);
|
||||||
|
m1->set_row
|
||||||
|
(new Vector(2, new long long[2]{ 5, 6 }), 0) WITH
|
||||||
|
(new Vector(2, new long long[2]{ 7, 8 }), 1);
|
||||||
|
|
||||||
|
// Multiply matrices
|
||||||
|
Matrix * res = (*m) * m1;
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "Matrix 'm':" << std::endl;
|
||||||
|
for (size_t t = 0; t < 4; ++t) std::cout << m->at(t, true) << ((t % 2) ? '\n' : ' ');
|
||||||
|
|
||||||
|
std::cout << "\nMatrix 'm1':" << std::endl;
|
||||||
|
for (size_t t = 0; t < 4; ++t) std::cout << m1->at(t, true) << ((t % 2) ? '\n' : ' ');
|
||||||
|
|
||||||
|
// Print result
|
||||||
|
std::cout << "\nMatrix 'res':" << std::endl;
|
||||||
|
for (size_t t = 0; t < 4; ++t) std::cout << res->at(t, true) << ((t%2) ? '\n' : ' ');
|
||||||
|
std::cout << "\ndet(m) = " << m->det() << "\ndet(m1) = " << m->det() << "\ndet(res) = " << res->det() << std::endl;
|
||||||
|
std::cin.ignore();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -11,11 +11,19 @@ namespace CryptoCPP {
|
|||||||
Galois * sub(const Galois * value) const; // Subtract
|
Galois * sub(const Galois * value) const; // Subtract
|
||||||
Galois * mul(const Galois * value) const; // Multiply
|
Galois * mul(const Galois * value) const; // Multiply
|
||||||
Galois * inv(const Galois * value) const; // Inverse multiply
|
Galois * inv(const Galois * value) const; // Inverse multiply
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t characteristic, exponent, irreducible;
|
size_t characteristic, exponent, irreducible;
|
||||||
|
|
||||||
// Reduce the value of this galois to one that fits the field parameters
|
// Reduce the value of this galois to one that fits the field parameters
|
||||||
void reduce();
|
void reduce();
|
||||||
|
|
||||||
|
// Self-mutable operations
|
||||||
|
void iadd(const Galois * value);
|
||||||
|
void isub(const Galois * value);
|
||||||
|
void imul(const Galois * value);
|
||||||
|
void iinv(const Galois * value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,9 +9,8 @@ namespace CryptoCPP {
|
|||||||
memset(valueSet, 0, count * sizeof(long long));
|
memset(valueSet, 0, count * sizeof(long long));
|
||||||
}
|
}
|
||||||
|
|
||||||
MATRIX_API Vector::Vector(size_t count, long long * values) : count(count), valueSet(new long long[count])
|
MATRIX_API Vector::Vector(size_t count, long long * values) : count(count), valueSet(values)
|
||||||
{
|
{
|
||||||
memcpy(valueSet, values, count * sizeof(long long));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MATRIX_API Vector::~Vector()
|
MATRIX_API Vector::~Vector()
|
||||||
@ -34,17 +33,22 @@ namespace CryptoCPP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DelegatingFPTR::DelegatingFPTR(Delegate impl, Matrix* context)
|
DelegatingFPTR::DelegatingFPTR(Delegate impl, PDelegate point, Matrix* context)
|
||||||
{
|
{
|
||||||
this->impl = impl;
|
this->impl = impl;
|
||||||
|
this->point = point;
|
||||||
this->context = context;
|
this->context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
MATRIX_API const DelegatingFPTR* DelegatingFPTR::operator()(const Vector & input, size_t index)
|
MATRIX_API const DelegatingFPTR* DelegatingFPTR::operator()(const Vector & input, size_t index) const
|
||||||
{
|
{
|
||||||
return (context->*impl)(input, index);
|
return (context->*impl)(input, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* DelegatingFPTR::operator()(Vector * input, size_t index) const
|
||||||
|
{
|
||||||
|
return (context->*point)(input, index);
|
||||||
|
}
|
||||||
|
|
||||||
Matrix::Matrix(size_t height, size_t width) : columns(new Vector*[width]), width(width), height(height)
|
Matrix::Matrix(size_t height, size_t width) : columns(new Vector*[width]), width(width), height(height)
|
||||||
{
|
{
|
||||||
@ -66,26 +70,62 @@ namespace CryptoCPP {
|
|||||||
for (size_t t = 0; t < width; ++t)
|
for (size_t t = 0; t < width; ++t)
|
||||||
delete columns[t];
|
delete columns[t];
|
||||||
delete[] columns;
|
delete[] columns;
|
||||||
// TODO: Add other deletions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MATRIX_API const DelegatingFPTR* Matrix::set_row(const Vector & row, size_t rowidx)
|
MATRIX_API const DelegatingFPTR* Matrix::set_row(const Vector & row, size_t rowidx)
|
||||||
{
|
{
|
||||||
if (rowidx < 0 || rowidx >= height) throw new std::exception("Index out of bounds");
|
return set_row_r(row, rowidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* Matrix::set_col(const Vector & col, size_t colidx)
|
||||||
|
{
|
||||||
|
return set_col_r(col, colidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* Matrix::set_row(Vector * row, size_t rowidx)
|
||||||
|
{
|
||||||
|
return set_row_p(row, rowidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* Matrix::set_col(Vector * col, size_t colidx)
|
||||||
|
{
|
||||||
|
return set_col_p(col, colidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* Matrix::set_row_r(const Vector & row, size_t rowidx)
|
||||||
|
{
|
||||||
|
if (rowidx >= height) throw new std::exception("Row index out of bounds");
|
||||||
size_t min = row.count < width ? row.count : width;
|
size_t min = row.count < width ? row.count : width;
|
||||||
for (size_t t = 0; t < min; ++t) columns[t]->at(rowidx, row.at(t));
|
for (size_t t = 0; t < min; ++t) columns[t]->at(rowidx, row.at(t));
|
||||||
return ar;
|
return ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
MATRIX_API const DelegatingFPTR* Matrix::set_col(const Vector & col, size_t colidx)
|
MATRIX_API const DelegatingFPTR* Matrix::set_col_r(const Vector & col, size_t colidx)
|
||||||
{
|
{
|
||||||
|
if (colidx >= width) throw new std::exception("Column index out of bounds");
|
||||||
|
size_t min = col.count < height ? col.count : height;
|
||||||
|
for (size_t t = 0; t < height; ++t) columns[colidx]->at(t, col.at(t));
|
||||||
return ac;
|
return ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* Matrix::set_row_p(Vector * row, size_t rowidx)
|
||||||
|
{
|
||||||
|
const DelegatingFPTR * chain = set_row((const Vector&) *row, rowidx);
|
||||||
|
delete row;
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* Matrix::set_col_p(Vector * col, size_t colidx)
|
||||||
|
{
|
||||||
|
const DelegatingFPTR * chain = set_col((const Vector&) *col, colidx);
|
||||||
|
delete col;
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
|
||||||
MATRIX_API long long Matrix::set_at(size_t col, size_t row, long long value)
|
MATRIX_API long long Matrix::set_at(size_t col, size_t row, long long value)
|
||||||
{
|
{
|
||||||
if (col < 0 || col >= width || row < 0 || row >= height) throw new std::exception("Index out of bounds");
|
if (col < 0 || col >= width || row < 0 || row >= height) throw new std::exception("Index out of bounds");
|
||||||
columns[col]->at(row, value);
|
return columns[col]->at(row, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
MATRIX_API long long Matrix::set_at(size_t index, bool rowMajor, long long value)
|
MATRIX_API long long Matrix::set_at(size_t index, bool rowMajor, long long value)
|
||||||
@ -126,9 +166,9 @@ namespace CryptoCPP {
|
|||||||
{
|
{
|
||||||
if (factor.height != width) throw new std::exception("Mismatched dimensions");
|
if (factor.height != width) throw new std::exception("Mismatched dimensions");
|
||||||
Matrix* result = new Matrix(height, factor.width);
|
Matrix* result = new Matrix(height, factor.width);
|
||||||
for (int i = 0; i < factor.width; ++i)
|
for (size_t i = 0; i < factor.width; ++i)
|
||||||
for (int j = 0; j < height; ++j)
|
for (size_t j = 0; j < height; ++j)
|
||||||
for (int k = 0; k < width; ++k)
|
for (size_t k = 0; k < width; ++k)
|
||||||
result->columns[i]->at(j, result->columns[i]->at(j) + (factor.columns[i]->at(k) * columns[k]->at(j)));
|
result->columns[i]->at(j, result->columns[i]->at(j) + (factor.columns[i]->at(k) * columns[k]->at(j)));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -142,12 +182,29 @@ namespace CryptoCPP {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MATRIX_API Matrix* Matrix::operator*(const Matrix & factor) const
|
||||||
|
{
|
||||||
|
return mul(factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
MATRIX_API Matrix* Matrix::operator*(const Matrix * factor) const
|
||||||
|
{
|
||||||
|
return mul(*factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
MATRIX_API Matrix* Matrix::operator*(long long scalar) const
|
||||||
|
{
|
||||||
|
return mul(scalar);
|
||||||
|
}
|
||||||
|
|
||||||
MATRIX_API Matrix * Matrix::minor(size_t row, size_t col) const
|
MATRIX_API Matrix * Matrix::minor(size_t row, size_t col) const
|
||||||
{
|
{
|
||||||
|
if (height == 0 || width == 0) return new Matrix(0, 0);
|
||||||
|
if (row >= height || col >= width) throw new std::exception("Index out of bounds");
|
||||||
Matrix* result = new Matrix(height - 1, width - 1);
|
Matrix* result = new Matrix(height - 1, width - 1);
|
||||||
for (int i = 0; i < width; ++i) {
|
for (size_t i = 0; i < width; ++i) {
|
||||||
if (i == col) continue;
|
if (i == col) continue;
|
||||||
for (int j = 0; j < height; ++j) {
|
for (size_t j = 0; j < height; ++j) {
|
||||||
if (j == row) continue;
|
if (j == row) continue;
|
||||||
result->columns[i + ((i > col) ? -1 : 0)]->at(j + ((j > row) ? -1 : 0), columns[i]->at(j));
|
result->columns[i + ((i > col) ? -1 : 0)]->at(j + ((j > row) ? -1 : 0), columns[i]->at(j));
|
||||||
}
|
}
|
||||||
@ -157,7 +214,21 @@ namespace CryptoCPP {
|
|||||||
|
|
||||||
MATRIX_API long long Matrix::det() const
|
MATRIX_API long long Matrix::det() const
|
||||||
{
|
{
|
||||||
return 0;
|
// Matrix safety checks
|
||||||
|
if (height != width) throw new std::exception("Matrix must be square to compute the determinant");
|
||||||
|
if (!height) throw new std::exception("Zero-matrix does not have a determinant");
|
||||||
|
|
||||||
|
// Compute determinant for 1x1 matrix
|
||||||
|
if (height == 1) return columns[0]->at(0);
|
||||||
|
|
||||||
|
// Compute determinant for higher-order matrices
|
||||||
|
long long result = 0;
|
||||||
|
for (size_t t = 0; t < width; ++t) {
|
||||||
|
Matrix * smaller = minor(0, t); // Compute minor
|
||||||
|
result += smaller->det() * columns[t]->at(0) * (long long)((t % 2) ? -1 : 1); // Compute partial determinant for the given minor
|
||||||
|
delete smaller; // Delete allocated minor
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#define MATRIX_API __declspec(dllimport)
|
#define MATRIX_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define WITH ->operator()
|
||||||
|
|
||||||
namespace CryptoCPP {
|
namespace CryptoCPP {
|
||||||
namespace Math {
|
namespace Math {
|
||||||
@ -29,24 +30,26 @@ namespace CryptoCPP {
|
|||||||
long long * const valueSet;
|
long long * const valueSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class DelegatingFPTR;
|
class DelegatingFPTR;
|
||||||
typedef const DelegatingFPTR*(Matrix::*Delegate)(const Vector & input, size_t at);
|
typedef const DelegatingFPTR*(Matrix::*Delegate)(const Vector & input, size_t at);
|
||||||
|
typedef const DelegatingFPTR*(Matrix::*PDelegate)(const Vector * input, size_t at);
|
||||||
|
|
||||||
class DelegatingFPTR {
|
class DelegatingFPTR {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DelegatingFPTR(Delegate impl, Matrix* context);
|
DelegatingFPTR(Delegate impl, PDelegate point, Matrix* context);
|
||||||
|
|
||||||
MATRIX_API const DelegatingFPTR* operator()(const Vector & input, size_t index);
|
MATRIX_API const DelegatingFPTR* operator()(const Vector & input, size_t index) const;
|
||||||
|
MATRIX_API const DelegatingFPTR* operator()(Vector * input, size_t index) const;
|
||||||
protected:
|
protected:
|
||||||
Delegate impl;
|
Delegate impl;
|
||||||
|
PDelegate point;
|
||||||
Matrix* context;
|
Matrix* context;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Matrix
|
class Matrix
|
||||||
{
|
{
|
||||||
friend class Vector;
|
|
||||||
friend class DelegatingFPTR;
|
|
||||||
public:
|
public:
|
||||||
MATRIX_API Matrix(size_t height, size_t width);
|
MATRIX_API Matrix(size_t height, size_t width);
|
||||||
MATRIX_API Matrix(const Matrix & copy);
|
MATRIX_API Matrix(const Matrix & copy);
|
||||||
@ -54,6 +57,13 @@ namespace CryptoCPP {
|
|||||||
|
|
||||||
MATRIX_API const DelegatingFPTR* set_row(const Vector & row, size_t rowidx);
|
MATRIX_API const DelegatingFPTR* set_row(const Vector & row, size_t rowidx);
|
||||||
MATRIX_API const DelegatingFPTR* set_col(const Vector & col, size_t colidx);
|
MATRIX_API const DelegatingFPTR* set_col(const Vector & col, size_t colidx);
|
||||||
|
MATRIX_API const DelegatingFPTR* set_row(Vector * row, size_t rowidx);
|
||||||
|
MATRIX_API const DelegatingFPTR* set_col(Vector * col, size_t colidx);
|
||||||
|
|
||||||
|
MATRIX_API const DelegatingFPTR* set_row_r(const Vector & row, size_t rowidx);
|
||||||
|
MATRIX_API const DelegatingFPTR* set_col_r(const Vector & col, size_t colidx);
|
||||||
|
MATRIX_API const DelegatingFPTR* set_row_p(Vector * row, size_t rowidx);
|
||||||
|
MATRIX_API const DelegatingFPTR* set_col_p(Vector * col, size_t colidx);
|
||||||
MATRIX_API long long set_at(size_t col, size_t row, long long value);
|
MATRIX_API long long set_at(size_t col, size_t row, long long value);
|
||||||
MATRIX_API long long set_at(size_t index, bool rowMajor, long long value);
|
MATRIX_API long long set_at(size_t index, bool rowMajor, long long value);
|
||||||
|
|
||||||
@ -65,12 +75,16 @@ namespace CryptoCPP {
|
|||||||
MATRIX_API Matrix* mul(const Matrix & factor) const;
|
MATRIX_API Matrix* mul(const Matrix & factor) const;
|
||||||
MATRIX_API Matrix* mul(long long scalar) const;
|
MATRIX_API Matrix* mul(long long scalar) const;
|
||||||
|
|
||||||
|
MATRIX_API Matrix* operator*(const Matrix & factor) const;
|
||||||
|
MATRIX_API Matrix* operator*(const Matrix * factor) const;
|
||||||
|
MATRIX_API Matrix* operator*(long long scalar) const;
|
||||||
|
|
||||||
MATRIX_API Matrix* minor(size_t row, size_t col) const;
|
MATRIX_API Matrix* minor(size_t row, size_t col) const;
|
||||||
MATRIX_API long long det() const;
|
MATRIX_API long long det() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const DelegatingFPTR* ar = new DelegatingFPTR(add_row, this);
|
const DelegatingFPTR* ar = new DelegatingFPTR((Delegate)&Matrix::set_row_r, (PDelegate)&Matrix::set_row_p, this);
|
||||||
const DelegatingFPTR* ac = new DelegatingFPTR(add_col, this);
|
const DelegatingFPTR* ac = new DelegatingFPTR((Delegate)&Matrix::set_col_r, (PDelegate)&Matrix::set_col_p, this);
|
||||||
Vector * * const columns;
|
Vector * * const columns;
|
||||||
const size_t height;
|
const size_t height;
|
||||||
const size_t width;
|
const size_t width;
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
namespace CryptoCPP {
|
namespace CryptoCPP {
|
||||||
namespace Primes {
|
namespace Primes {
|
||||||
bool fermat_prime_test(const BigInteger & value, size_t certainty);
|
bool fermat_prime_test(const Math::BigInteger & value, size_t certainty);
|
||||||
bool miller_rabin_prime_test(const BigInteger & value, size_t certainty);
|
bool miller_rabin_prime_test(const Math::BigInteger & value, size_t certainty);
|
||||||
|
|
||||||
BigInteger * generate_prime(size_t byteCount, size_t certainty);
|
Math::BigInteger * generate_prime(size_t byteCount, size_t certainty);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user