twofish 1.0.2 → 1.0.3
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/README.rdoc +11 -5
- data/Rakefile +12 -9
- data/lib/string.rb +16 -0
- data/lib/twofish.rb +553 -623
- data/lib/twofish/mode.rb +33 -0
- data/lib/twofish/padding.rb +75 -0
- data/test/benchmark.rb +17 -0
- data/test/test_twofish.rb +35 -9
- metadata +6 -2
data/README.rdoc
CHANGED
@@ -90,6 +90,17 @@ Aside from this README, rdoc documentation may be built as follows:
|
|
90
90
|
The documentation will be built in the rdoc subdirectory.
|
91
91
|
|
92
92
|
|
93
|
+
=== Benchmark
|
94
|
+
|
95
|
+
A simple benchmark can be found in test/benchmark.rb and can be run
|
96
|
+
thusly:
|
97
|
+
|
98
|
+
rake benchmark
|
99
|
+
|
100
|
+
Ruby 1.9 is approximately three times faster than ruby 1.8.7
|
101
|
+
(Ubuntu x86-64).
|
102
|
+
|
103
|
+
|
93
104
|
=== Bugs, omissions and weaknesses
|
94
105
|
|
95
106
|
Encryption and decryption are (not unexpectedly) slow. If you need a
|
@@ -97,11 +108,6 @@ faster implementation for Ruby then the BouncyCastle provider
|
|
97
108
|
(http://www.bouncycastle.org) plays well with JRuby (http://www.jruby.org).
|
98
109
|
See above ("Unit tests") for a sample script.
|
99
110
|
|
100
|
-
The original "pure Perl" implementation used Perl's integer pragma.
|
101
|
-
This implementation uses a private method mask32 to strip off any high
|
102
|
-
order bits in an effort to prevent (slow) promotion of Fixnums to Bignums.
|
103
|
-
This is a little clumsy and probably could be quicker.
|
104
|
-
|
105
111
|
Ruby >=1.9 introduces string encodings. The current workaround uses
|
106
112
|
#ord and #chr but this is not very satisfactory: it would be preferable
|
107
113
|
to move to byte arrays throughout.
|
data/Rakefile
CHANGED
@@ -1,35 +1,38 @@
|
|
1
1
|
|
2
|
+
require 'benchmark'
|
2
3
|
require 'rake'
|
3
4
|
require 'rake/clean'
|
4
|
-
require 'rake/gempackagetask'
|
5
|
-
require 'rake/rdoctask'
|
6
5
|
require 'rake/testtask'
|
6
|
+
require 'rdoc/task'
|
7
|
+
require 'rubygems/package_task'
|
7
8
|
|
8
9
|
desc 'Default task (test)'
|
9
10
|
task :default => [:test]
|
10
11
|
|
11
12
|
Rake::TestTask.new('test') do |test|
|
12
|
-
test.pattern = 'test
|
13
|
+
test.pattern = 'test/test_*.rb'
|
13
14
|
test.warning = true
|
14
15
|
end
|
15
16
|
|
17
|
+
Rake::TestTask.new('benchmark') do |test|
|
18
|
+
test.pattern = 'test/benchmark.rb'
|
19
|
+
end
|
20
|
+
|
16
21
|
SPECFILE = 'twofish.gemspec'
|
17
22
|
if File.exist?(SPECFILE)
|
18
23
|
spec = eval( File.read(SPECFILE) )
|
19
|
-
|
24
|
+
Gem::PackageTask.new(spec) do |pkg|
|
20
25
|
pkg.need_tar = true
|
21
26
|
end
|
22
27
|
end
|
23
28
|
|
24
|
-
|
29
|
+
RDoc::Task.new do |rdoc|
|
25
30
|
rdoc.rdoc_dir = 'rdoc'
|
26
31
|
rdoc.title = 'twofish.rb'
|
27
|
-
rdoc.options << '--line-numbers'
|
28
|
-
rdoc.options << '-A cattr_accessor=object'
|
32
|
+
rdoc.options << '--line-numbers'
|
29
33
|
rdoc.options << '--charset' << 'utf-8'
|
30
34
|
rdoc.options << '--all'
|
31
35
|
rdoc.rdoc_files.include('README.rdoc')
|
32
|
-
rdoc.rdoc_files.include('lib
|
33
|
-
rdoc.rdoc_files.include('test/test_twofish.rb')
|
36
|
+
rdoc.rdoc_files.include(Dir[ 'lib/**/*' ])
|
34
37
|
end
|
35
38
|
|
data/lib/string.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
unless method_defined?(:byteslice)
|
4
|
+
def byteslice(*args)
|
5
|
+
self.dup.force_encoding('ASCII-8BIT').slice!(*args)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
unless method_defined?(:force_encoding)
|
10
|
+
def force_encoding(encoding)
|
11
|
+
self # noop
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
data/lib/twofish.rb
CHANGED
@@ -8,9 +8,26 @@
|
|
8
8
|
# encryption algorithm based on original work by Guido Flohr.
|
9
9
|
class Twofish
|
10
10
|
|
11
|
-
|
11
|
+
require 'string' # monkey patch for MRI 1.8.7
|
12
|
+
require 'twofish/mode'
|
13
|
+
require 'twofish/padding'
|
12
14
|
|
13
|
-
|
15
|
+
# Setters for iv, mode defined below for validation
|
16
|
+
|
17
|
+
# Initialization vector for CBC mode.
|
18
|
+
attr_reader :iv
|
19
|
+
|
20
|
+
# The size of the key in bytes (16, 24, 32 bytes).
|
21
|
+
attr_reader :key_size
|
22
|
+
|
23
|
+
# Encryption mode eg Mode::ECB (default) or Mode::CBC.
|
24
|
+
attr_reader :mode
|
25
|
+
|
26
|
+
# Padding algorithm eg Padding::NONE (default) or Padding::ZERO_BYTE.
|
27
|
+
attr_reader :padding
|
28
|
+
|
29
|
+
# The block size in bytes (16).
|
30
|
+
BLOCK_SIZE = 16
|
14
31
|
|
15
32
|
#:stopdoc:
|
16
33
|
Q0 = [
|
@@ -323,7 +340,7 @@ class Twofish
|
|
323
340
|
# consists of four equal bytes, each with the value i. The function
|
324
341
|
# h is only applied to words of this type, so we only pass it the
|
325
342
|
# value of i.
|
326
|
-
k = []
|
343
|
+
@k = []
|
327
344
|
|
328
345
|
# The key-dependent S-boxes used in the g() function are created
|
329
346
|
# below. They are defined by g(X) = h(X, S), where S is the vector
|
@@ -333,12 +350,11 @@ class Twofish
|
|
333
350
|
# The relevant lookup tables qN have been precomputed and stored in
|
334
351
|
# tables.h; we also perform full key precomputations incorporating
|
335
352
|
# the MDS matrix multiplications.
|
336
|
-
xS0, xS1, xS2, xS3 = [], [], [], []
|
353
|
+
@xS0, @xS1, @xS2, @xS3 = [], [], [], []
|
337
354
|
case @key_size
|
338
355
|
when 16
|
339
356
|
s7, s6, s5, s4 = *mds_rem(le_longs[0], le_longs[1])
|
340
357
|
s3, s2, s1, s0 = *mds_rem(le_longs[2], le_longs[3])
|
341
|
-
a, b = 0, 0
|
342
358
|
(0..38).step(2) do |i|
|
343
359
|
j = i + 1
|
344
360
|
a = M0[Q0[Q0[i] ^ key[8]] ^ key[0]] ^
|
@@ -349,23 +365,22 @@ class Twofish
|
|
349
365
|
M1[Q0[Q1[j] ^ key[13]] ^ key[5]] ^
|
350
366
|
M2[Q1[Q0[j] ^ key[14]] ^ key[6]] ^
|
351
367
|
M3[Q1[Q1[j] ^ key[15]] ^ key[7]]
|
352
|
-
b =
|
353
|
-
a =
|
354
|
-
k.push(a)
|
355
|
-
a =
|
356
|
-
k.push(
|
368
|
+
b = ((b & 0xffffff) << 8) | (b >> 24)
|
369
|
+
a = 0xffffffff & (a+b)
|
370
|
+
@k.push(a)
|
371
|
+
a = 0xffffffff & (a+b)
|
372
|
+
@k.push((a & 0x7fffff) << 9 | a >> 23)
|
357
373
|
end
|
358
374
|
(0..255).each do |i|
|
359
|
-
xS0[i] = M0[Q0[Q0[i] ^ s4] ^ s0]
|
360
|
-
xS1[i] = M1[Q0[Q1[i] ^ s5] ^ s1]
|
361
|
-
xS2[i] = M2[Q1[Q0[i] ^ s6] ^ s2]
|
362
|
-
xS3[i] = M3[Q1[Q1[i] ^ s7] ^ s3]
|
375
|
+
@xS0[i] = M0[Q0[Q0[i] ^ s4] ^ s0]
|
376
|
+
@xS1[i] = M1[Q0[Q1[i] ^ s5] ^ s1]
|
377
|
+
@xS2[i] = M2[Q1[Q0[i] ^ s6] ^ s2]
|
378
|
+
@xS3[i] = M3[Q1[Q1[i] ^ s7] ^ s3]
|
363
379
|
end
|
364
380
|
when 24
|
365
381
|
sb, sa, s9, s8 = *mds_rem(le_longs[0], le_longs[1])
|
366
382
|
s7, s6, s5, s4 = *mds_rem(le_longs[2], le_longs[3])
|
367
383
|
s3, s2, s1, s0 = *mds_rem(le_longs[4], le_longs[5])
|
368
|
-
j = 1
|
369
384
|
(0..38).step(2) do |i|
|
370
385
|
j = i + 1
|
371
386
|
a = M0[Q0[Q0[Q1[i] ^ key[16]] ^ key[8]] ^ key[0]] ^
|
@@ -376,24 +391,23 @@ class Twofish
|
|
376
391
|
M1[Q0[Q1[Q1[j] ^ key[21]] ^ key[13]] ^ key[5]] ^
|
377
392
|
M2[Q1[Q0[Q0[j] ^ key[22]] ^ key[14]] ^ key[6]] ^
|
378
393
|
M3[Q1[Q1[Q0[j] ^ key[23]] ^ key[15]] ^ key[7]]
|
379
|
-
b =
|
380
|
-
a =
|
381
|
-
k.push(a)
|
382
|
-
a =
|
383
|
-
k.push(
|
394
|
+
b = ((b & 0xffffff) << 8) | (b >> 24)
|
395
|
+
a = 0xffffffff & (a+b)
|
396
|
+
@k.push(a)
|
397
|
+
a = 0xffffffff & (a+b)
|
398
|
+
@k.push((a & 0x7fffff) << 9 | a >> 23)
|
384
399
|
end
|
385
400
|
(0..255).each do |i|
|
386
|
-
xS0[i] = M0[Q0[Q0[Q1[i] ^ s8] ^ s4] ^ s0]
|
387
|
-
xS1[i] = M1[Q0[Q1[Q1[i] ^ s9] ^ s5] ^ s1]
|
388
|
-
xS2[i] = M2[Q1[Q0[Q0[i] ^ sa] ^ s6] ^ s2]
|
389
|
-
xS3[i] = M3[Q1[Q1[Q0[i] ^ sb] ^ s7] ^ s3]
|
401
|
+
@xS0[i] = M0[Q0[Q0[Q1[i] ^ s8] ^ s4] ^ s0]
|
402
|
+
@xS1[i] = M1[Q0[Q1[Q1[i] ^ s9] ^ s5] ^ s1]
|
403
|
+
@xS2[i] = M2[Q1[Q0[Q0[i] ^ sa] ^ s6] ^ s2]
|
404
|
+
@xS3[i] = M3[Q1[Q1[Q0[i] ^ sb] ^ s7] ^ s3]
|
390
405
|
end
|
391
406
|
when 32
|
392
407
|
sf, se, sd, sc = *mds_rem(le_longs[0], le_longs[1])
|
393
408
|
sb, sa, s9, s8 = *mds_rem(le_longs[2], le_longs[3])
|
394
409
|
s7, s6, s5, s4 = *mds_rem(le_longs[4], le_longs[5])
|
395
410
|
s3, s2, s1, s0 = *mds_rem(le_longs[6], le_longs[7])
|
396
|
-
j = 1
|
397
411
|
(0..38).step(2) do |i|
|
398
412
|
j = i + 1
|
399
413
|
a = M0[Q0[Q0[Q1[Q1[i] ^ key[24]] ^ key[16]] ^ key[8]] ^ key[0]] ^
|
@@ -404,25 +418,22 @@ class Twofish
|
|
404
418
|
M1[Q0[Q1[Q1[Q0[j] ^ key[29]] ^ key[21]] ^ key[13]] ^ key[5]] ^
|
405
419
|
M2[Q1[Q0[Q0[Q0[j] ^ key[30]] ^ key[22]] ^ key[14]] ^ key[6]] ^
|
406
420
|
M3[Q1[Q1[Q0[Q1[j] ^ key[31]] ^ key[23]] ^ key[15]] ^ key[7]]
|
407
|
-
b =
|
408
|
-
a =
|
409
|
-
k.push(a)
|
410
|
-
a =
|
411
|
-
k.push(
|
421
|
+
b = ((b & 0xffffff) << 8) | (b >> 24)
|
422
|
+
a = 0xffffffff & (a+b)
|
423
|
+
@k.push(a)
|
424
|
+
a = 0xffffffff & (a+b)
|
425
|
+
@k.push((a & 0x7fffff) << 9 | a >> 23)
|
412
426
|
end
|
413
427
|
(0..255).each do |i|
|
414
|
-
xS0[i] = M0[Q0[Q0[Q1[Q1[i]^sc]^s8]^s4]^s0]
|
415
|
-
xS1[i] = M1[Q0[Q1[Q1[Q0[i]^sd]^s9]^s5]^s1]
|
416
|
-
xS2[i] = M2[Q1[Q0[Q0[Q0[i]^se]^sa]^s6]^s2]
|
417
|
-
xS3[i] = M3[Q1[Q1[Q0[Q1[i]^sf]^sb]^s7]^s3]
|
428
|
+
@xS0[i] = M0[Q0[Q0[Q1[Q1[i]^sc]^s8]^s4]^s0]
|
429
|
+
@xS1[i] = M1[Q0[Q1[Q1[Q0[i]^sd]^s9]^s5]^s1]
|
430
|
+
@xS2[i] = M2[Q1[Q0[Q0[Q0[i]^se]^sa]^s6]^s2]
|
431
|
+
@xS3[i] = M3[Q1[Q1[Q0[Q1[i]^sf]^sb]^s7]^s3]
|
418
432
|
end
|
419
433
|
else
|
420
434
|
raise ArgumentError, "invalid key length #{@key_size} (expecting 16, 24 or 32 bytes)"
|
421
435
|
end
|
422
436
|
|
423
|
-
@k = k
|
424
|
-
@s = [ xS0, xS1, xS2, xS3 ]
|
425
|
-
|
426
437
|
end
|
427
438
|
|
428
439
|
# Assign the initialization vector.
|
@@ -440,14 +451,14 @@ class Twofish
|
|
440
451
|
# set to Mode::ECB then the IV will be ignored for any
|
441
452
|
# encrypt/decrypt operations.
|
442
453
|
def mode=(mode)
|
443
|
-
@mode = Mode
|
454
|
+
@mode = Mode.validate(mode)
|
444
455
|
end
|
445
456
|
|
446
457
|
# Set the padding scheme for the (CBC mode) cipher
|
447
458
|
# (Padding::NONE == :none or Padding::ZERO_BYTE ==
|
448
459
|
# :zero_byte).
|
449
460
|
def padding=(scheme)
|
450
|
-
@padding = Padding
|
461
|
+
@padding = Padding.validate(scheme)
|
451
462
|
end
|
452
463
|
|
453
464
|
# Return the cipher's block size in bytes.
|
@@ -458,15 +469,17 @@ class Twofish
|
|
458
469
|
# Encrypt a plaintext string, chunking as required for
|
459
470
|
# CBC mode.
|
460
471
|
def encrypt(plaintext)
|
461
|
-
|
462
|
-
|
472
|
+
plaintext = plaintext.dup.force_encoding('ASCII-8BIT')
|
473
|
+
padded_plaintext = Padding.pad!(plaintext, BLOCK_SIZE, @padding)
|
474
|
+
result = ''.force_encoding('ASCII-8BIT')
|
463
475
|
if @mode == Mode::CBC
|
464
476
|
@iv = generate_iv(BLOCK_SIZE) unless @iv
|
465
477
|
ciphertext_block = @iv
|
466
478
|
end
|
467
|
-
(0
|
468
|
-
|
469
|
-
|
479
|
+
(0...padded_plaintext.length).step(BLOCK_SIZE) do |block_ptr|
|
480
|
+
plaintext_block = padded_plaintext[block_ptr, BLOCK_SIZE]
|
481
|
+
xor_block!(plaintext_block, ciphertext_block) if Mode::CBC == @mode
|
482
|
+
result << ciphertext_block = encrypt_block(plaintext_block)
|
470
483
|
end
|
471
484
|
result
|
472
485
|
end
|
@@ -475,8 +488,9 @@ class Twofish
|
|
475
488
|
# chaining modes. If @iv is not set then we use the first block
|
476
489
|
# as the initialization vector when chaining.
|
477
490
|
def decrypt(ciphertext)
|
478
|
-
|
479
|
-
|
491
|
+
ciphertext = ciphertext.dup.force_encoding('ASCII-8BIT')
|
492
|
+
raise ArgumentError, "ciphertext is not a multiple of #{BLOCK_SIZE} bytes" unless (ciphertext.length % BLOCK_SIZE).zero?
|
493
|
+
result = ''.force_encoding('ASCII-8BIT')
|
480
494
|
if Mode::CBC == @mode
|
481
495
|
if @iv
|
482
496
|
feedback = @iv
|
@@ -485,542 +499,542 @@ class Twofish
|
|
485
499
|
ciphertext = ciphertext[BLOCK_SIZE..-1]
|
486
500
|
end
|
487
501
|
end
|
488
|
-
(0
|
502
|
+
(0...ciphertext.length).step(BLOCK_SIZE) do |block_ptr|
|
489
503
|
ciphertext_block = ciphertext[block_ptr, BLOCK_SIZE]
|
490
|
-
plaintext_block =
|
491
|
-
(
|
504
|
+
plaintext_block = decrypt_block(ciphertext_block)
|
505
|
+
xor_block!(plaintext_block, feedback) if Mode::CBC == @mode
|
492
506
|
result << plaintext_block
|
493
507
|
feedback = ciphertext_block
|
494
508
|
end
|
495
|
-
Padding
|
509
|
+
Padding.unpad!(result, BLOCK_SIZE, @padding)
|
510
|
+
end
|
511
|
+
|
512
|
+
# Exclusive-or two blocks together, byte-by-byte, storing the result
|
513
|
+
# in the first block.
|
514
|
+
def xor_block!(target, source)
|
515
|
+
(0...BLOCK_SIZE).each { |i| target[i] = (target[i].ord ^ source[i].ord).chr }
|
496
516
|
end
|
497
517
|
|
498
518
|
# Encrypt a single block (16 bytes).
|
499
519
|
def encrypt_block(plain_text)
|
500
520
|
|
501
521
|
words = plain_text.unpack('V4')
|
502
|
-
k = @k
|
503
522
|
|
504
|
-
r0 = k[0] ^ words[0]
|
505
|
-
r1 = k[1] ^ words[1]
|
506
|
-
r2 = k[2] ^ words[2]
|
507
|
-
r3 = k[3] ^ words[3]
|
508
|
-
|
509
|
-
xS0, xS1, xS2, xS3 = *@s
|
523
|
+
r0 = @k[0] ^ words[0]
|
524
|
+
r1 = @k[1] ^ words[1]
|
525
|
+
r2 = @k[2] ^ words[2]
|
526
|
+
r3 = @k[3] ^ words[3]
|
510
527
|
|
511
528
|
# i = 0
|
512
|
-
t0 = xS0[r0 & 0xff] ^
|
513
|
-
xS1[(r0 >> 8) & 0xff] ^
|
514
|
-
xS2[(r0 >> 16) & 0xff] ^
|
515
|
-
xS3[(r0 >> 24) & 0xff]
|
516
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
517
|
-
xS1[r1 & 0xff] ^
|
518
|
-
xS2[(r1 >> 8) & 0xff] ^
|
519
|
-
xS3[(r1 >> 16) & 0xff]
|
520
|
-
|
521
|
-
r2 ^=
|
522
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
523
|
-
|
524
|
-
r3 = ((r3 >> 31) & 1) |
|
525
|
-
r3 ^=
|
526
|
-
|
527
|
-
t0 = xS0[r2 & 0xff] ^
|
528
|
-
xS1[(r2 >> 8) & 0xff] ^
|
529
|
-
xS2[(r2 >> 16) & 0xff] ^
|
530
|
-
xS3[(r2 >> 24) & 0xff]
|
531
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
532
|
-
xS1[r3 & 0xff] ^
|
533
|
-
xS2[(r3 >> 8) & 0xff] ^
|
534
|
-
xS3[(r3 >> 16) & 0xff]
|
535
|
-
|
536
|
-
r0 ^=
|
537
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
538
|
-
|
539
|
-
r1 = ((r1 >> 31) & 1) |
|
540
|
-
r1 ^=
|
529
|
+
t0 = @xS0[r0 & 0xff] ^
|
530
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
531
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
532
|
+
@xS3[(r0 >> 24) & 0xff]
|
533
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
534
|
+
@xS1[r1 & 0xff] ^
|
535
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
536
|
+
@xS3[(r1 >> 16) & 0xff]
|
537
|
+
|
538
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[8])
|
539
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
540
|
+
|
541
|
+
r3 = ((r3 >> 31) & 1) | (r3 & 0x7fffffff) << 1
|
542
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[9])
|
543
|
+
|
544
|
+
t0 = @xS0[r2 & 0xff] ^
|
545
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
546
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
547
|
+
@xS3[(r2 >> 24) & 0xff]
|
548
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
549
|
+
@xS1[r3 & 0xff] ^
|
550
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
551
|
+
@xS3[(r3 >> 16) & 0xff]
|
552
|
+
|
553
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[10])
|
554
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
555
|
+
|
556
|
+
r1 = ((r1 >> 31) & 1) | (r1 & 0x7fffffff) << 1
|
557
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[11])
|
541
558
|
|
542
559
|
# i = 1
|
543
|
-
t0 = xS0[r0 & 0xff] ^
|
544
|
-
xS1[(r0 >> 8) & 0xff] ^
|
545
|
-
xS2[(r0 >> 16) & 0xff] ^
|
546
|
-
xS3[(r0 >> 24) & 0xff]
|
547
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
548
|
-
xS1[r1 & 0xff] ^
|
549
|
-
xS2[(r1 >> 8) & 0xff] ^
|
550
|
-
xS3[(r1 >> 16) & 0xff]
|
551
|
-
|
552
|
-
r2 ^=
|
553
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
554
|
-
|
555
|
-
r3 = ((r3 >> 31) & 1) |
|
556
|
-
r3 ^=
|
557
|
-
|
558
|
-
t0 = xS0[r2 & 0xff] ^
|
559
|
-
xS1[(r2 >> 8) & 0xff] ^
|
560
|
-
xS2[(r2 >> 16) & 0xff] ^
|
561
|
-
xS3[(r2 >> 24) & 0xff]
|
562
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
563
|
-
xS1[r3 & 0xff] ^
|
564
|
-
xS2[(r3 >> 8) & 0xff] ^
|
565
|
-
xS3[(r3 >> 16) & 0xff]
|
566
|
-
|
567
|
-
r0 ^=
|
568
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
569
|
-
|
570
|
-
r1 = ((r1 >> 31) & 1) |
|
571
|
-
r1 ^=
|
560
|
+
t0 = @xS0[r0 & 0xff] ^
|
561
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
562
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
563
|
+
@xS3[(r0 >> 24) & 0xff]
|
564
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
565
|
+
@xS1[r1 & 0xff] ^
|
566
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
567
|
+
@xS3[(r1 >> 16) & 0xff]
|
568
|
+
|
569
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[12])
|
570
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
571
|
+
|
572
|
+
r3 = ((r3 >> 31) & 1) | (r3 & 0x7fffffff) << 1
|
573
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[13])
|
574
|
+
|
575
|
+
t0 = @xS0[r2 & 0xff] ^
|
576
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
577
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
578
|
+
@xS3[(r2 >> 24) & 0xff]
|
579
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
580
|
+
@xS1[r3 & 0xff] ^
|
581
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
582
|
+
@xS3[(r3 >> 16) & 0xff]
|
583
|
+
|
584
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[14])
|
585
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
586
|
+
|
587
|
+
r1 = ((r1 >> 31) & 1) | (r1 & 0x7fffffff) << 1
|
588
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[15])
|
572
589
|
|
573
590
|
# i = 2
|
574
|
-
t0 = xS0[r0 & 0xff] ^
|
575
|
-
xS1[(r0 >> 8) & 0xff] ^
|
576
|
-
xS2[(r0 >> 16) & 0xff] ^
|
577
|
-
xS3[(r0 >> 24) & 0xff]
|
578
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
579
|
-
xS1[r1 & 0xff] ^
|
580
|
-
xS2[(r1 >> 8) & 0xff] ^
|
581
|
-
xS3[(r1 >> 16) & 0xff]
|
582
|
-
|
583
|
-
r2 ^=
|
584
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
585
|
-
|
586
|
-
r3 = ((r3 >> 31) & 1) |
|
587
|
-
r3 ^=
|
588
|
-
|
589
|
-
t0 = xS0[r2 & 0xff] ^
|
590
|
-
xS1[(r2 >> 8) & 0xff] ^
|
591
|
-
xS2[(r2 >> 16) & 0xff] ^
|
592
|
-
xS3[(r2 >> 24) & 0xff]
|
593
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
594
|
-
xS1[r3 & 0xff] ^
|
595
|
-
xS2[(r3 >> 8) & 0xff] ^
|
596
|
-
xS3[(r3 >> 16) & 0xff]
|
597
|
-
|
598
|
-
r0 ^=
|
599
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
600
|
-
|
601
|
-
r1 = ((r1 >> 31) & 1) |
|
602
|
-
r1 ^=
|
591
|
+
t0 = @xS0[r0 & 0xff] ^
|
592
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
593
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
594
|
+
@xS3[(r0 >> 24) & 0xff]
|
595
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
596
|
+
@xS1[r1 & 0xff] ^
|
597
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
598
|
+
@xS3[(r1 >> 16) & 0xff]
|
599
|
+
|
600
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[16])
|
601
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
602
|
+
|
603
|
+
r3 = ((r3 >> 31) & 1) | (r3 & 0x7fffffff) << 1
|
604
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[17])
|
605
|
+
|
606
|
+
t0 = @xS0[r2 & 0xff] ^
|
607
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
608
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
609
|
+
@xS3[(r2 >> 24) & 0xff]
|
610
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
611
|
+
@xS1[r3 & 0xff] ^
|
612
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
613
|
+
@xS3[(r3 >> 16) & 0xff]
|
614
|
+
|
615
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[18])
|
616
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
617
|
+
|
618
|
+
r1 = ((r1 >> 31) & 1) | (r1 & 0x7fffffff) << 1
|
619
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[19])
|
603
620
|
|
604
621
|
# i = 3
|
605
|
-
t0 = xS0[r0 & 0xff] ^
|
606
|
-
xS1[(r0 >> 8) & 0xff] ^
|
607
|
-
xS2[(r0 >> 16) & 0xff] ^
|
608
|
-
xS3[(r0 >> 24) & 0xff]
|
609
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
610
|
-
xS1[r1 & 0xff] ^
|
611
|
-
xS2[(r1 >> 8) & 0xff] ^
|
612
|
-
xS3[(r1 >> 16) & 0xff]
|
613
|
-
|
614
|
-
r2 ^=
|
615
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
616
|
-
|
617
|
-
r3 = ((r3 >> 31) & 1) |
|
618
|
-
r3 ^=
|
619
|
-
|
620
|
-
t0 = xS0[r2 & 0xff] ^
|
621
|
-
xS1[(r2 >> 8) & 0xff] ^
|
622
|
-
xS2[(r2 >> 16) & 0xff] ^
|
623
|
-
xS3[(r2 >> 24) & 0xff]
|
624
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
625
|
-
xS1[r3 & 0xff] ^
|
626
|
-
xS2[(r3 >> 8) & 0xff] ^
|
627
|
-
xS3[(r3 >> 16) & 0xff]
|
628
|
-
|
629
|
-
r0 ^=
|
630
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
631
|
-
|
632
|
-
r1 = ((r1 >> 31) & 1) |
|
633
|
-
r1 ^=
|
622
|
+
t0 = @xS0[r0 & 0xff] ^
|
623
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
624
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
625
|
+
@xS3[(r0 >> 24) & 0xff]
|
626
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
627
|
+
@xS1[r1 & 0xff] ^
|
628
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
629
|
+
@xS3[(r1 >> 16) & 0xff]
|
630
|
+
|
631
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[20])
|
632
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
633
|
+
|
634
|
+
r3 = ((r3 >> 31) & 1) | ((r3 & 0x7fffffff) << 1)
|
635
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[21])
|
636
|
+
|
637
|
+
t0 = @xS0[r2 & 0xff] ^
|
638
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
639
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
640
|
+
@xS3[(r2 >> 24) & 0xff]
|
641
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
642
|
+
@xS1[r3 & 0xff] ^
|
643
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
644
|
+
@xS3[(r3 >> 16) & 0xff]
|
645
|
+
|
646
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[22])
|
647
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
648
|
+
|
649
|
+
r1 = ((r1 >> 31) & 1) | (r1 & 0x7fffffff) << 1
|
650
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[23])
|
634
651
|
|
635
652
|
# i = 4
|
636
|
-
t0 = xS0[r0 & 0xff] ^
|
637
|
-
xS1[(r0 >> 8) & 0xff] ^
|
638
|
-
xS2[(r0 >> 16) & 0xff] ^
|
639
|
-
xS3[(r0 >> 24) & 0xff]
|
640
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
641
|
-
xS1[r1 & 0xff] ^
|
642
|
-
xS2[(r1 >> 8) & 0xff] ^
|
643
|
-
xS3[(r1 >> 16) & 0xff]
|
644
|
-
|
645
|
-
r2 ^=
|
646
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
647
|
-
|
648
|
-
r3 = ((r3 >> 31) & 1) |
|
649
|
-
r3 ^=
|
650
|
-
|
651
|
-
t0 = xS0[r2 & 0xff] ^
|
652
|
-
xS1[(r2 >> 8) & 0xff] ^
|
653
|
-
xS2[(r2 >> 16) & 0xff] ^
|
654
|
-
xS3[(r2 >> 24) & 0xff]
|
655
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
656
|
-
xS1[r3 & 0xff] ^
|
657
|
-
xS2[(r3 >> 8) & 0xff] ^
|
658
|
-
xS3[(r3 >> 16) & 0xff]
|
659
|
-
|
660
|
-
r0 ^=
|
661
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
662
|
-
|
663
|
-
r1 = ((r1 >> 31) & 1) |
|
664
|
-
r1 ^=
|
653
|
+
t0 = @xS0[r0 & 0xff] ^
|
654
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
655
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
656
|
+
@xS3[(r0 >> 24) & 0xff]
|
657
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
658
|
+
@xS1[r1 & 0xff] ^
|
659
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
660
|
+
@xS3[(r1 >> 16) & 0xff]
|
661
|
+
|
662
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[24])
|
663
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
664
|
+
|
665
|
+
r3 = ((r3 >> 31) & 1) | (r3 & 0x7fffffff) << 1
|
666
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[25])
|
667
|
+
|
668
|
+
t0 = @xS0[r2 & 0xff] ^
|
669
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
670
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
671
|
+
@xS3[(r2 >> 24) & 0xff]
|
672
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
673
|
+
@xS1[r3 & 0xff] ^
|
674
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
675
|
+
@xS3[(r3 >> 16) & 0xff]
|
676
|
+
|
677
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[26])
|
678
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
679
|
+
|
680
|
+
r1 = ((r1 >> 31) & 1) | ((r1 & 0x7fffffff) << 1)
|
681
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[27])
|
665
682
|
|
666
683
|
# i = 5
|
667
|
-
t0 = xS0[r0 & 0xff] ^
|
668
|
-
xS1[(r0 >> 8) & 0xff] ^
|
669
|
-
xS2[(r0 >> 16) & 0xff] ^
|
670
|
-
xS3[(r0 >> 24) & 0xff]
|
671
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
672
|
-
xS1[r1 & 0xff] ^
|
673
|
-
xS2[(r1 >> 8) & 0xff] ^
|
674
|
-
xS3[(r1 >> 16) & 0xff]
|
675
|
-
|
676
|
-
r2
|
677
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
678
|
-
|
679
|
-
r3 = ((r3 >> 31) & 1) |
|
680
|
-
r3 ^=
|
681
|
-
|
682
|
-
t0 = xS0[r2 & 0xff] ^
|
683
|
-
xS1[(r2 >> 8) & 0xff] ^
|
684
|
-
xS2[(r2 >> 16) & 0xff] ^
|
685
|
-
xS3[(r2 >> 24) & 0xff]
|
686
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
687
|
-
xS1[r3 & 0xff] ^
|
688
|
-
xS2[(r3 >> 8) & 0xff] ^
|
689
|
-
xS3[(r3 >> 16) & 0xff]
|
690
|
-
|
691
|
-
r0 ^=
|
692
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
693
|
-
|
694
|
-
r1 = ((r1 >> 31) & 1) |
|
695
|
-
r1 ^=
|
684
|
+
t0 = @xS0[r0 & 0xff] ^
|
685
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
686
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
687
|
+
@xS3[(r0 >> 24) & 0xff]
|
688
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
689
|
+
@xS1[r1 & 0xff] ^
|
690
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
691
|
+
@xS3[(r1 >> 16) & 0xff]
|
692
|
+
|
693
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[28])
|
694
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
695
|
+
|
696
|
+
r3 = ((r3 >> 31) & 1) | (r3 & 0x7fffffff) << 1
|
697
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[29])
|
698
|
+
|
699
|
+
t0 = @xS0[r2 & 0xff] ^
|
700
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
701
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
702
|
+
@xS3[(r2 >> 24) & 0xff]
|
703
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
704
|
+
@xS1[r3 & 0xff] ^
|
705
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
706
|
+
@xS3[(r3 >> 16) & 0xff]
|
707
|
+
|
708
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[30])
|
709
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
710
|
+
|
711
|
+
r1 = ((r1 >> 31) & 1) | (r1 & 0x7fffffff) << 1
|
712
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[31])
|
696
713
|
|
697
714
|
# i = 6
|
698
|
-
t0 = xS0[r0 & 0xff] ^
|
699
|
-
xS1[(r0 >> 8) & 0xff] ^
|
700
|
-
xS2[(r0 >> 16) & 0xff] ^
|
701
|
-
xS3[(r0 >> 24) & 0xff]
|
702
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
703
|
-
xS1[r1 & 0xff] ^
|
704
|
-
xS2[(r1 >> 8) & 0xff] ^
|
705
|
-
xS3[(r1 >> 16) & 0xff]
|
706
|
-
|
707
|
-
r2 ^=
|
708
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
709
|
-
|
710
|
-
r3 = ((r3 >> 31) & 1) |
|
711
|
-
r3 ^=
|
712
|
-
|
713
|
-
t0 = xS0[r2 & 0xff] ^
|
714
|
-
xS1[(r2 >> 8) & 0xff] ^
|
715
|
-
xS2[(r2 >> 16) & 0xff] ^
|
716
|
-
xS3[(r2 >> 24) & 0xff]
|
717
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
718
|
-
xS1[r3 & 0xff] ^
|
719
|
-
xS2[(r3 >> 8) & 0xff] ^
|
720
|
-
xS3[(r3 >> 16) & 0xff]
|
721
|
-
|
722
|
-
r0 ^=
|
723
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
724
|
-
|
725
|
-
r1 = ((r1 >> 31) & 1) |
|
726
|
-
r1 ^=
|
715
|
+
t0 = @xS0[r0 & 0xff] ^
|
716
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
717
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
718
|
+
@xS3[(r0 >> 24) & 0xff]
|
719
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
720
|
+
@xS1[r1 & 0xff] ^
|
721
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
722
|
+
@xS3[(r1 >> 16) & 0xff]
|
723
|
+
|
724
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[32])
|
725
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
726
|
+
|
727
|
+
r3 = ((r3 >> 31) & 1) | (r3 & 0x7fffffff) << 1
|
728
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[33])
|
729
|
+
|
730
|
+
t0 = @xS0[r2 & 0xff] ^
|
731
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
732
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
733
|
+
@xS3[(r2 >> 24) & 0xff]
|
734
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
735
|
+
@xS1[r3 & 0xff] ^
|
736
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
737
|
+
@xS3[(r3 >> 16) & 0xff]
|
738
|
+
|
739
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[34])
|
740
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
741
|
+
|
742
|
+
r1 = ((r1 >> 31) & 1) | (r1 & 0x7fffffff) << 1
|
743
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[35])
|
727
744
|
|
728
745
|
# i = 7
|
729
|
-
t0 = xS0[r0 & 0xff] ^
|
730
|
-
xS1[(r0 >> 8) & 0xff] ^
|
731
|
-
xS2[(r0 >> 16) & 0xff] ^
|
732
|
-
xS3[(r0 >> 24) & 0xff]
|
733
|
-
t1 = xS0[(r1 >> 24) & 0xff] ^
|
734
|
-
xS1[r1 & 0xff] ^
|
735
|
-
xS2[(r1 >> 8) & 0xff] ^
|
736
|
-
xS3[(r1 >> 16) & 0xff]
|
737
|
-
|
738
|
-
r2 ^=
|
739
|
-
r2 = (r2 >> 1 & 0x7fffffff) |
|
740
|
-
|
741
|
-
r3 = ((r3 >> 31) & 1) |
|
742
|
-
r3 ^=
|
743
|
-
|
744
|
-
t0 = xS0[r2 & 0xff] ^
|
745
|
-
xS1[(r2 >> 8) & 0xff] ^
|
746
|
-
xS2[(r2 >> 16) & 0xff] ^
|
747
|
-
xS3[(r2 >> 24) & 0xff]
|
748
|
-
t1 = xS0[(r3 >> 24) & 0xff] ^
|
749
|
-
xS1[r3 & 0xff] ^
|
750
|
-
xS2[(r3 >> 8) & 0xff] ^
|
751
|
-
xS3[(r3 >> 16) & 0xff]
|
752
|
-
|
753
|
-
r0 ^=
|
754
|
-
r0 = (r0 >> 1 & 0x7fffffff) |
|
755
|
-
|
756
|
-
r1 = ((r1 >> 31) & 1) |
|
757
|
-
r1 ^=
|
758
|
-
|
759
|
-
[k[4] ^ r2, k[5] ^ r3, k[6] ^ r0, k[7] ^ r1].pack("V4")
|
746
|
+
t0 = @xS0[r0 & 0xff] ^
|
747
|
+
@xS1[(r0 >> 8) & 0xff] ^
|
748
|
+
@xS2[(r0 >> 16) & 0xff] ^
|
749
|
+
@xS3[(r0 >> 24) & 0xff]
|
750
|
+
t1 = @xS0[(r1 >> 24) & 0xff] ^
|
751
|
+
@xS1[r1 & 0xff] ^
|
752
|
+
@xS2[(r1 >> 8) & 0xff] ^
|
753
|
+
@xS3[(r1 >> 16) & 0xff]
|
754
|
+
|
755
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[36])
|
756
|
+
r2 = (r2 >> 1 & 0x7fffffff) | (r2 & 0x1) << 31
|
757
|
+
|
758
|
+
r3 = ((r3 >> 31) & 1) | (r3 & 0x7fffffff) << 1
|
759
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[37])
|
760
|
+
|
761
|
+
t0 = @xS0[r2 & 0xff] ^
|
762
|
+
@xS1[(r2 >> 8) & 0xff] ^
|
763
|
+
@xS2[(r2 >> 16) & 0xff] ^
|
764
|
+
@xS3[(r2 >> 24) & 0xff]
|
765
|
+
t1 = @xS0[(r3 >> 24) & 0xff] ^
|
766
|
+
@xS1[r3 & 0xff] ^
|
767
|
+
@xS2[(r3 >> 8) & 0xff] ^
|
768
|
+
@xS3[(r3 >> 16) & 0xff]
|
769
|
+
|
770
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[38])
|
771
|
+
r0 = (r0 >> 1 & 0x7fffffff) | (r0 & 0x1) << 31
|
772
|
+
|
773
|
+
r1 = ((r1 >> 31) & 1) | (r1 & 0x7fffffff) << 1
|
774
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[39])
|
775
|
+
|
776
|
+
[@k[4] ^ r2, @k[5] ^ r3, @k[6] ^ r0, @k[7] ^ r1].pack("V4")
|
760
777
|
end
|
761
778
|
|
762
779
|
# Decrypt a single block (16 bytes).
|
763
780
|
def decrypt_block(plain)
|
764
|
-
words = plain.unpack("V4")
|
765
|
-
k = @k
|
766
781
|
|
767
|
-
|
768
|
-
r1 = k[5] ^ words[1]
|
769
|
-
r2 = k[6] ^ words[2]
|
770
|
-
r3 = k[7] ^ words[3]
|
782
|
+
words = plain.unpack("V4")
|
771
783
|
|
772
|
-
|
784
|
+
r0 = @k[4] ^ words[0]
|
785
|
+
r1 = @k[5] ^ words[1]
|
786
|
+
r2 = @k[6] ^ words[2]
|
787
|
+
r3 = @k[7] ^ words[3]
|
773
788
|
|
774
789
|
# i = 7
|
775
|
-
t0 = xS0[r0 & 0xff] ^
|
776
|
-
xS1[r0 >> 8 & 0xff] ^
|
777
|
-
xS2[r0 >> 16 & 0xff] ^
|
778
|
-
xS3[r0 >> 24 & 0xff]
|
779
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
780
|
-
xS1[r1 & 0xff] ^
|
781
|
-
xS2[r1 >> 8 & 0xff] ^
|
782
|
-
xS3[r1 >> 16 & 0xff]
|
783
|
-
|
784
|
-
r2 = r2 >> 31 & 0x1 |
|
785
|
-
r2 ^=
|
786
|
-
|
787
|
-
r3 ^=
|
788
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
789
|
-
|
790
|
-
t0 = xS0[r2 & 0xff] ^
|
791
|
-
xS1[r2 >> 8 & 0xff] ^
|
792
|
-
xS2[r2 >> 16 & 0xff] ^
|
793
|
-
xS3[r2 >> 24 & 0xff]
|
794
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
795
|
-
xS1[r3 & 0xff] ^
|
796
|
-
xS2[r3 >> 8 & 0xff] ^
|
797
|
-
xS3[r3 >> 16 & 0xff]
|
798
|
-
|
799
|
-
r0 = r0 >> 31 & 0x1 |
|
800
|
-
r0 ^=
|
801
|
-
|
802
|
-
r1 ^=
|
803
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
790
|
+
t0 = @xS0[r0 & 0xff] ^
|
791
|
+
@xS1[r0 >> 8 & 0xff] ^
|
792
|
+
@xS2[r0 >> 16 & 0xff] ^
|
793
|
+
@xS3[r0 >> 24 & 0xff]
|
794
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
795
|
+
@xS1[r1 & 0xff] ^
|
796
|
+
@xS2[r1 >> 8 & 0xff] ^
|
797
|
+
@xS3[r1 >> 16 & 0xff]
|
798
|
+
|
799
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
800
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[38])
|
801
|
+
|
802
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[39])
|
803
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
804
|
+
|
805
|
+
t0 = @xS0[r2 & 0xff] ^
|
806
|
+
@xS1[r2 >> 8 & 0xff] ^
|
807
|
+
@xS2[r2 >> 16 & 0xff] ^
|
808
|
+
@xS3[r2 >> 24 & 0xff]
|
809
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
810
|
+
@xS1[r3 & 0xff] ^
|
811
|
+
@xS2[r3 >> 8 & 0xff] ^
|
812
|
+
@xS3[r3 >> 16 & 0xff]
|
813
|
+
|
814
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
815
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[36])
|
816
|
+
|
817
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[37])
|
818
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
804
819
|
|
805
820
|
# i = 6
|
806
|
-
t0 = xS0[r0 & 0xff] ^
|
807
|
-
xS1[r0 >> 8 & 0xff] ^
|
808
|
-
xS2[r0 >> 16 & 0xff] ^
|
809
|
-
xS3[r0 >> 24 & 0xff]
|
810
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
811
|
-
xS1[r1 & 0xff] ^
|
812
|
-
xS2[r1 >> 8 & 0xff] ^
|
813
|
-
xS3[r1 >> 16 & 0xff]
|
814
|
-
|
815
|
-
r2 = r2 >> 31 & 0x1 |
|
816
|
-
r2 ^=
|
817
|
-
|
818
|
-
r3 ^=
|
819
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
820
|
-
|
821
|
-
t0 = xS0[r2 & 0xff] ^
|
822
|
-
xS1[r2 >> 8 & 0xff] ^
|
823
|
-
xS2[r2 >> 16 & 0xff] ^
|
824
|
-
xS3[r2 >> 24 & 0xff]
|
825
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
826
|
-
xS1[r3 & 0xff] ^
|
827
|
-
xS2[r3 >> 8 & 0xff] ^
|
828
|
-
xS3[r3 >> 16 & 0xff]
|
829
|
-
|
830
|
-
r0 = r0 >> 31 & 0x1 |
|
831
|
-
r0 ^=
|
832
|
-
|
833
|
-
r1 ^=
|
834
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
821
|
+
t0 = @xS0[r0 & 0xff] ^
|
822
|
+
@xS1[r0 >> 8 & 0xff] ^
|
823
|
+
@xS2[r0 >> 16 & 0xff] ^
|
824
|
+
@xS3[r0 >> 24 & 0xff]
|
825
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
826
|
+
@xS1[r1 & 0xff] ^
|
827
|
+
@xS2[r1 >> 8 & 0xff] ^
|
828
|
+
@xS3[r1 >> 16 & 0xff]
|
829
|
+
|
830
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
831
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[34])
|
832
|
+
|
833
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[35])
|
834
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
835
|
+
|
836
|
+
t0 = @xS0[r2 & 0xff] ^
|
837
|
+
@xS1[r2 >> 8 & 0xff] ^
|
838
|
+
@xS2[r2 >> 16 & 0xff] ^
|
839
|
+
@xS3[r2 >> 24 & 0xff]
|
840
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
841
|
+
@xS1[r3 & 0xff] ^
|
842
|
+
@xS2[r3 >> 8 & 0xff] ^
|
843
|
+
@xS3[r3 >> 16 & 0xff]
|
844
|
+
|
845
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
846
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[32])
|
847
|
+
|
848
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[33])
|
849
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
835
850
|
|
836
851
|
# i = 5
|
837
|
-
t0 = xS0[r0 & 0xff] ^
|
838
|
-
xS1[r0 >> 8 & 0xff] ^
|
839
|
-
xS2[r0 >> 16 & 0xff] ^
|
840
|
-
xS3[r0 >> 24 & 0xff]
|
841
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
842
|
-
xS1[r1 & 0xff] ^
|
843
|
-
xS2[r1 >> 8 & 0xff] ^
|
844
|
-
xS3[r1 >> 16 & 0xff]
|
845
|
-
|
846
|
-
r2 = r2 >> 31 & 0x1 |
|
847
|
-
r2 ^=
|
848
|
-
|
849
|
-
r3 ^=
|
850
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
851
|
-
|
852
|
-
t0 = xS0[r2 & 0xff] ^
|
853
|
-
xS1[r2 >> 8 & 0xff] ^
|
854
|
-
xS2[r2 >> 16 & 0xff] ^
|
855
|
-
xS3[r2 >> 24 & 0xff]
|
856
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
857
|
-
xS1[r3 & 0xff] ^
|
858
|
-
xS2[r3 >> 8 & 0xff] ^
|
859
|
-
xS3[r3 >> 16 & 0xff]
|
860
|
-
|
861
|
-
r0 = r0 >> 31 & 0x1 |
|
862
|
-
r0 ^=
|
863
|
-
|
864
|
-
r1 ^=
|
865
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
852
|
+
t0 = @xS0[r0 & 0xff] ^
|
853
|
+
@xS1[r0 >> 8 & 0xff] ^
|
854
|
+
@xS2[r0 >> 16 & 0xff] ^
|
855
|
+
@xS3[r0 >> 24 & 0xff]
|
856
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
857
|
+
@xS1[r1 & 0xff] ^
|
858
|
+
@xS2[r1 >> 8 & 0xff] ^
|
859
|
+
@xS3[r1 >> 16 & 0xff]
|
860
|
+
|
861
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
862
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[30])
|
863
|
+
|
864
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[31])
|
865
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
866
|
+
|
867
|
+
t0 = @xS0[r2 & 0xff] ^
|
868
|
+
@xS1[r2 >> 8 & 0xff] ^
|
869
|
+
@xS2[r2 >> 16 & 0xff] ^
|
870
|
+
@xS3[r2 >> 24 & 0xff]
|
871
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
872
|
+
@xS1[r3 & 0xff] ^
|
873
|
+
@xS2[r3 >> 8 & 0xff] ^
|
874
|
+
@xS3[r3 >> 16 & 0xff]
|
875
|
+
|
876
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
877
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[28])
|
878
|
+
|
879
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[29])
|
880
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
866
881
|
|
867
882
|
# i = 4
|
868
|
-
t0 = xS0[r0 & 0xff] ^
|
869
|
-
xS1[r0 >> 8 & 0xff] ^
|
870
|
-
xS2[r0 >> 16 & 0xff] ^
|
871
|
-
xS3[r0 >> 24 & 0xff]
|
872
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
873
|
-
xS1[r1 & 0xff] ^
|
874
|
-
xS2[r1 >> 8 & 0xff] ^
|
875
|
-
xS3[r1 >> 16 & 0xff]
|
876
|
-
|
877
|
-
r2 = r2 >> 31 & 0x1 |
|
878
|
-
r2 ^=
|
879
|
-
|
880
|
-
r3 ^=
|
881
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
882
|
-
|
883
|
-
t0 = xS0[r2 & 0xff] ^
|
884
|
-
xS1[r2 >> 8 & 0xff] ^
|
885
|
-
xS2[r2 >> 16 & 0xff] ^
|
886
|
-
xS3[r2 >> 24 & 0xff]
|
887
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
888
|
-
xS1[r3 & 0xff] ^
|
889
|
-
xS2[r3 >> 8 & 0xff] ^
|
890
|
-
xS3[r3 >> 16 & 0xff]
|
891
|
-
|
892
|
-
r0 = r0 >> 31 & 0x1 |
|
893
|
-
r0 ^=
|
894
|
-
|
895
|
-
r1 ^=
|
896
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
897
|
-
|
883
|
+
t0 = @xS0[r0 & 0xff] ^
|
884
|
+
@xS1[r0 >> 8 & 0xff] ^
|
885
|
+
@xS2[r0 >> 16 & 0xff] ^
|
886
|
+
@xS3[r0 >> 24 & 0xff]
|
887
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
888
|
+
@xS1[r1 & 0xff] ^
|
889
|
+
@xS2[r1 >> 8 & 0xff] ^
|
890
|
+
@xS3[r1 >> 16 & 0xff]
|
891
|
+
|
892
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
893
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[26])
|
894
|
+
|
895
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[27])
|
896
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
897
|
+
|
898
|
+
t0 = @xS0[r2 & 0xff] ^
|
899
|
+
@xS1[r2 >> 8 & 0xff] ^
|
900
|
+
@xS2[r2 >> 16 & 0xff] ^
|
901
|
+
@xS3[r2 >> 24 & 0xff]
|
902
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
903
|
+
@xS1[r3 & 0xff] ^
|
904
|
+
@xS2[r3 >> 8 & 0xff] ^
|
905
|
+
@xS3[r3 >> 16 & 0xff]
|
906
|
+
|
907
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
908
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[24])
|
909
|
+
|
910
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[25])
|
911
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
898
912
|
|
899
913
|
# i = 3
|
900
|
-
t0 = xS0[r0 & 0xff] ^
|
901
|
-
xS1[r0 >> 8 & 0xff] ^
|
902
|
-
xS2[r0 >> 16 & 0xff] ^
|
903
|
-
xS3[r0 >> 24 & 0xff]
|
904
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
905
|
-
xS1[r1 & 0xff] ^
|
906
|
-
xS2[r1 >> 8 & 0xff] ^
|
907
|
-
xS3[r1 >> 16 & 0xff]
|
908
|
-
|
909
|
-
r2 = r2 >> 31 & 0x1 |
|
910
|
-
r2 ^=
|
911
|
-
|
912
|
-
r3 ^=
|
913
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
914
|
-
|
915
|
-
t0 = xS0[r2 & 0xff] ^
|
916
|
-
xS1[r2 >> 8 & 0xff] ^
|
917
|
-
xS2[r2 >> 16 & 0xff] ^
|
918
|
-
xS3[r2 >> 24 & 0xff]
|
919
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
920
|
-
xS1[r3 & 0xff] ^
|
921
|
-
xS2[r3 >> 8 & 0xff] ^
|
922
|
-
xS3[r3 >> 16 & 0xff]
|
923
|
-
|
924
|
-
r0 = r0 >> 31 & 0x1 |
|
925
|
-
r0 ^=
|
926
|
-
|
927
|
-
r1 ^=
|
928
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
914
|
+
t0 = @xS0[r0 & 0xff] ^
|
915
|
+
@xS1[r0 >> 8 & 0xff] ^
|
916
|
+
@xS2[r0 >> 16 & 0xff] ^
|
917
|
+
@xS3[r0 >> 24 & 0xff]
|
918
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
919
|
+
@xS1[r1 & 0xff] ^
|
920
|
+
@xS2[r1 >> 8 & 0xff] ^
|
921
|
+
@xS3[r1 >> 16 & 0xff]
|
922
|
+
|
923
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
924
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[22])
|
925
|
+
|
926
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[23])
|
927
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
928
|
+
|
929
|
+
t0 = @xS0[r2 & 0xff] ^
|
930
|
+
@xS1[r2 >> 8 & 0xff] ^
|
931
|
+
@xS2[r2 >> 16 & 0xff] ^
|
932
|
+
@xS3[r2 >> 24 & 0xff]
|
933
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
934
|
+
@xS1[r3 & 0xff] ^
|
935
|
+
@xS2[r3 >> 8 & 0xff] ^
|
936
|
+
@xS3[r3 >> 16 & 0xff]
|
937
|
+
|
938
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
939
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[20])
|
940
|
+
|
941
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[21])
|
942
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
929
943
|
|
930
944
|
# i = 2
|
931
|
-
t0 = xS0[r0 & 0xff] ^
|
932
|
-
xS1[r0 >> 8 & 0xff] ^
|
933
|
-
xS2[r0 >> 16 & 0xff] ^
|
934
|
-
xS3[r0 >> 24 & 0xff]
|
935
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
936
|
-
xS1[r1 & 0xff] ^
|
937
|
-
xS2[r1 >> 8 & 0xff] ^
|
938
|
-
xS3[r1 >> 16 & 0xff]
|
939
|
-
|
940
|
-
r2 = r2 >> 31 & 0x1 |
|
941
|
-
r2 ^=
|
942
|
-
|
943
|
-
r3 ^=
|
944
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
945
|
-
|
946
|
-
t0 = xS0[r2 & 0xff] ^
|
947
|
-
xS1[r2 >> 8 & 0xff] ^
|
948
|
-
xS2[r2 >> 16 & 0xff] ^
|
949
|
-
xS3[r2 >> 24 & 0xff]
|
950
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
951
|
-
xS1[r3 & 0xff] ^
|
952
|
-
xS2[r3 >> 8 & 0xff] ^
|
953
|
-
xS3[r3 >> 16 & 0xff]
|
954
|
-
|
955
|
-
r0 = r0 >> 31 & 0x1 |
|
956
|
-
r0 ^=
|
957
|
-
|
958
|
-
r1 ^=
|
959
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
945
|
+
t0 = @xS0[r0 & 0xff] ^
|
946
|
+
@xS1[r0 >> 8 & 0xff] ^
|
947
|
+
@xS2[r0 >> 16 & 0xff] ^
|
948
|
+
@xS3[r0 >> 24 & 0xff]
|
949
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
950
|
+
@xS1[r1 & 0xff] ^
|
951
|
+
@xS2[r1 >> 8 & 0xff] ^
|
952
|
+
@xS3[r1 >> 16 & 0xff]
|
953
|
+
|
954
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
955
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[18])
|
956
|
+
|
957
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[19])
|
958
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
959
|
+
|
960
|
+
t0 = @xS0[r2 & 0xff] ^
|
961
|
+
@xS1[r2 >> 8 & 0xff] ^
|
962
|
+
@xS2[r2 >> 16 & 0xff] ^
|
963
|
+
@xS3[r2 >> 24 & 0xff]
|
964
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
965
|
+
@xS1[r3 & 0xff] ^
|
966
|
+
@xS2[r3 >> 8 & 0xff] ^
|
967
|
+
@xS3[r3 >> 16 & 0xff]
|
968
|
+
|
969
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
970
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[16])
|
971
|
+
|
972
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[17])
|
973
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
960
974
|
|
961
975
|
# i = 1
|
962
|
-
t0 = xS0[r0 & 0xff] ^
|
963
|
-
xS1[r0 >> 8 & 0xff] ^
|
964
|
-
xS2[r0 >> 16 & 0xff] ^
|
965
|
-
xS3[r0 >> 24 & 0xff]
|
966
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
967
|
-
xS1[r1 & 0xff] ^
|
968
|
-
xS2[r1 >> 8 & 0xff] ^
|
969
|
-
xS3[r1 >> 16 & 0xff]
|
970
|
-
|
971
|
-
r2 = r2 >> 31 & 0x1 |
|
972
|
-
r2 ^=
|
973
|
-
|
974
|
-
r3 ^=
|
975
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
976
|
-
|
977
|
-
t0 = xS0[r2 & 0xff] ^
|
978
|
-
xS1[r2 >> 8 & 0xff] ^
|
979
|
-
xS2[r2 >> 16 & 0xff] ^
|
980
|
-
xS3[r2 >> 24 & 0xff]
|
981
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
982
|
-
xS1[r3 & 0xff] ^
|
983
|
-
xS2[r3 >> 8 & 0xff] ^
|
984
|
-
xS3[r3 >> 16 & 0xff]
|
985
|
-
|
986
|
-
r0 = r0 >> 31 & 0x1 |
|
987
|
-
r0 ^=
|
988
|
-
|
989
|
-
r1 ^=
|
990
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
976
|
+
t0 = @xS0[r0 & 0xff] ^
|
977
|
+
@xS1[r0 >> 8 & 0xff] ^
|
978
|
+
@xS2[r0 >> 16 & 0xff] ^
|
979
|
+
@xS3[r0 >> 24 & 0xff]
|
980
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
981
|
+
@xS1[r1 & 0xff] ^
|
982
|
+
@xS2[r1 >> 8 & 0xff] ^
|
983
|
+
@xS3[r1 >> 16 & 0xff]
|
984
|
+
|
985
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
986
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[14])
|
987
|
+
|
988
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[15])
|
989
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
990
|
+
|
991
|
+
t0 = @xS0[r2 & 0xff] ^
|
992
|
+
@xS1[r2 >> 8 & 0xff] ^
|
993
|
+
@xS2[r2 >> 16 & 0xff] ^
|
994
|
+
@xS3[r2 >> 24 & 0xff]
|
995
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
996
|
+
@xS1[r3 & 0xff] ^
|
997
|
+
@xS2[r3 >> 8 & 0xff] ^
|
998
|
+
@xS3[r3 >> 16 & 0xff]
|
999
|
+
|
1000
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
1001
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[12])
|
1002
|
+
|
1003
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[13])
|
1004
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
991
1005
|
|
992
1006
|
# i = 0
|
993
|
-
t0 = xS0[r0 & 0xff] ^
|
994
|
-
xS1[r0 >> 8 & 0xff] ^
|
995
|
-
xS2[r0 >> 16 & 0xff] ^
|
996
|
-
xS3[r0 >> 24 & 0xff]
|
997
|
-
t1 = xS0[r1 >> 24 & 0xff] ^
|
998
|
-
xS1[r1 & 0xff] ^
|
999
|
-
xS2[r1 >> 8 & 0xff] ^
|
1000
|
-
xS3[r1 >> 16 & 0xff]
|
1001
|
-
|
1002
|
-
r2 = r2 >> 31 & 0x1 |
|
1003
|
-
r2 ^=
|
1004
|
-
|
1005
|
-
r3 ^=
|
1006
|
-
r3 = r3 >> 1 & 0x7fffffff |
|
1007
|
-
|
1008
|
-
t0 = xS0[r2 & 0xff] ^
|
1009
|
-
xS1[r2 >> 8 & 0xff] ^
|
1010
|
-
xS2[r2 >> 16 & 0xff] ^
|
1011
|
-
xS3[r2 >> 24 & 0xff]
|
1012
|
-
t1 = xS0[r3 >> 24 & 0xff] ^
|
1013
|
-
xS1[r3 & 0xff] ^
|
1014
|
-
xS2[r3 >> 8 & 0xff] ^
|
1015
|
-
xS3[r3 >> 16 & 0xff]
|
1016
|
-
|
1017
|
-
r0 = r0 >> 31 & 0x1 |
|
1018
|
-
r0 ^=
|
1019
|
-
|
1020
|
-
r1 ^=
|
1021
|
-
r1 = r1 >> 1 & 0x7fffffff |
|
1022
|
-
|
1023
|
-
[
|
1007
|
+
t0 = @xS0[r0 & 0xff] ^
|
1008
|
+
@xS1[r0 >> 8 & 0xff] ^
|
1009
|
+
@xS2[r0 >> 16 & 0xff] ^
|
1010
|
+
@xS3[r0 >> 24 & 0xff]
|
1011
|
+
t1 = @xS0[r1 >> 24 & 0xff] ^
|
1012
|
+
@xS1[r1 & 0xff] ^
|
1013
|
+
@xS2[r1 >> 8 & 0xff] ^
|
1014
|
+
@xS3[r1 >> 16 & 0xff]
|
1015
|
+
|
1016
|
+
r2 = r2 >> 31 & 0x1 | (r2 & 0x7fffffff) << 1
|
1017
|
+
r2 ^= 0xffffffff & (t0 + t1 + @k[10])
|
1018
|
+
|
1019
|
+
r3 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[11])
|
1020
|
+
r3 = r3 >> 1 & 0x7fffffff | (r3 & 0x1) << 31
|
1021
|
+
|
1022
|
+
t0 = @xS0[r2 & 0xff] ^
|
1023
|
+
@xS1[r2 >> 8 & 0xff] ^
|
1024
|
+
@xS2[r2 >> 16 & 0xff] ^
|
1025
|
+
@xS3[r2 >> 24 & 0xff]
|
1026
|
+
t1 = @xS0[r3 >> 24 & 0xff] ^
|
1027
|
+
@xS1[r3 & 0xff] ^
|
1028
|
+
@xS2[r3 >> 8 & 0xff] ^
|
1029
|
+
@xS3[r3 >> 16 & 0xff]
|
1030
|
+
|
1031
|
+
r0 = r0 >> 31 & 0x1 | (r0 & 0x7fffffff) << 1
|
1032
|
+
r0 ^= 0xffffffff & (t0 + t1 + @k[8])
|
1033
|
+
|
1034
|
+
r1 ^= 0xffffffff & (t0 + ((t1 & 0x7fffffff) << 1) + @k[9])
|
1035
|
+
r1 = r1 >> 1 & 0x7fffffff | (r1 & 0x1) << 31
|
1036
|
+
|
1037
|
+
[@k[0] ^ r2, @k[1] ^ r3, @k[2] ^ r0, @k[3] ^ r1].pack("V4")
|
1024
1038
|
end
|
1025
1039
|
|
1026
1040
|
private
|
@@ -1058,16 +1072,16 @@ private
|
|
1058
1072
|
t = b >> 24
|
1059
1073
|
|
1060
1074
|
# Shift the others up.
|
1061
|
-
b =
|
1062
|
-
a =
|
1075
|
+
b = ((b & 0xffffff) << 8) | (a >> 24)
|
1076
|
+
a = ((a & 0xffffff) << 8)
|
1063
1077
|
|
1064
|
-
u =
|
1078
|
+
u = ((t & 0x7fffffff) << 1)
|
1065
1079
|
|
1066
1080
|
# Subtract the modular polynomial on overflow.
|
1067
1081
|
u ^= 0x14d unless (t & 0x80).zero?
|
1068
1082
|
|
1069
1083
|
# Remove t * (a * x^2 + 1).
|
1070
|
-
b ^= t ^
|
1084
|
+
b ^= t ^ ((u & 0xffff) << 16)
|
1071
1085
|
|
1072
1086
|
# Form u = a*t + t/a = t*(a + 1/a).
|
1073
1087
|
u ^= 0x7fffffff & (t >> 1)
|
@@ -1076,103 +1090,19 @@ private
|
|
1076
1090
|
u ^= 0xa6 unless (t & 0x01).zero?
|
1077
1091
|
|
1078
1092
|
# Remove t * (a + 1/a) * (x^3 + x).
|
1079
|
-
b ^=
|
1093
|
+
b ^= ((u & 0xff) << 24) | ((u & 0xffffff) << 8)
|
1080
1094
|
|
1081
1095
|
end
|
1082
1096
|
|
1083
1097
|
[ b >> 24, b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff ]
|
1084
1098
|
end
|
1085
1099
|
|
1086
|
-
# Retain only lowest 32 bits of the given integer.
|
1087
|
-
def mask32(x)
|
1088
|
-
x & 0xffffffff
|
1089
|
-
end
|
1090
|
-
|
1091
1100
|
# Generates a random initialization vector of the given length.
|
1092
1101
|
# Warning: use Ruby standard library Kernel#rand.
|
1093
1102
|
def generate_iv(block_size)
|
1094
1103
|
Array.new(block_size).
|
1095
1104
|
map{ |x| rand(256) }.
|
1096
|
-
pack("C#{block_size}")
|
1097
|
-
end
|
1098
|
-
|
1099
|
-
end
|
1100
|
-
|
1101
|
-
# Encryption modes.
|
1102
|
-
#
|
1103
|
-
# The only currently implemented modes are ECB (Electronic Code Book)
|
1104
|
-
# and CBC (Cipher Block Chaining).
|
1105
|
-
module Mode
|
1106
|
-
|
1107
|
-
ECB = :ecb
|
1108
|
-
CBC = :cbc
|
1109
|
-
ALL = [ CBC, ECB ]
|
1110
|
-
DEFAULT = ECB
|
1111
|
-
|
1112
|
-
# Takes a string or symbol and returns the lowercased
|
1113
|
-
# symbol representation if this is a recognized mode.
|
1114
|
-
# Otherwise, throws ArgumentError.
|
1115
|
-
def Mode::validate(mode)
|
1116
|
-
mode_sym = mode.nil? ? DEFAULT : mode.to_s.downcase.to_sym
|
1117
|
-
raise ArgumentError, "unknown cipher mode #{mode.inspect}" unless ALL.include? mode_sym
|
1118
|
-
mode_sym
|
1119
|
-
end
|
1120
|
-
|
1121
|
-
end
|
1122
|
-
|
1123
|
-
# Implements padding modes to make plaintext into a complete
|
1124
|
-
# number of blocks before encryption and to remove that padding
|
1125
|
-
# after successful decryption.
|
1126
|
-
#
|
1127
|
-
# The only implemented padding schemes are :none and
|
1128
|
-
# :zero_byte. Note that zero byte padding is potentially
|
1129
|
-
# dangerous because if the plaintext terminates in
|
1130
|
-
# zero bytes then these will be erroneously removed by #unpad.
|
1131
|
-
# A more sensible padding scheme should be used in this case.
|
1132
|
-
module Padding
|
1133
|
-
|
1134
|
-
NONE = :none
|
1135
|
-
ZERO_BYTE = :zero_byte
|
1136
|
-
ALL = [ NONE, ZERO_BYTE ]
|
1137
|
-
DEFAULT = NONE
|
1138
|
-
|
1139
|
-
# Takes a string or symbol and returns the lowercased
|
1140
|
-
# symbol representation if this is a recognized padding scheme.
|
1141
|
-
# Otherwise, throws ArgumentError.
|
1142
|
-
def Padding::validate(scheme)
|
1143
|
-
scheme_sym = scheme.nil? ? DEFAULT : scheme.to_s.downcase.to_sym
|
1144
|
-
raise ArgumentError, "unknown padding scheme #{scheme.inspect}" unless ALL.include? scheme_sym
|
1145
|
-
scheme_sym
|
1146
|
-
end
|
1147
|
-
|
1148
|
-
# Pad the given plaintext to a complete number of blocks. If
|
1149
|
-
# the padding scheme is :none and the plaintext is not a whole
|
1150
|
-
# number of blocks then ArgumentError is thrown.
|
1151
|
-
def Padding::pad(plaintext, block_size, scheme=DEFAULT)
|
1152
|
-
scheme_sym = validate(scheme)
|
1153
|
-
remainder = plaintext.length % block_size
|
1154
|
-
case scheme_sym
|
1155
|
-
when NONE
|
1156
|
-
raise ArgumentError, "no padding scheme specified and plaintext length is not a multiple of the block size" unless remainder.zero?
|
1157
|
-
plaintext.dup
|
1158
|
-
when ZERO_BYTE
|
1159
|
-
unless remainder.zero?
|
1160
|
-
plaintext.dup << "\0" * (block_size - remainder)
|
1161
|
-
else
|
1162
|
-
plaintext.dup
|
1163
|
-
end
|
1164
|
-
end
|
1165
|
-
end
|
1166
|
-
|
1167
|
-
# Unpad the given plaintext using the given scheme.
|
1168
|
-
def Padding::unpad(plaintext, block_size, scheme=DEFAULT)
|
1169
|
-
scheme_sym = validate(scheme)
|
1170
|
-
case scheme_sym
|
1171
|
-
when NONE
|
1172
|
-
plaintext.dup
|
1173
|
-
when ZERO_BYTE
|
1174
|
-
plaintext.dup.sub(/\000+\Z/, '')
|
1175
|
-
end
|
1105
|
+
pack("C#{block_size}") # defaults to ASCII-8BIT encoding
|
1176
1106
|
end
|
1177
1107
|
|
1178
1108
|
end
|