' ***************************************************************************************
'Subject: Basic library include file for polynomial arithmetic modulo p.
' (version exclusively for characteristic 2 in packet PolMods.zip)
'Author : Sjoerd.J.Schaper
'Date : 11-01-2012
'Code : FreeBasic 1.06.0 (QuickBasic 7.1 adaptation in packet PolMods.zip)
'
' ***************************************************************************************
CONST nmx = 256, pmx = 27 ' max.degree, primes
CONST LB = 15, MB = &H8000& ' bigint base
'
' ***************************************************************************************
TYPE Poly FIELD = 1 ' univariate polynomial:
n AS SHORT ' degree and
c(nmx) AS LONG ' coefficients
END TYPE
TYPE Bigi FIELD = 1 ' big integer:
l AS SHORT ' length,
s AS SHORT ' sign and
d(nmx) AS SHORT ' base 2^ 15 digits
END TYPE
DIM SHARED Modulus AS SHORT ' field characteristic < 32768
'
' ***************************************************************************************
' Initialization and assignment
' ***************************************************************************************
DECLARE FUNCTION Setchar (ByVal p AS SHORT) AS SHORT
'Set prime field characteristic, returns 0 if composite(p)
DECLARE SUB Letc (ByRef f AS Poly, ByVal c AS SHORT)
'Set f to constant c
DECLARE SUB Letm (ByRef f AS Poly, ByVal c AS SHORT)
'Set f to monomial X + c
DECLARE SUB Rndp (ByRef f AS Poly, ByVal n AS SHORT, ByVal m AS SHORT)
'f:= random monic polynomial of degree n with m non-zero coefficients
DECLARE SUB Leti (ByRef a AS Bigi, ByVal b AS LONG)
'Let bigint a = b
'
' ***************************************************************************************
' In- and output
' ***************************************************************************************
DECLARE FUNCTION Parsp (ByRef f AS Poly, ByVal g AS ZSTRING PTR) AS SHORT
'Parse input polynomial, set modulus to input fractions
DECLARE SUB Prntp (ByRef f AS Poly, ByRef g AS STRING)
'Pretty print polynomial with prefix g
DECLARE SUB Readp (ByRef f AS Poly, ByVal n AS SHORT)
'Input coefficient vector f.c[n..0]
DECLARE FUNCTION CRTfile (ByVal p AS SHORT) AS SHORT
'Open an inputfile for LargeInt-module CRTtrans.bas
'set p = number of CRT-primes (<= pmx), p = 0 to close
DECLARE SUB CRTprnt (f() AS Poly, ByVal sw AS SHORT, ByVal g AS ZSTRING PTR)
'Print polynomial array f() to open file #Tfile.
'Set sw = 0 for integral f, sw = 1 for rational f
'with denominators cleared, sw = 2 for printing fractions.
'Set sw + 4 to divide out content(f), g is a comment string.
DECLARE SUB CRTchar (ByVal p AS SHORT)
'Fast field characteristic, without primality test
'
' ***************************************************************************************
' Polynomial arithmetic functions
' ***************************************************************************************
DECLARE SUB Addp (ByRef f AS Poly, ByRef g AS Poly)
'Polynomial f:= f + g
DECLARE SUB Divdp (ByRef f AS Poly, ByRef g AS Poly, ByRef q AS Poly)
'Division f = g * q + r; f:= r, q:= f / g
DECLARE SUB Multp (ByRef f AS Poly, ByRef g AS Poly)
'f:= f * g
DECLARE SUB Squp (ByRef f AS Poly)
'f:= f ^ 2
DECLARE SUB Subtp (ByRef f AS Poly, ByRef g AS Poly)
'f:= f - g
DECLARE SUB Shlp (ByRef f AS Poly, ByVal k AS SHORT)
'f:= f * X^ k
DECLARE SUB Shrp (ByRef f AS Poly, ByVal k AS SHORT)
'f:= f / X^ k
'
' ***************************************************************************************
' Modulo-polynomial functions
' ***************************************************************************************
DECLARE SUB Invp (ByRef f AS Poly, ByRef g AS Poly, ByRef d AS Poly)
'f:= f^ -1 Mod g, g:= g / gcd(f, g), d:= gcd(f, g)
DECLARE SUB Modmltp (ByRef f AS Poly, ByRef g AS Poly, ByRef h AS Poly)
'Polynomial f:= f * g Mod h
DECLARE SUB Modpwrp (ByRef f AS Poly, ByRef k AS Bigi, ByRef g AS Poly)
'f:= f^ bigint(k) Mod g, set g = 0 to skip reduction
'
' ***************************************************************************************
' Checks
' ***************************************************************************************
DECLARE FUNCTION Ispc (ByRef f AS Poly, ByVal c AS SHORT) AS SHORT
'Is f = constant c ?
DECLARE FUNCTION Ispm (ByRef f AS Poly, ByVal c AS SHORT) AS SHORT
'Is f = monomial X + c ?
DECLARE FUNCTION Isirrd (ByRef f AS Poly) AS SHORT
'Is f irreducible ?
'
' ***************************************************************************************
' Assorted functions
' ***************************************************************************************
DECLARE SUB Bezoup (ByRef f AS Poly, ByRef g AS Poly, ByRef d AS Poly)
'Solution of the Diophantine equation fa + gb = gcd(f, g).
'Returns a in f, b in g, and gcd(f, g) in d
DECLARE SUB Deriv (ByRef f AS Poly, ByRef g AS Poly)
'g:= derivative f'
DECLARE FUNCTION Disc (ByRef f AS Poly) AS SHORT
'Return discriminant(f)
DECLARE FUNCTION Eval (ByRef f AS Poly, ByVal c AS LONG) AS SHORT
'Evaluate f(c) with Horner's rule
DECLARE SUB Gcdp (ByRef f AS Poly, ByRef g AS Poly, ByRef d AS Poly)
'd:= polynomial gcd(f, g)
DECLARE SUB Monic (ByRef f AS Poly)
'Make monic(f)
DECLARE FUNCTION Psdiv (ByRef f AS Poly, ByRef g AS Poly, ByRef q AS Poly) AS SHORT
'Pseudo-division, returns the scalar L(g)^(f.n - g.n + 1) * f = g * q + r
DECLARE SUB Recip (ByRef f AS Poly)
'f:= reciprocal X^f.n * f(1/ X)
DECLARE FUNCTION Result (ByRef f AS Poly, ByRef g AS Poly) AS SHORT
'Return resultant(f, g)
DECLARE SUB Subst (ByRef f AS Poly, ByRef g AS Poly)
'Horner substitution f:= f(g(X))
'
' ***************************************************************************************
' Modular arithmetic functions
' ***************************************************************************************
DECLARE FUNCTION Modd (ByVal c AS LONG) AS SHORT
'Return positive(c) mod global modulus
DECLARE FUNCTION Balc (ByVal c AS LONG) AS SHORT
'Return least absolute value(c) mod global modulus
DECLARE FUNCTION Inv (ByVal c AS LONG) AS SHORT
'Return 1/ c mod global modulus
DECLARE FUNCTION Modpwr (ByVal a AS LONG, ByVal k AS SHORT) AS SHORT
'Return a^ k mod global modulus
'
' ***************************************************************************************
' Building big integer exponents
' ***************************************************************************************
DECLARE SUB Addi (ByRef a AS Bigi, ByVal c AS SHORT)
'bigint a:= a + c
DECLARE FUNCTION Divi (ByRef a AS Bigi, ByVal c AS SHORT) AS SHORT
'a:= a / c, returns remainder
DECLARE SUB Muli (ByRef a AS Bigi, ByVal c AS SHORT)
'a:= a * c
DECLARE SUB Pwri (ByRef p AS Bigi, ByVal a AS SHORT, ByVal k AS SHORT)
'p:= a ^ k
DECLARE SUB Squi (ByRef a AS Bigi)
'a:= a ^ 2
'
' ***************************************************************************************
' Internal functions
' ***************************************************************************************
DECLARE SUB Adjp (ByRef f AS Poly, ByVal n AS SHORT)
'Adjust degree n of polynomial f
DECLARE SUB Lftj (ByRef a AS Bigi, ByVal k AS SHORT)
'Left-justify bigint a, starting at array element k
DECLARE SUB Mulc (ByRef f AS Poly, ByVal c AS SHORT)
'f:= f * c mod global modulus
DECLARE SUB Negp (ByRef f AS Poly)
'f:= -f mod global modulus
DECLARE SUB PosLc (ByRef f AS Poly)
'Make positive leading coefficient
DECLARE FUNCTION Tail (ByRef f AS Poly, ByRef g AS Poly) AS SHORT
'Zeroed poly tail for Addp and Subtp
DECLARE SUB Triald (Pf() AS LONG, ByRef fx AS SHORT, ByVal n AS LONG)
'Return primefactors of n in Pf(fx, k)
DECLARE SUB Work (ByRef f AS STRING)
'Set f to the working directory in ENVIRON("LARGEINT"),
'the stringbuffer must be large enough to hold the path
'
' ***************************************************************************************
#IFNDEF __LIB
#INCLIB "polymodp"
' ***************************************************************************************
'28 largest primes < 2^ 15 for CRT-transform:
' ***************************************************************************************
DATA 32749,32719,32717,32713,32707,32693,32687
DATA 32653,32647,32633,32621,32611,32609,32603
DATA 32587,32579,32573,32569,32563,32561,32537
DATA 32533,32531,32507,32503,32497,32491,32479
'
' ***************************************************************************************
#ENDIF
All this functionality in only 20 Kb
The above eight modules need transformation module CRTtrans.bas
to lift the results from the intersection of 28 small equivalence classes:
Plus GF(2^8) versions of the above three Elgamal cryptography modules.
References: