finitefield 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+