finitefield 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE.txt ADDED
@@ -0,0 +1,52 @@
1
+ FiniteField is copyrighted free software by Stephen Doyle <stephendoyle75@gmail.com>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL
3
+ (see COPYING.txt file), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict
21
+ with standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial).
42
+
43
+ 5. The scripts and library files supplied as input to or produced as
44
+ output from the software do not automatically fall under the
45
+ copyright of the software, but belong to whomever generated them,
46
+ and may be sold commercially, and may be aggregated with this
47
+ software.
48
+
49
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
50
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
51
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
52
+ PURPOSE.
data/README.txt ADDED
@@ -0,0 +1,11 @@
1
+ Introduction
2
+ ------------
3
+ The finitefield library is a utility library that provides support for
4
+ performing operations on elements in a finite field. Basic operations
5
+ such as multiplication, division, inverse, addition and subtraction are
6
+ supported.
7
+
8
+ The initial release of this library is limited in scope to only supporting
9
+ fields of the form 2^n.
10
+
11
+
@@ -0,0 +1,147 @@
1
+
2
+ # Finite fields of characteristic 2
3
+
4
+ class FiniteField
5
+ attr_reader :polynomial
6
+ attr_reader :p
7
+
8
+ # Create a field of GF(2^n) using the specified generator polynomial
9
+ def initialize(n, polynomial)
10
+ @polynomial = polynomial
11
+ @n = n
12
+ end
13
+
14
+ # Adds two finite field elements and returns the result.
15
+ def add(lhs, rhs)
16
+ # In characteristic two fields, addition is the xor operation.
17
+ lhs ^ rhs
18
+ end
19
+
20
+ # Subtracts the second argument from the first and return the
21
+ # result. In fields of characteristic two this is the same as
22
+ # the add method.
23
+ def subtract(lhs, rhs)
24
+ add(lhs, rhs)
25
+ end
26
+
27
+ # Multiplies two field elements, modulo the generator polynomial
28
+ # and returns the result.
29
+ def multiply(a, b)
30
+ m = multiplyWithoutReducing(a, b)
31
+ reduce(m)
32
+ end
33
+
34
+ # Multiply two field exlements without modulo with the generator
35
+ # polynomial.
36
+ def multiplyWithoutReducing(a, b)
37
+ result = 0
38
+ mask = 1
39
+ i = 0
40
+
41
+ while i <= @n
42
+ if mask & b != 0
43
+ result ^= a
44
+ end
45
+ a <<= 1
46
+ mask <<= 1
47
+ i += 1
48
+ end
49
+
50
+ return result
51
+ end
52
+
53
+ # Reduce the input value by modulo with the generator polynomial
54
+ def reduce(a)
55
+ result = 0
56
+ i = degree(a)
57
+ mask = 1 << i
58
+
59
+ while i >= @n
60
+ if mask & a != 0
61
+ result ^= 1 << (i - @n)
62
+ a = subtract(a, @polynomial << (i - @n))
63
+ end
64
+ i -= 1
65
+ mask >>= 1
66
+ end
67
+ return a
68
+ end
69
+
70
+ # Computes the multiplicative inverse of the element and returns
71
+ # the result.
72
+ def inverse(a)
73
+ remainder = [0,0,0]
74
+ quotient = [0,0,0]
75
+ auxillary = [0,0,0]
76
+
77
+ remainder[1] = @polynomial
78
+ remainder[2] = a
79
+ auxillary[1] = 0
80
+ auxillary[2] = 1
81
+ i = 2
82
+
83
+ # puts "#{remainder[i].to_s(base=16)} #{quotient[i].to_s(base=16)} #{auxillary[i].to_s(base=16)}"
84
+
85
+ while(remainder[i] > 1)
86
+ i += 1
87
+ result = binary_div(remainder[i-2], remainder[i-1])
88
+ remainder[i] = result[1]
89
+ quotient[i] = result[0]
90
+ auxillary[i] = binary_mul(quotient[i], auxillary[i-1]) ^ auxillary[i-2]
91
+ # puts "#{remainder[i].to_s(base=16)} #{quotient[i].to_s(base=16)} #{auxillary[i].to_s(base=16)}"
92
+ end
93
+
94
+ return auxillary[i]
95
+ end
96
+
97
+ # Division of two field elements (rhs/lhs). This is the same as
98
+ # rhs * lhs^-1 i.e. multiply(rhs, inverse(lhs))
99
+ def divide(lhs, rhs)
100
+ multiply(lhs, inverse(rhs))
101
+ end
102
+
103
+ # Find the degree of the polynomial representing the input field
104
+ # element v. This takes O(degree(v)) operations.
105
+ def degree(v)
106
+ if v != 0
107
+ result = -1
108
+ while v != 0
109
+ v >>= 1
110
+ result += 1
111
+ end
112
+ return result
113
+ end
114
+ return 0
115
+ end
116
+
117
+ # Binary multiplication. Or more explicitly - multiplication over a binary field
118
+ def binary_mul(lhs, rhs)
119
+ result = 0
120
+ a = [degree(lhs), degree(rhs)].max
121
+ 0.upto(a) do |i|
122
+ if lhs & (1 << i) != 0:
123
+ result ^= rhs
124
+ end
125
+ rhs <<= 1
126
+ end
127
+ return result
128
+ end
129
+
130
+ # Binary division. Or more explicitly - division over a binary field
131
+ def binary_div(lhs, rhs)
132
+ q = 0
133
+ r = lhs
134
+ p1 = degree(lhs)
135
+ p2 = degree(rhs)
136
+
137
+ (p1 - p2 + 1).downto(0) do |i|
138
+ q <<= 1
139
+ if r & (1 << (p2+i)) != 0
140
+ q |= 1
141
+ r ^= (rhs << i)
142
+ end
143
+ end
144
+ return [q, r]
145
+ end
146
+
147
+ end
data/test/tc_basic.rb ADDED
@@ -0,0 +1,29 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+
3
+ require 'test/unit'
4
+ require 'finitefield'
5
+
6
+ class BasicTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @field = FiniteField.new(8, 0x11D)
10
+ end
11
+
12
+ def test_get_polynomial
13
+ assert_equal(0x11D, @field.polynomial)
14
+ end
15
+
16
+ def test_degree
17
+ assert_equal(8, @field.degree(0x11D))
18
+ end
19
+
20
+ def test_binary_mul
21
+ assert_equal(0xa95, @field.binary_mul(0x53, 0x23))
22
+ end
23
+
24
+ def test_binary_div
25
+ assert_equal([5, 4], @field.binary_div(0x11b, 0x53))
26
+ end
27
+ end
28
+
29
+
data/test/tc_gf2.rb ADDED
@@ -0,0 +1,38 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+
3
+ require 'test/unit'
4
+ require 'finitefield'
5
+
6
+ class GF2Test < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @field = FiniteField.new(8, 0x11D)
10
+ end
11
+
12
+ def test_gf2_addition_success
13
+ assert_equal(3, @field.add(0x1, 0x2))
14
+ end
15
+
16
+ def test_gf2_subtraction_success
17
+ assert_equal(1, @field.subtract(0x3, 0x2))
18
+ end
19
+
20
+ def test_gf2_multiplication_success
21
+ assert_equal(0x6 , @field.multiply(0x3, 0x2))
22
+ assert_equal(0xc9 , @field.multiply(0xab, 0x11))
23
+ assert_equal(0x01, @field.multiply(0x8c, 0x53))
24
+ end
25
+
26
+ def test_gf2_inverse_success
27
+ f = FiniteField.new(8, 0x11B)
28
+ assert_equal(0xca, f.inverse(0x53))
29
+ assert_equal(0x8c, @field.inverse(0x53))
30
+ end
31
+
32
+ def test_gf2_division_success
33
+ assert_equal(0x11 , @field.divide(0xc9, 0xab))
34
+ end
35
+
36
+ end
37
+
38
+
@@ -0,0 +1,5 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+
3
+ require 'test/unit'
4
+ require 'tc_basic'
5
+ require 'tc_gf2'
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: finitefield
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Doyle
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-10-24 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Finite Field implementation in Ruby.
17
+ email: stephendoyle75@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README.txt
26
+ - LICENSE.txt
27
+ - lib/finitefield.rb
28
+ - test/ts_finitefield.rb
29
+ - test/tc_basic.rb
30
+ - test/tc_gf2.rb
31
+ has_rdoc: false
32
+ homepage: http://finitefield.rubyforge.org/
33
+ post_install_message:
34
+ rdoc_options: []
35
+
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project:
53
+ rubygems_version: 1.0.1
54
+ signing_key:
55
+ specification_version: 2
56
+ summary: Finite Field implementation in Ruby.
57
+ test_files: []
58
+