Class: Miscreant::Internals::Block
- Inherits:
-
Object
- Object
- Miscreant::Internals::Block
- Defined in:
- lib/miscreant/internals/block.rb
Overview
A 128-bit block (i.e. for AES)
Constant Summary collapse
- SIZE =
Size of an AES block in bytes
16
- R =
Minimal irreducible polynomial for a 128-bit block size
0x87
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
Instance Method Summary collapse
-
#[](n) ⇒ Object
Retrieve the value of the byte at the given index as an integer.
-
#[]=(n, byte) ⇒ Object
Set the value of the byte at the given index as an integer.
-
#clear ⇒ Object
Reset the value of this block to all zeroes.
-
#copy(other_block) ⇒ Object
Copy the contents of another block into this block.
-
#dbl ⇒ Object
Double a value over GF(2^128):.
-
#encrypt(cipher) ⇒ Object
Encrypt this block in-place, replacing its current contents with their ciphertext under the given block cipher.
-
#initialize(data = nil) ⇒ Block
constructor
Create a new Block, optionally from the given data.
-
#inspect ⇒ Object
Inspect the contents of the block in hex.
-
#xor_in_place(value) ⇒ Object
XOR the given data into the current block in-place.
Constructor Details
#initialize(data = nil) ⇒ Block
Create a new Block, optionally from the given data
17 18 19 20 21 22 23 |
# File 'lib/miscreant/internals/block.rb', line 17 def initialize(data = nil) if data @data = Util.validate_bytestring("block data", data, length: SIZE) else @data = "\0".b * SIZE end end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
14 15 16 |
# File 'lib/miscreant/internals/block.rb', line 14 def data @data end |
Instance Method Details
#[](n) ⇒ Object
Retrieve the value of the byte at the given index as an integer
31 32 33 34 35 36 |
# File 'lib/miscreant/internals/block.rb', line 31 def [](n) raise IndexError, "n must be zero or greater (got #{n})" if n < 0 raise IndexError, "n must be less than #{SIZE} (got #{n})" unless n < SIZE @data.getbyte(n) end |
#[]=(n, byte) ⇒ Object
Set the value of the byte at the given index as an integer
39 40 41 |
# File 'lib/miscreant/internals/block.rb', line 39 def []=(n, byte) @data.setbyte(n, byte) end |
#clear ⇒ Object
Reset the value of this block to all zeroes
44 45 46 |
# File 'lib/miscreant/internals/block.rb', line 44 def clear SIZE.times { |n| @data[n] = 0 } end |
#copy(other_block) ⇒ Object
Copy the contents of another block into this block
49 50 51 |
# File 'lib/miscreant/internals/block.rb', line 49 def copy(other_block) SIZE.times { |n| @data[n] = other_block.data[n] } end |
#dbl ⇒ Object
Double a value over GF(2^128):
a<<1 if firstbit(a)=0
(a<<1) ??? 0???????10000111 if firstbit(a)=1
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/miscreant/internals/block.rb', line 58 def dbl overflow = 0 words = @data.unpack("N4").reverse words.map! do |word| new_word = (word << 1) & 0xFFFFFFFF new_word |= overflow overflow = (word & 0x80000000) >= 0x80000000 ? 1 : 0 new_word end @data = words.reverse.pack("N4") @data[-1] = (@data[-1].ord ^ Util.ct_select(overflow, R, 0)).chr self end |
#encrypt(cipher) ⇒ Object
Encrypt this block in-place, replacing its current contents with their ciphertext under the given block cipher
78 79 80 81 82 83 |
# File 'lib/miscreant/internals/block.rb', line 78 def encrypt(cipher) raise TypeError, "invalid cipher: #{cipher.class}" unless cipher.is_a?(AES::BlockCipher) # TODO: more efficient in-place encryption @data = cipher.encrypt(@data) end |
#inspect ⇒ Object
Inspect the contents of the block in hex
26 27 28 |
# File 'lib/miscreant/internals/block.rb', line 26 def inspect "#<#{self.class} data:\"#{@data.unpack('H*').first}\">" end |
#xor_in_place(value) ⇒ Object
XOR the given data into the current block in-place
88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/miscreant/internals/block.rb', line 88 def xor_in_place(value) case value when Block value = value.data when String Util.validate_bytestring("value", value, length: SIZE) else raise TypeError, "invalid XOR input: #{value.class}" end SIZE.times do |i| self[i] ^= value.getbyte(i) end end |