Skip to content

Commit

Permalink
improving docs
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewcooke committed Jul 8, 2015
1 parent b19f941 commit bec26db
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 14 deletions.
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ the relationships between different structures, but to enable
arithmetic on various types, motivated largely by the practical needs
of crypto code.

* [Examples](#examples)
* [Types](#types)
* [Integers Modulo N](#integers-modulo-n)

Incomplete; pull requests welcome.

## Examples
Expand Down Expand Up @@ -112,3 +116,55 @@ julia> print(FR(x^7 + x^6 + x^3 + x, rijndael) * FR(x^6 + x^4 + x + 1, rijndael)

However, note that `rinjdael` here requires 9 bits of storage; there is no
representation with an implicit msb.

## Types

`Residue <: Integer` - abstract superclass for (almost) everything below.
Used to provide some common utilities (like automatic promotion from
integers).

### Integers Modulo N

`ZModN{N,I<:Integer} <: Residue` - abstract superclass for *integers* modulo
some value, where `N` is the modulus, and so typically an `Int` (yes, that's a
integer as a *type*, not a value), and `I`

This has two concrete subclasses, because when `N` is a prime number we can do
more stuff.

`ZRing{N, I<:Integer} <: ZModN{N,I}` - the general case.

`ZField{N, I<:Integer} <: ZModN{N,I}` - assumes that `N` is prime.

These constructors can be used directly, but do not check that arguments are
consistent with assumptoins made in the code (primality, values within range,
etc).

The associated functions `ZR()` and `ZF()` are more suitable for "normal" use,
and include support for factory functions:

```julia
julia> ZF(3, 5, UInt8)
ZField{3,UInt8}(2)

julia> ZF(3, 5)
ZField{3,Int64}(2)

julia> GF3 = ZF(3)
(anonymous function)

julia> GF3(5)
ZField{3,Int64}(2)
```

The macros `@zring` and `@zfield` can also be used to convert all integers
with scope:

```julia
julia> @zring 4 begin
A = [1 2 3 4 5]
end
1x5 Array{IntModN.ZRing{4,Int64},2}:
1 2 3 0 1
```
`
23 changes: 9 additions & 14 deletions src/IntModN.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,14 @@ import Base: show, showcompact, zero, one, inv, real, abs, convert,
rand, rand!, print, map, leading_zeros, divrem, endof
import Base.Random.AbstractRNG

# Pkg.clone("https://github.com/astrieanna/TypeCheck.jl.git")
#using TypeCheck
# Pkg.clone("https://github.com/vtjnash/Polynomial.jl")
#using Polynomial

export ZModN, ZField, ZRing, ZR, ZF, GF2, @zring, @zfield,
ZPoly, ZP, X, P, order, modulus, factor, itype,
GF2Poly, GF2P, GF2X,
FModN, FRing, FR,
extended_euclidean


# we generally support promotion into tyoes here (from integers) and
# we generally support promotion into types here (from integers) and
# conversion back. but that's all. users can add other promotion /
# conversion if required.

Expand All @@ -48,17 +43,17 @@ export ZModN, ZField, ZRing, ZR, ZF, GF2, @zring, @zfield,
# but we need an additional type so that we can intercept things like
# automatic promotion to floats from integers.

abstract IntegerOnly <: Integer
abstract Residue <: Integer

/{I<:Integer,M<:IntegerOnly}(i::I, m::M) = convert(M, i) / m
/{I<:Integer,M<:IntegerOnly}(m::M, i::I) = m / convert(M, i)
inv{M<:IntegerOnly}(m::M) = error("no inverse defined")
/{I<:Integer,M<:Residue}(i::I, m::M) = convert(M, i) / m
/{I<:Integer,M<:Residue}(m::M, i::I) = m / convert(M, i)
inv{M<:Residue}(m::M) = error("no inverse defined")


# --- integers modulo n


abstract ZModN{N, I<:Integer} <: IntegerOnly
abstract ZModN{N, I<:Integer} <: Residue

# we need two types here because prime moduli have a faster inverse
# (via euler's theorem) (note - we do NOT test for primality).
Expand Down Expand Up @@ -171,7 +166,7 @@ for Z in (ZRing, ZField)
end
end

# http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#IntegerOnly_integers
# http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Residue_integers
function extended_euclidean{I<:Integer}(a::I, n::I)
t::I, newt::I = zero(I), one(I)
r::I, newr::I = n, a
Expand Down Expand Up @@ -214,7 +209,7 @@ end

# --- supertype for all polynomial representations

abstract PModN <: IntegerOnly
abstract PModN <: Residue

endof(a::PModN) = length(a)
start(::PModN) = 1
Expand Down Expand Up @@ -643,7 +638,7 @@ degree{U<:Unsigned}(p::GF2Poly{U}) = 8*sizeof(U) - leading_zeros(p)

# this all assumes that the factor poynomial is irreducible

abstract FModN{P<:PModN, F} <: IntegerOnly
abstract FModN{P<:PModN, F} <: Residue

# assumes already reduced
immutable FRing{P<:PModN, F} <: FModN{P,F}
Expand Down

0 comments on commit bec26db

Please sign in to comment.