c++ math linear-algebra computer-algebra-systems finite-field

c++ - Biblioteca exacta de álgebra lineal de campo finito grande(por ejemplo, GF(2 ^ 128)/GF(2 ^ 256))



math linear-algebra (1)

General

Estoy buscando una biblioteca que sea capaz de hacer cálculos exactos en campos finitos grandes como GF (2 128 ) / 𝔽 2 128 y GF (2 256 ) / 𝔽 2 256 . Enumeré las características que necesito y las características que serían geniales a continuación. Obviamente, la biblioteca debería ser lo más rápida posible :-). Ah, ya que no soy un maestro de C ++ (y probablemente la mayoría de las bibliotecas son C ++), el código de ejemplo de, por ejemplo, genera un elemento aleatorio / una constante y lo multiplica a su inverso multiplicativo

Características imprescindibles

  • Adición de elementos de campo
  • Multiplicación de elemento de campo.
  • Encuentra el inverso multiplicativo de un elemento de campo

Es bueno tener características

  • Soporte de matrices / vectores
  • Soporte de elementos aleatorios

Bibliotecas que ya he visto que probablemente no funcionen

  • FFLAS/FFPACK , parece no funcionar con campos finitos tan grandes
  • Givaro , parece no trabajar en campos finitos tan grandes

Bibliotecas que ya vi que podrían funcionar (pero no pude usar)

  • NTL , no pude invertir un elemento, pero realmente debería funcionar ya que SAGE parece usar esta biblioteca cuando define GF (2 ^ 256) y allí se puede invertir un elemento utilizando x^(-1)
  • PARI/GP , no pude encontrar todo lo que necesito en la documentación, pero la documentación de SAGE dice que debería funcionar

Otras notas

  • Estoy escribiendo un programa de Haskell e interactuaré con esa biblioteca más adelante, así que una interfaz de Haskell más fácil es mejor :-)

La biblioteca NTL parece funcionar, usando este código (lo siento, no puedo programar en C ++)

#include <NTL/GF2E.h> #include <NTL/GF2EX.h> #include <NTL/GF2X.h> #include <NTL/GF2XFactoring.h> NTL_CLIENT int main() { GF2X P = BuildIrred_GF2X(256); GF2E::init(P); GF2E zero = GF2E::zero(); GF2E one; GF2E r = random_GF2E(); GF2E r2 = random_GF2E(); conv(one, 1L); cout << "Cardinality: " << GF2E::cardinality() << endl; cout << "ZERO: " << zero << " --> " << IsZero(zero) << endl; cout << "ONE: " << one << " --> " << IsOne(one) << endl; cout << "1/r: " << 1/r << ", r * (1/r): " << (r * (1/r)) << endl; cout << "1/r2: " << 1/r2 << ", r2 * (1/r2): " << (r2 * (1/r2)) << endl; }

Parece funcionar, prueba (salida de este programa):

Cardinality: 115792089237316195423570985008687907853269984665640564039457584007913129639936 ZERO: [] --> 1 ONE: [1] --> 1 1/r: [0 1 0 1 1 0 1 1 1 0 1 1 1 0 0 1 1 0 1 1 1 0 1 1 0 0 0 0 0 1 0 1 0 1 1 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0 1 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 0 1 1 0 0 1 1 0 0 1 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 1 0 1 0 0 1 1 0 1 1 0 1 1 1 1 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 1 0 1], r * (1/r): [1] 1/r2: [1 0 1 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 0 1 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 0 0 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 1 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 1 0 1 1 1 0 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 1 0 1 0 0 1 0 1 0 0 1 1], r2 * (1/r2): [1]

Incluso la inversión parece funcionar (desplácese tan correctamente como sea posible en el ejemplo de salida anterior) :-)