packages feed

KpqC-0.1.0: cbits/third_party/AIMer/field_common.c

// SPDX-License-Identifier: MIT

#include "field.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

void gf_to_bytes(uint8_t *out, const gf in)
{
  for (size_t i = 0; i < AIM3_NUM_WORDS_FIELD; i++)
  {
    uint64_t u = in[i];
    for (size_t j = 0; j < 8; j++)
    {
      out[8 * i + j] = (uint8_t)u;
      u >>= 8;
    }
  }
}

void gf_from_bytes(gf out, const uint8_t *in)
{
  for (size_t i = 0; i < AIM3_NUM_WORDS_FIELD; i++)
  {
    uint64_t u = 0;
    for (int j = 7; j >= 0; j--)
    {
      u = (u << 8) | in[8 * i + j];
    }
    out[i] = u;
  }
}

void gf_set0(gf a)
{
  for (size_t i = 0; i < AIM3_NUM_WORDS_FIELD; i++)
  {
    a[i] = 0;
  }
}

bool gf_is0(const gf a)
{
  uint64_t result = 0;
  for (size_t i = 0; i < AIM3_NUM_WORDS_FIELD; i++)
  {
    result |= a[i];
  }
  return result == 0;
}

void gf_copy(gf out, const gf in)
{
  for (size_t i = 0; i < AIM3_NUM_WORDS_FIELD; i++)
  {
    out[i] = in[i];
  }
}

void gf_add(gf c, const gf a, const gf b)
{
  for (size_t i = 0; i < AIM3_NUM_WORDS_FIELD; i++)
  {
    c[i] = a[i] ^ b[i];
  }
}

void gf_inv(gf c, const gf a)
{
  gf temp;

  gf_copy(temp, a);
  gf_set0(c);
  c[0] = 1;

  // c = a^{2^n - 2} = prod_{i = 1}^{n-1} a^{2^i}
  for (size_t i = 1; i < AIM3_NUM_BITS_FIELD; i++)
  {
    gf_sqr(temp, temp); // temp = a^{2^i}
    gf_mul(c, c, temp);
  }
}

// c += a * b
void gf_mul_add(gf c, const gf a, const gf b)
{
  gf r;
  gf_mul(r, a, b);
  gf_add(c, c, r);
}

// c += sum_i a[i] * b[i]
void gf_mat_vec_mul_add(gf c, const gf a, const gf b[AIM3_NUM_BITS_FIELD])
{
  gf r;
  gf_mat_vec_mul(r, a, b);
  gf_add(c, c, r);
}