text: /*
   *  Copyright (C) 2017 - This file is part of libecc project
   *
   *  Authors:
   *      Ryad BENADJILA <ryadbenadjila@gmail.com>
   *      Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
   *      Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
   *
   *  Contributors:
   *      Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
   *      Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
   *
   *  This software is licensed under a dual BSD and GPL v2 license.
   *  See LICENSE file at the root folder of the project.
   */
  #ifndef __NN_H__
  #define __NN_H__
  
  #include "../words/words.h"
  #include "nn_config.h"
  #include "../utils/utils.h"
  
  /*
   * For a given amount of bytes (resp. bits), return the minimum number
   * of words required to store that amount of bytes (respectively bits).
   */
  #define BYTE_LEN_WORDS(nbytes) (((nbytes) + WORD_BYTES - 1) / WORD_BYTES)
  #define BIT_LEN_WORDS(nbits) (((nbits) + WORD_BITS - 1) / WORD_BITS)
  
  /*
   * For a given amount of bytes (resp. bits), return the first number of
   * bytes (resp. bits) equal or above to that value which is a multiple
   * of word bytes.
   */
  #define BYTE_LEN_CEIL(nbytes) (BYTE_LEN_WORDS(nbytes) * WORD_BYTES)
  #define BIT_LEN_CEIL(nbits) (BIT_LEN_WORDS(nbits) * WORD_BITS)
  
  /*
   * Our nn type contains an array of words, which is of a fixed given storage
   * size defined in nn_lib_ecc_config.h.
   *
   * Each word in this array is in local endianness whereas the words
   * in the array are ordered in a little endian way with regard to their
   * indices. That is: the word at index 0 in the array contains the least
   * significant word of the nn.
   *
   * Except explicitly specified (some functions may provide automatic
   * initialization of output params), initialization is usually required
   * before nn can be used.
   *
   * After initialization, the 'wlen' attribute provides at each moment
   * an upper bound on the position of last non-zero word in the array.
   * All words after that point are always guaranteed to be 0 after any
   * manipulation by a function of this module.
   * Functions use this assumption to optimize operations by avoiding to
   * process leading zeros.
   * Nevertheless, some functions still access words past the 'wlen' index
   * and return correct results only if these words are 0.
   *
   * Note that functions with parameters not explicitly marked as const may
   * modify the value of the 'wlen' attribute if they see fit.
   * And indeed most of them set the output 'wlen' attribute to the maximal
   * possible value given the inputs 'wlen' attributes.
   * The most notable exceptions are the logical functions whose result
   * depends on the preset value of the output 'wlen' attribute.
   */
  typedef struct {
  	word_t val[BIT_LEN_WORDS(NN_MAX_BIT_LEN)];
  	word_t magic;
  	u8 wlen;
  } nn;
  
  typedef nn *nn_t;
  typedef const nn *nn_src_t;
  
  void nn_check_initialized(nn_src_t A);
  int nn_is_initialized(nn_src_t A);
  void nn_zero(nn_t A);
  void nn_one(nn_t A);
  void nn_set_word_value(nn_t A, word_t val);
  void nn_uninit(nn_t A);
  void nn_init(nn_t A, u16 len);
  void nn_cnd_swap(int cnd, nn_t in1, nn_t in2);
  void nn_set_wlen(nn_t A, u8 new_wlen);
  int nn_iszero(nn_src_t A);
  int nn_isone(nn_src_t A);
  int nn_isodd(nn_src_t A);
  int nn_cmp_word(nn_src_t in, word_t w);
  int nn_cmp(nn_src_t A, nn_src_t B);
  void nn_copy(nn_t dst_nn, nn_src_t src_nn);
  void nn_normalize(nn_t in1);
  void nn_init_from_buf(nn_t out_nn, const u8 *buf, u16 buflen);
  void nn_export_to_buf(u8 *buf, u16 buflen, nn_src_t in_nn);
  
  #endif /* __NN_H__ */
  