/**
 * \file ffi_math
 * \brief Interface for matrixs over finite field elements
 */

#ifndef FFI_MAT_H
#define FFI_MAT_H

#include "rng.h"
#include "fips202.h"
#include "ffi.h"


void ffi_mat_set(ffi_mat& o, const ffi_mat v, unsigned int n, unsigned int m);
void ffi_mat_set_zero(ffi_mat& o, unsigned int n, unsigned int m);
void ffi_mat_add(ffi_mat& o, const ffi_mat m1, const ffi_mat m2);
void ffi_mat_sub(ffi_mat& o, const ffi_mat m1, const ffi_mat m2);
void ffi_mat_mul(ffi_mat& o, const ffi_mat m1, const ffi_mat m2);
void ffi_mat_mul(ffi_vec& o, const ffi_mat m1, const ffi_vec v2);
void ffi_mat_mul(ffi_vec& o, const ffi_vec v1, const ffi_mat m2);
void ffi_mat_negate(ffi_mat& o, const ffi_mat m);
void ffi_mat_transpose(ffi_mat& o, const ffi_mat m);
unsigned int ffi_mat_is_zero(ffi_mat& o);
int ffi_mat_is_equal_to(const ffi_mat& m1, const ffi_mat& m2, long n, long m);

void ffi_mat_set_random_using_rng(ffi_mat& o, long n, long m);
void ffi_mat_set_random_from_support_using_rng(ffi_mat& o, long n, long m, const ffi_vec& support, unsigned int rank);
void ffi_mat_set_random_using_shake256(ffi_mat& o, long n, long m, unsigned char* seed, unsigned int size);

void ffi_mat_to_string(unsigned char* str, const ffi_mat& o, unsigned int n, unsigned int m);
void ffi_mat_from_string(const unsigned char* str, ffi_mat& o, unsigned int n, unsigned int m);

#endif
