bkerley-affine 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +1 -1
- data/lib/affine/cipher.rb +25 -0
- data/lib/affine/errors.rb +18 -2
- metadata +2 -2
data/VERSION.yml
CHANGED
data/lib/affine/cipher.rb
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
module Affine
|
2
|
+
# The affine cipher for positive integers. This algorithm is only defined
|
3
|
+
# for positive integers, and many arguments have further restrictions.
|
4
|
+
#
|
5
|
+
# == Usage
|
6
|
+
#
|
7
|
+
# @a = Affine::Cipher.new(2176782371, 65182241782, 123235151)
|
8
|
+
# ct = @a.encipher(14)
|
9
|
+
# 14 == @a.decipher(ct)
|
2
10
|
class Cipher
|
11
|
+
|
12
|
+
# Cipher objects are used both for decryption and encryption.
|
13
|
+
#
|
14
|
+
# == Arguments
|
15
|
+
# [+modulus+] specifies how many different plaintexts and ciphertexts
|
16
|
+
# are available.
|
17
|
+
# [+a_key+] multiplied against the plaintext. <b>Must be coprime with
|
18
|
+
# +modulus+.</b>
|
19
|
+
# [+b_key+] added to the multiplied plaintext. No restrictions, but
|
20
|
+
# it's modulus math, so making it larger than +modulus+ is
|
21
|
+
# useless.
|
3
22
|
def initialize(modulus, a_key, b_key)
|
4
23
|
raise CoprimeError.new(modulus, a_key) if modulus.gcd(a_key) != 1
|
5
24
|
@modulus = modulus
|
@@ -7,15 +26,21 @@ module Affine
|
|
7
26
|
@b_key = b_key
|
8
27
|
@a_inv = extended_gcd(a_key, modulus)
|
9
28
|
end
|
29
|
+
|
30
|
+
# Encrypt one +plaintext+ into a +ciphertext+.
|
10
31
|
def encipher(plaintext)
|
11
32
|
raise RangeError.new(plaintext, @modulus) if plaintext > @modulus
|
12
33
|
((@a_key * plaintext) + @b_key) % @modulus
|
13
34
|
end
|
35
|
+
|
36
|
+
# Decrypt one +ciphertext+ into a +plaintext+.
|
14
37
|
def decipher(ciphertext)
|
15
38
|
raise RangeError.new(ciphertext, @modulus) if ciphertext > @modulus
|
16
39
|
(@a_inv * (ciphertext - @b_key)) % @modulus
|
17
40
|
end
|
18
41
|
|
42
|
+
alias_method :encrypt, :encipher
|
43
|
+
alias_method :decrypt, :decipher
|
19
44
|
private
|
20
45
|
# from http://snippets.dzone.com/posts/show/6074
|
21
46
|
def extended_gcd(b,m,_recursion_depth=0)
|
data/lib/affine/errors.rb
CHANGED
@@ -1,13 +1,29 @@
|
|
1
1
|
module Affine
|
2
|
+
|
3
|
+
# Parent class for Affine cipher errors.
|
4
|
+
#
|
5
|
+
# This is a good kind of error to rescue when you're not
|
6
|
+
# sure about the key, modulus, plaintext, or ciphertext
|
7
|
+
# and want to fail cleanly.
|
2
8
|
class AffineError < StandardError
|
3
9
|
end
|
10
|
+
|
11
|
+
# Raised when two numbers that are supposed to be coprime
|
12
|
+
# (greatest common denominator of 1) are not.
|
13
|
+
#
|
14
|
+
# Keys and moduli from external sources might raise these.
|
4
15
|
class CoprimeError < AffineError
|
5
|
-
def initialize(a, b)
|
16
|
+
def initialize(a, b) #:nodoc:
|
6
17
|
super("Expected #{a} to be coprime with #{b}")
|
7
18
|
end
|
8
19
|
end
|
20
|
+
|
21
|
+
# Raised when an input number is larger than the modulus.
|
22
|
+
#
|
23
|
+
# Plaintexts or ciphertexts from external sources might
|
24
|
+
# raise these.
|
9
25
|
class RangeError < AffineError
|
10
|
-
def initialize(n, mod)
|
26
|
+
def initialize(n, mod) #:nodoc:
|
11
27
|
super("Expected input #{n} to be smaller than modulus #{mod}")
|
12
28
|
end
|
13
29
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bkerley-affine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryce Kerley
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|