/**
 * \file ffi_vec.h
 * \brief Interface for vectors over finite field elements
 */

#ifndef FFI_VEC_H
#define FFI_VEC_H

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


void ffi_vec_set(ffi_vec& o, const ffi_vec v, unsigned int size);
void ffi_vec_set_zero(ffi_vec& o, unsigned int size);
void ffi_vec_set_random_using_rng(ffi_vec& o, unsigned int size);
void ffi_vec_set_random_full_rank_with_one_using_rng(ffi_vec& o, unsigned int size);
void ffi_vec_set_random_full_rank_using_rng(ffi_vec& o, unsigned int size);
void ffi_vec_set_random_from_support_using_rng(ffi_vec& o, unsigned int size, const ffi_vec& support, unsigned int rank);
void ffi_vec_set_random_using_shake256(ffi_vec& o, unsigned int size, unsigned char* seed, unsigned int seed_size);
void ffi_vec_set_random_full_rank_using_shake256(ffi_vec& o, unsigned int size, unsigned char* seed, unsigned int seed_size);

void ffi_vec_set_random_full_rank_with_one_using_seedexpander(ffi_vec& o, unsigned int size, AES_XOF_struct* ctx);
void ffi_vec_set_random_from_support_using_seedexpander(ffi_vec& o, unsigned int size, const ffi_vec& support, unsigned int rank, AES_XOF_struct* ctx);
void ffi_vec_set_random_using_seedexpander(ffi_vec& o, unsigned int size, AES_XOF_struct* ctx);

void ffi_vec_add(ffi_vec& o, const ffi_vec v1, const ffi_vec v2, unsigned int size);
void ffi_vec_sub(ffi_vec& o, const ffi_vec v1, const ffi_vec v2, unsigned int size);
void ffi_vec_mul(ffi_vec o, const ffi_vec v1, const ffi_vec v2, unsigned int size);

void ffi_vec_inner_product(ffi_elt& o, const ffi_vec v1, const ffi_vec v2);
void ffi_vec_scalar_mul(ffi_vec& o, const ffi_vec v, const ffi_elt e, unsigned int size);
void ffi_vec_neg(ffi_vec& o, const ffi_vec v, unsigned int size);

unsigned int ffi_vec_gauss(ffi_vec o, unsigned int size);
unsigned int ffi_vec_get_rank(ffi_vec v, unsigned int size);

void ffi_vec_to_string(unsigned char* str, const ffi_vec& o, unsigned int n);
void ffi_vec_from_string(const unsigned char* str, ffi_vec& o, unsigned int n);

int ffi_vec_is_equal_to(const ffi_vec& o1, const ffi_vec& o2, long n);

#endif
