API reference
Utility functions
DarkIntegers.bitsizeof — Functionbitsizeof(::Type{T}) where T
bitsizeof(x)Size, in bits, of the canonical binary representation of the given type T. Size, in bits, of object x if it is not a type.
DarkIntegers.log_bitsizeof — Functionlog_bitsizeof(::Type{T}) where T
log_bitsizeof(x)log2() of the value returned by bitsizeof for that argument.
DarkIntegers.num_bits — Functionnum_bits(x)Returns the number of bits in the representation of the absolute value of an integer.
DarkIntegers.encompassing_type — Functionencompassing_type(tp::Type{<:Unsigned})Returns the built-in type that covers all the range of tp (not necessarily unsigned).
DarkIntegers.as_builtin — Functionas_builtin(x)Returns the integer x converted to a builtin type with the minimum suitable size.
Single-limb arithmetic
DarkIntegers.addhilo — Functionaddhilo(x_hi::T, x_lo::T, y::T) where T <: UnsignedCalculates hi * B + lo = x_hi * B + x_lo + y, where B == typemax(T) + 1. Returns the result as a pair (hi::T, lo::T). An overflow in hi (if any) is ignored.
DarkIntegers.mulhilo — Functionmulhilo(x::T, y::T) where T <: UnsignedCalculates hi * B + lo = x * y, where B == typemax(T) + 1. Returns the result as a pair (hi::T, lo::T).
DarkIntegers.divremhilo — Functiondivremhilo(x_hi::T, x_lo::T, y::T) where T <: UnsignedCalculates divrem(x_hi * B + x_lo, y), where B == typemax(T) + 1. Returns a tuple (q::T, r::T, o::Bool), where q is the quotient (the part of it fitting into the bits of T), r is the remainder is o is the overflow flag.
DarkIntegers.divhilo — Functiondivhilo(x_hi::T, x_lo::T, y::T) where T <: UnsignedCalculates div(x_hi * B + x_lo, y), where B == typemax(T) + 1. Returns a tuple (q::T, o::Bool), where q is the quotient (the part of it fitting into the bits of T), and o is the overflow flag.
DarkIntegers.remhilo — Functionremhilo(x_hi::T, x_lo::T, y::T) where T <: UnsignedCalculates rem(x_hi * B + x_lo, y), where B == typemax(T) + 1.
Single-limb modulo arithmetic
DarkIntegers.addmod — Functionaddmod(x::T, y::T, modulus::T) where T <: UnsignedReturns mod(x + y, modulus) (even if x + y overflows T). Assumes x and y are in range 0 ... modulus.
DarkIntegers.submod — Functionsubmod(x::T, y::T, modulus::T) where T <: UnsignedReturns mod(x - y, modulus) (even if x - y underflows).
DarkIntegers.mulmod — Functionmulmod(x::T, y::T, modulus::T) where T <: UnsignedReturns mod(x * y, modulus) (even if x * y overflows T).
DarkIntegers.powmod — Functionpowmod(x::T, y::V, modulus::T) where {T <: Unsigned, V}Returns mod(x * y, modulus) (even if x * y overflows T).
Multi-precision numbers
DarkIntegers.MLUInt — TypeMulti-precision unsigned integer type, with N limbs of type T (which must be an unsigned integer type).
Supports +, -, *, divrem, div, rem, mod, ^, ==, !=, <, <=, >, >=, zero, one, oneunit, iseven, isodd, typemin, typemax, iszero, sizeof (can be off if limbs have the type UInt4), bitsizeof, leading_zeros, trailing_zeros, eltype, abs.
Also supports num_bits, halve, double, encompassing_type.
The objects can be created either with convert(), or as
MLUInt(x::NTuple{N, T})
MLUInt{N, T}(x::NTuple{N, V})DarkIntegers.MLInt — TypeMulti-precision unsigned integer type, with N limbs of type T (which must be an unsigned integer type).
Supports +, -, *, divrem, div, rem, mod, ^, ==, !=, <, <=, >, >=, zero, one, oneunit, iseven, isodd, typemin, typemax, iszero, sizeof (can be off if limbs have the type UInt4), bitsizeof, leading_zeros, trailing_zeros, eltype, abs.
Also supports num_bits, halve, double, encompassing_type.
The objects can be created either with convert(), or as
MLInt(x::NTuple{N, T})
MLInt{N, T}(x::NTuple{N, V})Modulo integers
DarkIntegers.ModUInt — TypeAn unsigned integer with all operations performed modulo M.
Supports +, -, *, divrem, div, rem, ^, <, <=, >, >=, zero, one and isodd. Note that the division is a regular division, not multiplication by the inverse (which is not guaranteed to exist for any M).
ModUInt{T, M}(x::Integer) where {T <: Unsigned, M}Creates an ModUInt object. M must have the type T.
Modulo integers (Montgomery representation)
DarkIntegers.MgModUInt — TypeResidue ring element in Montgomery representation. Multiplication is much faster than for ModUInt, addition and subtraction are the same, but division and conversion to regular integers is slower.
Supports +, -, *, divrem, div, rem, ^, <, <=, >, >=, zero, one and isodd. Note that the division is a regular division, not multiplication by the inverse (which is not guaranteed to exist for any M).
MgModUInt{T, M}(x::Integer) where {T <: Unsigned, M}Creates an MgModUInt object. M must have the type T and be an odd number.
Modulo integers helper functions
DarkIntegers.value — Functionraw_value(x::AbstractModUInt{T, M})Returns the value of type T stored in the object (converted out of any special representation if necessary).
DarkIntegers.raw_value — Functionraw_value(x::AbstractModUInt{T, M})Returns the raw value of type T stored in the object (without any conversions).
DarkIntegers.modulus — Functionmodulus(::Type{AbstractModUInt{T, M}})
modulus(x::AbstractModUInt{T, M})Returns the modulus M (of type T) for a modulo integer object or type.
(Nega)cyclic polynomials
DarkIntegers.Polynomial — TypeFixed-size polynomials (with the degree limited by N-1). Currently supports moduli x^n-1 (cyclic_modulus) or x^n+1 (negacyclic_modulus). Supports any type that has arithmetic operators defined for it, including ModUInt and MgModUInt.
Polynomial(coeffs::AbstractArray{T, 1}, modulus::AbstractCyclicModulus) where TCreate a polynomial given the array of coefficients (the i-th coefficient corresponds to the (i-1)-th power).
DarkIntegers.mul_by_monomial — Functionmul_by_monomial(p::Polynomial, power::Integer)Multiply the polynomial by x^power. If power lies outside [0, 2 * N) where N-1 is the maximum degree of the polynomial, a modulo 2 * N will be taken.
DarkIntegers.cyclic_modulus — ConstantA constant denoting cyclic polynomial modulus (x^N - 1), to be supplied to the Polynomial constructor.
DarkIntegers.negacyclic_modulus — ConstantA constant denoting negacyclic polynomial modulus (x^N + 1), to be supplied to the Polynomial constructor.
DarkIntegers.known_isprime — Functionknown_isprime(::Val{X})A method of this function can be defined by the user for a certain X to avoid isprime() being called on it when determining the multiplication function for a polynomial (which can reduce start-up time if X is very large).
DarkIntegers.known_polynomial_mul_function — Functionknown_polynomial_mul_function(::Type{T}, ::Val{N}, polynomial_modulus::AbstractPolynomialModulus)A method of this function can be defined by the user to specify the multiplication function for a certain polynomial coefficient type, length and modulus. Has to return a function with the signature (p1::Polynomial{T, N}, p2::Polynomial{T, N}) :: Polynomial{T, N}, for example one of DarkIntegers.karatsuba_mul, DarkIntegers.nussbaumer_mul, DarkIntegers.ntt_mul.
DarkIntegers.broadcast_into_polynomial — Functionbroadcast_into_polynomial(func, args...)Treat any polynomials in args as 1-dimensional arrays and apply func.(args...), saving the result into a new polynomial.
The moduli of the polynomials in args must be the same.
DarkIntegers.broadcast_into_polynomial! — Functionbroadcast_into_polynomial!(func, p::Polynomial, args...)Treat p and any polynomials in args as 1-dimensional arrays and apply p .= func.(args...).
The moduli of the polynomials in args and the modulus of p must be the same.
DarkIntegers.with_modulus — Functionwith_modulus(p::Polynomial{T, N}, new_modulus::AbstractPolynomialModulus)Returns a new polynomial object with a changed modulus.
DarkIntegers.resize — Functionresize(p::Polynomial, new_length::Integer)Returns a polynomial with changed length. If new_length is greater than the current length, coefficients for higher powers will be set to 0. If new_length is smaller, coefficients for higher powers will be discarded.
NTT
DarkIntegers.ntt — Functionntt(data::Array{T, 1}; inverse::Bool=false, tangent::Bool=false) where T <: AbstractModUIntPerform an NTT on data. If tangent is true, use the tangent NTT (for multiplying tangent polynomials).
DarkIntegers.known_generator — Functionknown_generator(::Val{X})A method of this function can be defined by the user for a certain X to provide a known generator to use in NTT for this modulus.
A generator is a number g between 0 and X-1 such that g^1 mod X, ..., g^(X-1) mod X are all numbers from 1 to X-1 (in any order).