sjcl 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +2 -0
- data/LICENSE +21 -0
- data/README.md +27 -0
- data/Rakefile +10 -0
- data/lib/sjcl.rb +55 -0
- data/lib/sjcl/aes.rb +105 -0
- data/lib/sjcl/aes_tables.rb +5 -0
- data/lib/sjcl/bit_array.rb +156 -0
- data/lib/sjcl/ccm.rb +118 -0
- data/lib/sjcl/codec_base64.rb +65 -0
- data/lib/sjcl/codec_hex.rb +23 -0
- data/lib/sjcl/codec_string.rb +41 -0
- data/lib/sjcl/pbkdf2.rb +170 -0
- data/lib/sjcl/random.rb +10 -0
- data/lib/sjcl/version.rb +3 -0
- data/sjcl.gemspec +24 -0
- data/spec/aes_spec.rb +35 -0
- data/spec/bit_array_spec.rb +42 -0
- data/spec/ccm_spec.rb +34 -0
- data/spec/code_base64_spec.rb +16 -0
- data/spec/codec_string_spec.rb +16 -0
- data/spec/codex_hex_spec.rb +16 -0
- data/spec/integration_spec.rb +31 -0
- data/spec/pbkdf2_spec.rb +12 -0
- data/spec/spec_helper.rb +10 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 29f8b5de12d94ed4a88c0bc39573a2e6b0448231
|
4
|
+
data.tar.gz: 3a042cd7897783efa68a1ed3c1303ac823f23218
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b45ef4f755370378ffdc7b84f80509032789a2c3efdd7a8e0fbbd25422c4d60d97ca89b1928c7420c9dcd388593b55b544cd260a897f5859ae9af32ee0c2739c
|
7
|
+
data.tar.gz: c7dc290ae0bc477bdee3e62eece162f7671be51ab4908b7c35d926d431cd6a33efe41653aa17115f2bcca1890a8c58cfd0b62362e33ff15c1bfa8e515b61a44d
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Mark Percival <m@mdp.im>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
## SJCL_rb
|
2
|
+
[![Build Status](https://secure.travis-ci.org/mdp/sjcl_rb.png)](http://travis-ci.org/mdp/sjcl_rb)
|
3
|
+
|
4
|
+
A Ruby gem to interop with SJCL in AES-CCM mode.
|
5
|
+
|
6
|
+
Defaults to 256 bit AES in CCM mode with 10_000 iteration PBKDF2
|
7
|
+
|
8
|
+
### Install
|
9
|
+
|
10
|
+
gem install sjcl
|
11
|
+
|
12
|
+
### Usage
|
13
|
+
|
14
|
+
enc = SJCL.encrypt('password', "Something to encrypt")
|
15
|
+
dec = SJCL.decrypt('password', enc)
|
16
|
+
|
17
|
+
### Dev Notes
|
18
|
+
|
19
|
+
This is a very naive implementation of SJCL's AES library in ruby.
|
20
|
+
It's not been optimized for performance and instead tries to be a very
|
21
|
+
close approximation of SJCL in terms of code and organization.
|
22
|
+
|
23
|
+
### TODO
|
24
|
+
|
25
|
+
- More modes
|
26
|
+
- Test interop with node module directly
|
27
|
+
- Test more scenarios
|
data/Rakefile
ADDED
data/lib/sjcl.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'sjcl/bit_array'
|
2
|
+
require 'sjcl/codec_string'
|
3
|
+
require 'sjcl/codec_base64'
|
4
|
+
require 'sjcl/codec_hex'
|
5
|
+
require 'sjcl/aes'
|
6
|
+
require 'sjcl/ccm'
|
7
|
+
require 'sjcl/pbkdf2'
|
8
|
+
require 'sjcl/random'
|
9
|
+
require 'json'
|
10
|
+
require 'base64'
|
11
|
+
|
12
|
+
module SJCL
|
13
|
+
|
14
|
+
DEFAULT = {
|
15
|
+
v:1, iter:10000, ks:256, ts:64,
|
16
|
+
mode:"ccm", adata:"", cipher:"aes"
|
17
|
+
}
|
18
|
+
|
19
|
+
def self.decrypt(password, jsonstr)
|
20
|
+
cipher_obj = JSON.parse(jsonstr, :symbolize_names => true)
|
21
|
+
key = SJCL::Misc.pbkdf2(password,
|
22
|
+
cipher_obj[:salt],
|
23
|
+
cipher_obj[:iter],
|
24
|
+
cipher_obj[:ks])
|
25
|
+
cipher = SJCL::Cipher::AES.new(key)
|
26
|
+
|
27
|
+
ct = SJCL::Codec::Base64.toBits(cipher_obj[:ct])
|
28
|
+
iv = SJCL::Codec::Base64.toBits(cipher_obj[:iv])
|
29
|
+
adata = SJCL::Codec::Base64.toBits(cipher_obj[:adata])
|
30
|
+
out = SJCL::Mode::CCM.decrypt(cipher, ct, iv, adata)
|
31
|
+
SJCL::Codec::UTF8String.fromBits(out)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.encrypt(password, str, opts={})
|
35
|
+
opts = DEFAULT.merge(opts)
|
36
|
+
iv = SJCL::Random.randomWords(4)
|
37
|
+
salt = SJCL::Codec::Base64.fromBits(SJCL::Random.randomWords(2))
|
38
|
+
key = SJCL::Misc.pbkdf2(password,
|
39
|
+
salt,
|
40
|
+
opts[:iter],
|
41
|
+
opts[:ks])
|
42
|
+
cipher = SJCL::Cipher::AES.new(key)
|
43
|
+
pt = SJCL::Codec::UTF8String.toBits(str)
|
44
|
+
adata = SJCL::Codec::UTF8String.toBits(opts[:adata])
|
45
|
+
ct = SJCL::Mode::CCM.encrypt(cipher, pt, iv, adata)
|
46
|
+
ct = SJCL::Codec::Base64.fromBits(ct)
|
47
|
+
out = opts.merge({
|
48
|
+
:ct => ct,
|
49
|
+
:iv => SJCL::Codec::Base64.fromBits(iv),
|
50
|
+
:salt => salt
|
51
|
+
})
|
52
|
+
out.to_json
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/lib/sjcl/aes.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'sjcl/aes_tables'
|
2
|
+
|
3
|
+
module SJCL::Cipher
|
4
|
+
class AES
|
5
|
+
TABLES = SJCL::Cipher::AES_Tables::TABLES
|
6
|
+
attr_reader :key
|
7
|
+
|
8
|
+
def initialize(key)
|
9
|
+
@raw_key = key
|
10
|
+
@keyLen = key.length
|
11
|
+
schedule_keys
|
12
|
+
end
|
13
|
+
|
14
|
+
def schedule_keys
|
15
|
+
sbox = TABLES[0][4]
|
16
|
+
decTable = TABLES[1]
|
17
|
+
encKey = @raw_key.dup
|
18
|
+
decKey = []
|
19
|
+
rcon = 1
|
20
|
+
i = @keyLen
|
21
|
+
j = 0
|
22
|
+
while i < 4*@keyLen + 28
|
23
|
+
tmp = encKey[i-1] ? encKey[i-1] & 0xFFFFFFFF : 0
|
24
|
+
if (i % @keyLen === 0 || (@keyLen === 8 && i % @keyLen === 4))
|
25
|
+
tmp = sbox[tmp >> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255]
|
26
|
+
if (i % @keyLen === 0)
|
27
|
+
tmp = tmp<<8 ^ tmp >> 24 ^ rcon << 24
|
28
|
+
rcon = rcon << 1 ^ (rcon >> 7) * 283
|
29
|
+
end
|
30
|
+
end
|
31
|
+
encKey[i] = (encKey[i-@keyLen] ^ tmp) & 0xFFFFFFFF;
|
32
|
+
i += 1
|
33
|
+
end
|
34
|
+
while i > 0
|
35
|
+
tmp = encKey[j & 3 != 0 ? i : i - 4];
|
36
|
+
tmp = tmp & 0xFFFFFFFF
|
37
|
+
if (i<=4 || j<4)
|
38
|
+
decKey[j] = tmp;
|
39
|
+
else
|
40
|
+
decKey[j] = decTable[0][sbox[tmp >> 24]] ^
|
41
|
+
decTable[1][sbox[tmp >> 16 & 255]] ^
|
42
|
+
decTable[2][sbox[tmp >> 8 & 255]] ^
|
43
|
+
decTable[3][sbox[tmp & 255]]
|
44
|
+
end
|
45
|
+
decKey[j] = decKey[j] & 0xFFFFFFFF
|
46
|
+
i -= 1
|
47
|
+
j += 1
|
48
|
+
end
|
49
|
+
@key = [encKey, decKey]
|
50
|
+
end
|
51
|
+
|
52
|
+
def encrypt(data)
|
53
|
+
crypt(data,0)
|
54
|
+
end
|
55
|
+
|
56
|
+
def decrypt(data)
|
57
|
+
crypt(data,1)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def crypt(input, dir)
|
63
|
+
key = @key[dir]
|
64
|
+
a = input[0] ^ key[0]
|
65
|
+
b = input[dir == 1 ? 3 : 1] ^ key[1]
|
66
|
+
c = input[2] ^ key[2]
|
67
|
+
d = input[dir == 1 ? 1 : 3] ^ key[3]
|
68
|
+
a2 = 0
|
69
|
+
b2 = 0
|
70
|
+
c2 = 0
|
71
|
+
nInnerRounds = key.length/4 - 2
|
72
|
+
kIndex = 4
|
73
|
+
out = [0,0,0,0]
|
74
|
+
table = TABLES[dir]
|
75
|
+
# Load up the tables
|
76
|
+
t0 = table[0]
|
77
|
+
t1 = table[1]
|
78
|
+
t2 = table[2]
|
79
|
+
t3 = table[3]
|
80
|
+
sbox = table[4]
|
81
|
+
|
82
|
+
nInnerRounds.times do
|
83
|
+
a2 = t0[a >> 24 & 255] ^ t1[b>>16 & 255] ^ t2[c>>8 & 255] ^ t3[d & 255] ^ key[kIndex]
|
84
|
+
b2 = t0[b >> 24 & 255] ^ t1[c>>16 & 255] ^ t2[d>>8 & 255] ^ t3[a & 255] ^ key[kIndex + 1]
|
85
|
+
c2 = t0[c >> 24 & 255] ^ t1[d>>16 & 255] ^ t2[a>>8 & 255] ^ t3[b & 255] ^ key[kIndex + 2]
|
86
|
+
d = t0[d >> 24 & 255] ^ t1[a>>16 & 255] ^ t2[b>>8 & 255] ^ t3[c & 255] ^ key[kIndex + 3]
|
87
|
+
kIndex += 4
|
88
|
+
a=a2; b=b2; c=c2;
|
89
|
+
end
|
90
|
+
|
91
|
+
4.times do |i|
|
92
|
+
out[dir != 0 ? 3&-i : i] =
|
93
|
+
sbox[a>>24 & 255]<<24 ^
|
94
|
+
sbox[b>>16 & 255]<<16 ^
|
95
|
+
sbox[c>>8 & 255]<<8 ^
|
96
|
+
sbox[d & 255] ^
|
97
|
+
key[kIndex];
|
98
|
+
kIndex += 1
|
99
|
+
a2=a; a=b; b=c; c=d; d=a2;
|
100
|
+
end
|
101
|
+
return out
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
module SJCL::Cipher
|
2
|
+
module AES_Tables
|
3
|
+
TABLES = [[[-966564955,-126059388,-294160487,-159679603,-855539,-697603139,-563122255,-1849309868,1613770832,33620227,-832084055,1445669757,-402719207,-1244145822,1303096294,-327780710,-1882535355,528646813,-1983264448,-92439161,-268764651,-1302767125,-1907931191,-68095989,1101901292,-1277897625,1604494077,1169141738,597466303,1403299063,-462261610,-1681866661,1974974402,-503448292,1033081774,1277568618,1815492186,2118074177,-168298750,-2083730353,1748251740,1369810420,-773462732,-101584632,-495881837,-1411852173,1647391059,706024767,134480908,-1782069422,1176707941,-1648114850,806885416,932615841,168101135,798661301,235341577,605164086,461406363,-538779075,-840176858,1311188841,2142417613,-361400929,302582043,495158174,1479289972,874125870,907746093,-596742478,-1269146898,1537253627,-1538108682,1983593293,-1210657183,2108928974,1378429307,-572267714,1580150641,327451799,-1504488459,-1177431704,0,-1041371860,1075847264,-469959649,2041688520,-1235526675,-731223362,-1916023994,1740553945,1916352843,-1807070498,-1739830060,-1336387352,-2049978550,-1143943061,-974131414,1336584933,-302253290,-2042412091,-1706209833,1714631509,293963156,-1975171633,-369493744,67240454,-25198719,-1605349136,2017213508,631218106,1269344483,-1571728909,1571005438,-2143272768,93294474,1066570413,563977660,1882732616,-235539196,1673313503,2008463041,-1344611723,1109467491,537923632,-436207846,-34344178,-1076702611,-2117218996,403442708,638784309,-1007883217,-1101045791,899127202,-2008791860,773265209,-1815821225,1437050866,-58818942,2050833735,-932944724,-1168286233,840505643,-428641387,-1067425632,427917720,-1638969391,-1545806721,1143087718,1412049534,999329963,193497219,-1941551414,-940642775,1807268051,672404540,-1478566279,-1134666014,369822493,-1378100362,-606019525,1681011286,1949973070,336202270,-1840690725,201721354,1210328172,-1201906460,-1614626211,-1110191250,1135389935,-1000185178,965841320,831886756,-739974089,-226920053,-706222286,-1949775805,1849112409,-630362697,26054028,-1311386268,-1672589614,1235855840,-663982924,-1403627782,-202050553,-806688219,-899324497,-193299826,1202630377,268961816,1874508501,-260540280,1243948399,1546530418,941366308,1470539505,1941222599,-1748580783,-873928669,-1579295364,-395021156,1042226977,-1773450275,1639824860,227249030,260737669,-529502064,2084453954,1907733956,-865704278,-1874310952,100860677,-134810111,470683154,-1033805405,1781871967,-1370007559,1773779408,394692241,-1715355304,974986535,664706745,-639508168,-336005101,731420851,571543859,-764843589,-1445340816,126783113,865375399,765172662,1008606754,361203602,-907417312,-2016489911,-1437248001,1344809080,-1512054918,59542671,1503764984,160008576,437062935,1707065306,-672733647,-2076032314,-798463816,-2109652541,697932208,1512910199,504303377,2075177163,-1470868228,1841019862,739644986],[-1513725085,-2064089988,-1712425097,-1913226373,234877682,-1110021269,-1310822545,1418839493,1348481072,50462977,-1446090905,2102799147,434634494,1656084439,-431117397,-1695779210,1167051466,-1658879358,1082771913,-2013627011,368048890,-340633255,-913422521,201060592,-331240019,1739838676,-44064094,-364531793,-1088185188,-145513308,-1763413390,1536934080,-1032472649,484572669,-1371696237,1783375398,1517041206,1098792767,49674231,1334037708,1550332980,-195975771,886171109,150598129,-1813876367,1940642008,1398944049,1059722517,201851908,1385547719,1699095331,1587397571,674240536,-1590192490,252314885,-1255171430,151914247,908333586,-1692696448,1038082786,651029483,1766729511,-847269198,-1612024459,454166793,-1642232957,1951935532,775166490,758520603,-1294176658,-290170278,-77881184,-157003182,1299594043,1639438038,-830622797,2068982057,1054729187,1901997871,-1760328572,-173649069,1757008337,0,750906861,1614815264,535035132,-931548751,-306816165,-1093375382,1183697867,-647512386,1265776953,-560706998,-728216500,-391096232,1250283471,1807470800,717615087,-447763798,384695291,-981056701,-677753523,1432761139,-1810791035,-813021883,283769337,100925954,-2114027649,-257929136,1148730428,-1171939425,-481580888,-207466159,-27417693,-1065336768,-1979347057,-1388342638,-1138647651,1215313976,82966005,-547111748,-1049119050,1974459098,1665278241,807407632,451280895,251524083,1841287890,1283575245,337120268,891687699,801369324,-507617441,-1573546089,-863484860,959321879,1469301956,-229267545,-2097381762,1199193405,-1396153244,-407216803,724703513,-1780059277,-1598005152,-1743158911,-778154161,2141445340,1715741218,2119445034,-1422159728,-2096396152,-896776634,700968686,-747915080,1009259540,2041044702,-490971554,487983883,1991105499,1004265696,1449407026,1316239930,504629770,-611169975,168560134,1816667172,-457679780,1570751170,1857934291,-280777556,-1497079198,-1472622191,-1540254315,936633572,-1947043463,852879335,1133234376,1500395319,-1210421907,-1946055283,1689376213,-761508274,-532043351,-1260884884,-89369002,133428468,634383082,-1345690267,-1896580486,-381178194,403703816,-714097990,-1997506440,1867130149,1918643758,607656988,-245913946,-948718412,1368901318,600565992,2090982877,-1662487436,557719327,-577352885,-597574211,-2045932661,-2062579062,-1864339344,1115438654,-999180875,-1429445018,-661632952,84280067,33027830,303828494,-1547542175,1600795957,-106014889,-798377543,-1860729210,1486471617,658119965,-1188585826,953803233,334231800,-1288988520,857870609,-1143838359,1890179545,-1995993458,-1489791852,-1238525029,574365214,-1844082809,550103529,1233637070,-5614251,2018519080,2057691103,-1895592820,-128343647,-2146858615,387583245,-630865985,836232934,-964410814,-1194301336,-1014873791,-1339450983,2002398509,287182607,-881086288,-56077228,-697451589,975967766],[1671808611,2089089148,2006576759,2072901243,-233963534,1807603307,1873927791,-984313403,810573872,16974337,1739181671,729634347,-31856642,-681396777,-1410970197,1989864566,-901410870,-2103631998,-918517303,2106063485,-99225606,1508618841,1204391495,-267650064,-1377025619,-731401260,-1560453214,-1343601233,-1665195108,-1527295068,1922491506,-1067738176,-1211992649,-48438787,-1817297517,644500518,911895606,1061256767,-150800905,-867204148,878471220,-1510714971,-449523227,-251069967,1905517169,-663508008,827548209,356461077,67897348,-950889017,593839651,-1017209405,405286936,-1767819370,84871685,-1699401830,118033927,305538066,-2137318528,-499261470,-349778453,661212711,-1295155278,1973414517,152769033,-2086789757,745822252,439235610,455947803,1857215598,1525593178,-1594139744,1391895634,994932283,-698239018,-1278313037,695947817,-482419229,795958831,-2070473852,1408607827,-781665839,0,-315833875,543178784,-65018884,-1312261711,1542305371,1790891114,-884568629,-1093048386,961245753,1256100938,1289001036,1491644504,-817199665,-798245936,-282409489,-1427812438,-82383365,1137018435,1305975373,861234739,-2053893755,1171229253,-116332039,33948674,2139225727,1357946960,1011120188,-1615190625,-1461498968,1374921297,-1543610973,1086357568,-1886780017,-1834139758,-1648615011,944271416,-184225291,-1126210628,-1228834890,-629821478,560153121,271589392,-15014401,-217121293,-764559406,-850624051,202643468,322250259,-332413972,1608629855,-1750977129,1154254916,389623319,-1000893500,-1477290585,2122513534,1028094525,1689045092,1575467613,422261273,1939203699,1621147744,-2120738431,1339137615,-595614756,577127458,712922154,-1867826288,-2004677752,1187679302,-299251730,-1194103880,339486740,-562452514,1591917662,186455563,-612979237,-532948000,844522546,978220090,169743370,1239126601,101321734,611076132,1558493276,-1034051646,-747717165,-1393605716,1655096418,-1851246191,-1784401515,-466103324,2039214713,-416098841,-935097400,928607799,1840765549,-1920204403,-714821163,1322425422,-1444918871,1823791212,1459268694,-200805388,-366620694,1706019429,2056189050,-1360443474,135794696,-1160417350,2022240376,628050469,779246638,472135708,-1494132826,-1261997132,-967731258,-400307224,-579034659,1956440180,522272287,1272813131,-1109630531,-1954148981,-1970991222,1888542832,1044544574,-1245417035,1722469478,1222152264,50660867,-167643146,236067854,1638122081,895445557,1475980887,-1177523783,-2037311610,-1051158079,489110045,-1632032866,-516367903,-132912136,-1733088360,288563729,1773916777,-646927911,-1903622258,-1800981612,-1682559589,505560094,-2020469369,-383727127,-834041906,1442818645,678973480,-545610273,-1936784500,-1577559647,-1988097655,219617805,-1076206145,-432941082,1120306242,1756942440,1103331905,-1716508263,762796589,252780047,-1328841808,1425844308,-1143575109,372911126],[1667474886,2088535288,2004326894,2071694838,-219017729,1802223062,1869591006,-976923503,808472672,16843522,1734846926,724270422,-16901657,-673750347,-1414797747,1987484396,-892713585,-2105369313,-909557623,2105378810,-84273681,1499065266,1195886990,-252703749,-1381110719,-724277325,-1566376609,-1347425723,-1667449053,-1532692653,1920112356,-1061135461,-1212693899,-33743647,-1819038147,640051788,909531756,1061110142,-134806795,-859025533,875846760,-1515850671,-437963567,-235861767,1903268834,-656903253,825316194,353713962,67374088,-943238507,589522246,-1010606435,404236336,-1768513225,84217610,-1701137105,117901582,303183396,-2139055333,-488489505,-336910643,656894286,-1296904833,1970642922,151591698,-2088526307,741110872,437923380,454765878,1852748508,1515908788,-1600062629,1381168804,993742198,-690593353,-1280061827,690584402,-471646499,791638366,-2071685357,1398011302,-774805319,0,-303223615,538992704,-50585629,-1313748871,1532751286,1785380564,-875870579,-1094788761,960056178,1246420628,1280103576,1482221744,-808498555,-791647301,-269538619,-1431640753,-67430675,1128514950,1296947098,859002214,-2054843375,1162203018,-101117719,33687044,2139062782,1347481760,1010582648,-1616922075,-1465326773,1364325282,-1549533603,1077985408,-1886418427,-1835881153,-1650607071,943212656,-168491791,-1128472733,-1229536905,-623217233,555836226,269496352,-58651,-202174723,-757961281,-842183551,202118168,320025894,-320065597,1600119230,-1751670219,1145359496,387397934,-993765485,-1482165675,2122220284,1027426170,1684319432,1566435258,421079858,1936954854,1616945344,-2122213351,1330631070,-589529181,572679748,707427924,-1869567173,-2004319477,1179044492,-286381625,-1195846805,336870440,-555845209,1583276732,185277718,-606374227,-522175525,842159716,976899700,168435220,1229577106,101059084,606366792,1549591736,-1027449441,-741118275,-1397952701,1650632388,-1852725191,-1785355215,-454805549,2038008818,-404278571,-926399605,926374254,1835907034,-1920103423,-707435343,1313788572,-1448484791,1819063512,1448540844,-185333773,-353753649,1701162954,2054852340,-1364268729,134748176,-1162160785,2021165296,623210314,774795868,471606328,-1499008681,-1263220877,-960081513,-387439669,-572687199,1953799400,522133822,1263263126,-1111630751,-1953790451,-1970633457,1886425312,1044267644,-1246378895,1718004428,1212733584,50529542,-151649801,235803164,1633788866,892690282,1465383342,-1179004823,-2038001385,-1044293479,488449850,-1633765081,-505333543,-117959701,-1734823125,286339874,1768537042,-640061271,-1903261433,-1802197197,-1684294099,505291324,-2021158379,-370597687,-825341561,1431699370,673740880,-539002203,-1936945405,-1583220647,-1987477495,218961690,-1077945755,-421121577,1111672452,1751693520,1094828930,-1717981143,757954394,252645662,-1330590853,1414855848,-1145317779,370555436],[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22]],[[1374988112,2118214995,437757123,975658646,1001089995,530400753,-1392879445,1273168787,540080725,-1384747530,-1999866223,-184398811,1340463100,-987051049,641025152,-1251826801,-558802359,632953703,1172967064,1576976609,-1020300030,-2125664238,-1924753501,1809054150,59727847,361929877,-1083344149,-1789765158,-725712083,1484005843,1239443753,-1899378620,1975683434,-191989384,-1722270101,666464733,-1092530250,-259478249,-920605594,2110667444,1675577880,-451268222,-1756286112,1649639237,-1318815776,-1150570876,-25059300,-116905068,1883793496,-1891238631,-1797362553,1383856311,-1418472669,1917518562,-484470953,1716890410,-1293211641,800440835,-2033878118,-751368027,807962610,599762354,33778362,-317291940,-1966138325,-1485196142,-217582864,1315562145,1708848333,101039829,-785096161,-995688822,875451293,-1561111136,92987698,-1527321739,193195065,1080094634,1584504582,-1116860335,1042385657,-1763899843,-583137874,1306967366,-1856729675,1908694277,67556463,1615861247,429456164,-692196969,-1992277044,1742315127,-1326955843,126454664,-417768648,2043211483,-1585706425,2084704233,-125559095,0,159417987,841739592,504459436,1817866830,-49348613,260388950,1034867998,908933415,168810852,1750902305,-1688513327,607530554,202008497,-1822955761,-1259432238,463180190,-2134850225,1641816226,1517767529,470948374,-493635062,-1063245083,1008918595,303765277,235474187,-225720403,766945465,337553864,1475418501,-1351284916,-291906117,-1551933187,-150919521,1551037884,1147550661,1543208500,-1958532746,-886847780,-1225917336,-1192955549,-684598070,1113818384,328671808,-2067394272,-2058738563,-759480840,-1359400431,-953573011,496906059,-592301837,226906860,2009195472,733156972,-1452230247,294930682,1206477858,-1459843900,-1594867942,1451044056,573804783,-2025238841,-650587711,-1932877058,-1730933962,-1493859889,-1518674392,-625504730,1068351396,742039012,1350078989,1784663195,1417561698,-158526526,-1864845080,775550814,-2101104651,-1621262146,1775276924,1876241833,-819653965,-928212677,270040487,-392404114,-616842373,-853116919,1851332852,-325404927,-2091935064,-426414491,-1426069890,566021896,-283776794,-1159226407,1248802510,-358676012,699432150,832877231,708780849,-962227152,899835584,1951317047,-58537306,-527380304,866637845,-251357110,1106041591,2144161806,395441711,1984812685,1139781709,-861254316,-459930401,-1630423581,1282050075,-1054072904,1181045119,-1654724092,25965917,-91786125,-83148498,-1285087910,-1831087534,-384805325,1842759443,-1697160820,933301370,1509430414,-351060855,-827774994,-1218328267,-518199827,2051518780,-1663901863,1441952575,404016761,1942435775,1408749034,1610459739,-549621996,2017778566,-894438527,-1184316354,941896748,-1029488545,371049330,-1126030068,675039627,-15887039,967311729,135050206,-659233636,1683407248,2076935265,-718096784,1215061108,-793225406],[1347548327,1400783205,-1021700188,-1774573730,-885281941,-249586363,-1414727080,-1823743229,1428173050,-156404115,-1853305738,636813900,-61872681,-674944309,-2144979644,-1883938141,1239331162,1730525723,-1740248562,-513933632,46346101,310463728,-1551022441,-966011911,-419197089,-1793748324,-339776134,-627748263,768917123,-749177823,692707433,1150208456,1786102409,2029293177,1805211710,-584599183,-1229004465,401639597,1724457132,-1266823622,409198410,-2098914767,1620529459,1164071807,-525245321,-2068091986,486441376,-1795618773,1483753576,428819965,-2020286868,-1219331080,598438867,-495826174,1474502543,711349675,129166120,53458370,-1702443653,-1512884472,-231724921,-1306280027,-1174273174,1559041666,730517276,-1834518092,-252508174,-1588696606,-848962828,-721025602,533804130,-1966823682,-1657524653,-1599933611,839224033,1973745387,957055980,-1438621457,106852767,1371368976,-113368694,1033297158,-1361232379,1179510461,-1248766835,91341917,1862534868,-10465259,605657339,-1747534359,-863420349,2003294622,-1112479678,-2012771957,954669403,-612775698,1201765386,-377732593,-906460130,0,-2096529274,1211247597,-1407315600,1315723890,-67301633,1443857720,507358933,657861945,1678381017,560487590,-778347692,975451694,-1324610969,261314535,-759894378,-1642357871,1333838021,-1570644960,1767536459,370938394,182621114,-440360918,1128014560,487725847,185469197,-1376613433,-1188186456,-938205527,-2057834215,1286567175,-1141990947,-39616672,-1611202266,-1134791947,-985373125,878443390,1988838185,-590666810,1756818940,1673061617,-891866660,272786309,1075025698,545572369,2105887268,-120407235,296679730,1841768865,1260232239,-203640272,-334657966,-797457949,1814803222,-1716948807,-99511224,575138148,-995558260,446754879,-665420500,-282971248,-947435186,-1042728751,-24327518,915985419,-811141759,681933534,651868046,-1539330625,-466863459,223377554,-1687527476,1649704518,-1024029421,-393160520,1580087799,-175979601,-1096852096,2087309459,-1452288723,-1278270190,1003007129,-1492117379,1860738147,2077965243,164439672,-194094824,32283319,-1467789414,1709610350,2125135846,136428751,-420538904,-642062437,-833982666,-722821367,-701910916,-1355701070,824852259,818324884,-1070226842,930369212,-1493400886,-1327460144,355706840,1257309336,-146674470,243256656,790073846,-1921626666,1296297904,1422699085,-538667516,-476130891,457992840,-1195299809,2135319889,77422314,1560382517,1945798516,788204353,1521706781,1385356242,870912086,325965383,-1936009375,2050466060,-1906706412,-1981082820,-288446169,901210569,-304014107,1014646705,1503449823,1062597235,2031621326,-1082931401,-363595827,1533017514,350174575,-2038938405,-2117423117,1052338372,741876788,1606591296,1914052035,213705253,-1960297399,1107234197,1899603969,-569897805,-1663519516,-1872472383,1635502980,1893020342,1950903388,1120974935],[-1487908364,1699970625,-1530717673,1586903591,1808481195,1173430173,1487645946,59984867,-95084496,1844882806,1989249228,1277555970,-671330331,-875051734,1149249077,-1550863006,1514790577,459744698,244860394,-1058972162,1963115311,-267222708,-1750889146,-104436781,1608975247,-1667951214,2062270317,1507497298,-2094148418,567498868,1764313568,-935031095,-1989511742,2037970062,1047239000,1910319033,1337376481,-1390940024,-1402549984,984907214,1243112415,830661914,861968209,2135253587,2011214180,-1367032981,-1608712575,731183368,1750626376,-48656571,1820824798,-122203525,-752637069,48394827,-1890065633,-1423284651,671593195,-1039978571,2073724613,145085239,-2014171096,-1515052097,1790575107,-2107839210,472615631,-1265457287,-219090169,-492745111,-187865638,-1093335547,1646252340,-24460122,1402811438,1436590835,-516815478,-344611594,-331805821,-274055072,-1626972559,273792366,-1963377119,104699613,95345982,-1119466010,-1917480620,1560637892,-730921978,369057872,-81520232,-375925059,1137477952,-1636341799,1119727848,-1954019447,1530455833,-287606328,172466556,266959938,516552836,0,-2038232704,-314035669,1890328081,1917742170,-262898,945164165,-719438418,958871085,-647755249,-1507760036,1423022939,775562294,1739656202,-418409641,-1764576018,-1851909221,-984645440,547512796,1265195639,437656594,-1173691757,719700128,-532464606,387781147,218828297,-944901493,-1464259146,-1446505442,428169201,122466165,-574886247,1627235199,648017665,-172204942,1002783846,2117360635,695634755,-958608605,-60246291,-245122844,-590686415,-2062531997,574624663,287343814,612205898,1039717051,840019705,-1586641111,793451934,821288114,1391201670,-472877119,376187827,-1181111952,1224348052,1679968233,-1933268740,1058709744,752375421,-1863376333,1321699145,-775825096,-1560376118,188127444,-2117097739,-567761542,-1910056265,-1079754835,-1645990854,-1844621192,-862229921,1180849278,331544205,-1192718120,-144822727,-1342864701,-2134991011,-1820562992,766078933,313773861,-1724135252,2108100632,1668212892,-1149510853,2013908262,418672217,-1224610662,-1700232369,1852171925,-427906305,-821550660,-387518699,-1680229657,919489135,164948639,2094410160,-1297141340,590424639,-1808742747,1723872674,-1137216434,-895026046,-793714544,-669699161,-1739919100,-621329940,1343127501,-164685935,-695372211,-1337113617,1297403050,81781910,-1243373871,-2011476886,532201772,1367295589,-368796322,895287692,1953757831,1093597963,492483431,-766340389,1446242576,1192455638,1636604631,209336225,344873464,1015671571,669961897,-919226527,-437395172,-1321436601,-547775278,1933530610,-830924780,935293895,-840281097,-1436852227,1863638845,-611944380,-209597777,-1002522264,875313188,1080017571,-1015933411,621591778,1233856572,-1790836979,24197544,-1277294580,-459482956,-1047501738,-2073986101,-1234119374,1551124588,1463996600],[-190361519,1097159550,396673818,660510266,-1418998981,-1656360673,-94852180,-486304949,821712160,1986918061,-864644728,38544885,-438830001,718002117,893681702,1654886325,-1319482914,-1172609243,-368142267,-20913827,796197571,1290801793,1184342925,-738605461,-1889540349,-1835231979,1836772287,1381620373,-1098699308,1948373848,-529979063,-909622130,-1031181707,-1904641804,1480485785,-1183720153,-514869570,-2001922064,548169417,-835013507,-548792221,439452389,1362321559,1400849762,1685577905,1806599355,-2120213250,137073913,1214797936,1174215055,-563312748,2079897426,1943217067,1258480242,529487843,1437280870,-349698126,-1245576401,-981755258,923313619,679998000,-1079659997,57326082,377642221,-820237430,2041877159,133361907,1776460110,-621490843,96392454,878845905,-1493267772,777231668,-212492126,-1964953083,-152341084,-2081670901,1626319424,1906247262,1846563261,562755902,-586793578,1040559837,-423803315,1418573201,-1000536719,114585348,1343618912,-1728371687,-1108764714,1078185097,-643926169,-398279248,-1987344377,425408743,-923870343,2081048481,1108339068,-2078357000,0,-2138668279,736970802,292596766,1517440620,251657213,-2059905521,-1361764803,758720310,265905162,1554391400,1532285339,908999204,174567692,1474760595,-292105548,-1684955621,-1060810880,-601841055,2001430874,303699484,-1816524062,-1607801408,585122620,454499602,151849742,-1949848078,-1230456531,514443284,-249985705,1963412655,-1713521682,2137062819,19308535,1928707164,1715193156,-75615141,1126790795,600235211,-302225226,-453942344,836553431,1669664834,-1759363053,-971956092,1243905413,-1153566510,-114159186,698445255,-1641067747,-1305414692,-2041385971,-1042034569,-1290376149,1891211689,-1807156719,-379313593,-57883480,-264299872,2100090966,865136418,1229899655,953270745,-895287668,-737462632,-176042074,2061379749,-1215420710,-1379949505,983426092,2022837584,1607244650,2118541908,-1928084746,-658970480,972512814,-1011878526,1568718495,-795640727,-718427793,621982671,-1399243832,410887952,-1671205144,1002142683,645401037,1494807662,-1699282452,1335535747,-1787927066,-1671510,-1127282655,367585007,-409216582,1865862730,-1626745622,-1333995991,-1531793615,1059270954,-1517014842,-1570324427,1320957812,-2100648196,-1865371424,-1479011021,77089521,-321194175,-850391425,-1846137065,1305906550,-273658557,-1437772596,-1778065436,-776608866,1787304780,740276417,1699839814,1592394909,-1942659839,-2022411270,188821243,1729977011,-606973294,274084841,-699985043,-681472870,-1593017801,-132870567,322734571,-1457000754,1640576439,484830689,1202797690,-757114468,-227328171,349075736,-952647821,-137500077,-39167137,1030690015,1155237496,-1342996022,1757691577,607398968,-1556062270,499347990,-500888388,1011452712,227885567,-1476300487,213114376,-1260086056,1455525988,-880516741,850817237,1817998408,-1202240816],[82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212,164,92,204,93,101,182,146,108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125]]]
|
4
|
+
end
|
5
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
module SJCL::BitArray
|
2
|
+
SMASK32 = (1 << 31) # Signed 32 mask
|
3
|
+
|
4
|
+
def self.bitSlice(arr, bstart, bend=0)
|
5
|
+
a = arr.dup
|
6
|
+
a = shiftRight(a.slice(bstart/32,a.length), 32 - (bstart & 31)).slice(1,a.length-1)
|
7
|
+
bend == 0 ? a : clamp(a, bend-bstart)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.extract(arr, bstart, blength)
|
11
|
+
sh = (-bstart-blength) & 31
|
12
|
+
if ((bstart + blength - 1 ^ bstart) & -32)
|
13
|
+
x = lshift(arr[bstart/32|0], 32 - sh) ^ (arr[bstart/33|0] >> sh);
|
14
|
+
else
|
15
|
+
x = lshift(arr[bstart/32|0], sh);
|
16
|
+
end
|
17
|
+
return (x & (lshift(1,blength) - 1));
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.lshift(n, a)
|
21
|
+
(n << a) & 0x7FFFFFFF
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.bitLength(a)
|
25
|
+
l = a.length
|
26
|
+
return 0 if (l === 0)
|
27
|
+
x = a[l - 1];
|
28
|
+
return (l-1) * 32 + getPartial(x);
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.clamp(arr, len)
|
32
|
+
a = arr.dup
|
33
|
+
return a if (a.length * 32) < len
|
34
|
+
a = a.slice(0, (len / 32.0).ceil);
|
35
|
+
l = a.length;
|
36
|
+
len = len & 31;
|
37
|
+
if (l > 0 && len > 0)
|
38
|
+
a[l-1] = partial(len, a[l-1] & -(0x80000000 >> (len-1)), 1);
|
39
|
+
end
|
40
|
+
a
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.concat(a1, a2)
|
44
|
+
return a1 + a2 if (a1.length === 0 || a2.length === 0)
|
45
|
+
last = a1[a1.length-1]
|
46
|
+
shift = getPartial(last)
|
47
|
+
if (shift === 32)
|
48
|
+
return a1 + a2
|
49
|
+
else
|
50
|
+
return shiftRight(a2, shift, last, a1.slice(0,a1.length-1))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.partial(len, x, _end=0)
|
55
|
+
return x if len == 32
|
56
|
+
if _end == 1
|
57
|
+
part = x|0
|
58
|
+
else
|
59
|
+
part = x << 32-len
|
60
|
+
end
|
61
|
+
part &= 0xFFFFFFFF # Force to 32 bits
|
62
|
+
# Nasty due to JS defaulting to signed 32
|
63
|
+
if part > 0x7FFFFFFF
|
64
|
+
part - 0xFFFFFFFF - 1 + len * 0x10000000000
|
65
|
+
else
|
66
|
+
part + len * 0x10000000000
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.getPartial(x)
|
71
|
+
bits = (x.to_f/0x10000000000).round
|
72
|
+
return bits > 0 ? bits : 32
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.shiftRight(a, shift, carry=0, out=[])
|
76
|
+
out = out.dup
|
77
|
+
last2 = 0
|
78
|
+
while shift >= 32
|
79
|
+
out.push(carry)
|
80
|
+
carry = 0
|
81
|
+
shift -= 32
|
82
|
+
end
|
83
|
+
if (shift === 0)
|
84
|
+
return out.concat(a)
|
85
|
+
end
|
86
|
+
a.length.times do |i|
|
87
|
+
out.push(carry | (a[i] & 0xFFFFFFFF)>>shift)
|
88
|
+
carry = (a[i] << (32-shift) & 0xFFFFFFFF)
|
89
|
+
end
|
90
|
+
last2 = a.length > 0 ? a[a.length-1] : 0
|
91
|
+
shift2 = getPartial(last2)
|
92
|
+
out.push(partial((shift+shift2) & 31, (shift + shift2 > 32) ? carry : out.pop(),1))
|
93
|
+
return out;
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.xor4(x,y)
|
97
|
+
if x.length < 4 || y.length < 4
|
98
|
+
x = zero_array(x, 4)
|
99
|
+
y = zero_array(y, 4)
|
100
|
+
end
|
101
|
+
mask32 [x[0]^y[0],x[1]^y[1],x[2]^y[2],x[3]^y[3]]
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.mask32(arr)
|
105
|
+
out = []
|
106
|
+
for a in arr
|
107
|
+
out << (a & 0xFFFFFFFF)
|
108
|
+
end
|
109
|
+
out
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.zero_array(arr, amount)
|
113
|
+
out = []
|
114
|
+
amount.times do |i|
|
115
|
+
out[i] = arr[i] || 0
|
116
|
+
end
|
117
|
+
arr
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.convertToSigned32(arr)
|
121
|
+
out = []
|
122
|
+
for n in arr
|
123
|
+
n = n & 0xFFFFFFFF if n > 0xFFFFFFF
|
124
|
+
if n > SMASK32
|
125
|
+
n = (n & ~SMASK32) - (n & SMASK32)
|
126
|
+
out.push n
|
127
|
+
else
|
128
|
+
out.push n
|
129
|
+
end
|
130
|
+
end
|
131
|
+
out
|
132
|
+
end
|
133
|
+
|
134
|
+
# caveat: clears out of band data
|
135
|
+
def self.convertToUnsigned32(arr)
|
136
|
+
out = []
|
137
|
+
for n in arr
|
138
|
+
out.push(n & 0xFFFFFFFF)
|
139
|
+
end
|
140
|
+
out
|
141
|
+
end
|
142
|
+
|
143
|
+
# Compare two SJCL type BitArrays
|
144
|
+
# caveat: ignore out of band data
|
145
|
+
def self.compare(arr1, arr2)
|
146
|
+
return false if arr1.length != arr2.length
|
147
|
+
arr1 = convertToSigned32(arr1)
|
148
|
+
arr2 = convertToSigned32(arr2)
|
149
|
+
(arr1.length- 1).times do |i|
|
150
|
+
return false if arr1[i] != arr2[i]
|
151
|
+
end
|
152
|
+
# The last word is a funky use of a double
|
153
|
+
return false if arr2[arr2.length - 1] != arr1[arr1.length - 1]
|
154
|
+
return true
|
155
|
+
end
|
156
|
+
end
|
data/lib/sjcl/ccm.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
module SJCL::Mode
|
2
|
+
module CCM
|
3
|
+
NAME = "ccm"
|
4
|
+
|
5
|
+
def self.encrypt(prf, plaintext, iv, adata=[], tlen=64)
|
6
|
+
ccml = 2
|
7
|
+
out = plaintext.dup
|
8
|
+
ivl = SJCL::BitArray.bitLength(iv) / 8
|
9
|
+
ol = SJCL::BitArray.bitLength(out) / 8
|
10
|
+
raise "ccm: IV must be at least 7 bytes" if ivl < 7
|
11
|
+
while ccml < 4 && ((ol & 0xFFFFFFFF) >> 8*ccml > 0)
|
12
|
+
ccml += 1
|
13
|
+
end
|
14
|
+
ccml = 15 - ivl if ccml < 15 - ivl
|
15
|
+
iv = SJCL::BitArray.clamp(iv,8*(15-ccml));
|
16
|
+
tag = computeTag(prf, plaintext, iv, adata, tlen, ccml)
|
17
|
+
|
18
|
+
# encrypt
|
19
|
+
out = ctrMode(prf, out, iv, tag, tlen, ccml)
|
20
|
+
SJCL::BitArray.concat(out[:data], out[:tag])
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.decrypt(prf, ciphertext, iv, adata=[], tlen=64)
|
24
|
+
ccml = 2
|
25
|
+
ivl = SJCL::BitArray.bitLength(iv) / 8
|
26
|
+
ol = SJCL::BitArray.bitLength(ciphertext)
|
27
|
+
out = SJCL::BitArray.clamp(ciphertext, ol - tlen)
|
28
|
+
tag = SJCL::BitArray.bitSlice(ciphertext, ol - tlen)
|
29
|
+
|
30
|
+
ol = (ol - tlen) / 8;
|
31
|
+
raise "ccm: iv must be at least 7 bytes" if (ivl < 7)
|
32
|
+
|
33
|
+
# compute the length of the length
|
34
|
+
while ccml < 4 && ((ol & 0xFFFFFFFF) >> 8*ccml > 0)
|
35
|
+
ccml += 1
|
36
|
+
end
|
37
|
+
|
38
|
+
if (ccml < 15 - ivl)
|
39
|
+
ccml = 15-ivl
|
40
|
+
end
|
41
|
+
iv = SJCL::BitArray.clamp(iv,8*(15-ccml))
|
42
|
+
|
43
|
+
# decrypt
|
44
|
+
out = ctrMode(prf, out, iv, tag, tlen, ccml)
|
45
|
+
|
46
|
+
# check the tag
|
47
|
+
tag2 = computeTag(prf, out[:data], iv, adata, tlen, ccml)
|
48
|
+
if (!SJCL::BitArray.compare(out[:tag], tag2))
|
49
|
+
raise "ccm: tag doesn't match"
|
50
|
+
end
|
51
|
+
return out[:data]
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.computeTag(prf, plaintext, iv, adata, tlen, l)
|
55
|
+
tlen /= 8
|
56
|
+
if (tlen % 2 != 0 || tlen < 4 || tlen > 16)
|
57
|
+
raise "ccm: invalid tag length"
|
58
|
+
end
|
59
|
+
|
60
|
+
# mac the flags
|
61
|
+
mac = [SJCL::BitArray.partial(8, (adata.length > 0 ? 1<<6 : 0) | ((tlen-2) << 2) | l-1)]
|
62
|
+
|
63
|
+
# mac the iv and length
|
64
|
+
mac = SJCL::BitArray.concat(mac, iv)
|
65
|
+
mac[3] = (mac[3] || 0) | SJCL::BitArray.bitLength(plaintext)/8
|
66
|
+
mac = prf.encrypt(mac)
|
67
|
+
i=0
|
68
|
+
|
69
|
+
if (adata.length > 0)
|
70
|
+
# mac the associated data. start with its length...
|
71
|
+
tmp = SJCL::BitArray.bitLength(adata)/8;
|
72
|
+
if (tmp <= 0xFEFF)
|
73
|
+
macData = [SJCL::BitArray.partial(16, tmp)];
|
74
|
+
elsif (tmp <= 0xFFFFFFFF)
|
75
|
+
macData = SJCL::BitArray.concat([SJCL::BitArray.partial(16,0xFFFE)], [tmp]);
|
76
|
+
end
|
77
|
+
|
78
|
+
# mac the data itself
|
79
|
+
macData = SJCL::BitArray.concat(macData, adata);
|
80
|
+
while i < macData.length
|
81
|
+
mac = prf.encrypt(SJCL::BitArray.xor4(mac, macData.slice(i,i+4).concat([0,0,0])));
|
82
|
+
i+=4
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
i = 0
|
87
|
+
while i < plaintext.length
|
88
|
+
mac = prf.encrypt(SJCL::BitArray.xor4(mac, plaintext.slice(i,i+4).concat([0,0,0])));
|
89
|
+
i+=4
|
90
|
+
end
|
91
|
+
|
92
|
+
SJCL::BitArray.clamp(mac, tlen * 8)
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.ctrMode(prf, data, iv, tag, tlen, ccml)
|
96
|
+
l = data.length
|
97
|
+
data = data.dup
|
98
|
+
bl= SJCL::BitArray.bitLength(data)
|
99
|
+
ctr = SJCL::BitArray.concat([SJCL::BitArray.partial(8,ccml-1)],iv).concat([0,0,0]).slice(0,4)
|
100
|
+
tag = SJCL::BitArray.xor4(tag,prf.encrypt(ctr))
|
101
|
+
tag = SJCL::BitArray.bitSlice(tag, 0, tlen)
|
102
|
+
return {tag:tag, data:[]} if (l == 0)
|
103
|
+
i = 0
|
104
|
+
while i < l
|
105
|
+
ctr[3] += 1;
|
106
|
+
enc = prf.encrypt(ctr);
|
107
|
+
data[i] = (data[i] || 0) ^ enc[0];
|
108
|
+
data[i+1] = (data[i+1] || 0) ^ enc[1];
|
109
|
+
data[i+2] = (data[i+2] || 0) ^ enc[2];
|
110
|
+
data[i+3] = (data[i+3] || 0) ^ enc[3];
|
111
|
+
i += 4
|
112
|
+
end
|
113
|
+
return { tag: tag, data: SJCL::BitArray.clamp(data,bl) }
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module SJCL::Codec
|
2
|
+
module Base64
|
3
|
+
CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
4
|
+
def self.fromBits(arr, noEquals=false, url=false)
|
5
|
+
out = ""
|
6
|
+
bits=0
|
7
|
+
c = CHARS.dup
|
8
|
+
ta=0
|
9
|
+
i = 0
|
10
|
+
bl = SJCL::BitArray.bitLength(arr)
|
11
|
+
if (url)
|
12
|
+
c = c[0,62] + '-_';
|
13
|
+
end
|
14
|
+
while (out.length * 6) < bl
|
15
|
+
a = (arr[i] & 0xFFFFFFFF) || 0
|
16
|
+
out += c[(ta ^ a >> bits) >> 26,1]
|
17
|
+
if (bits < 6)
|
18
|
+
ta = (a << (6-bits)) & 0xFFFFFFFF
|
19
|
+
bits += 26
|
20
|
+
i += 1
|
21
|
+
else
|
22
|
+
ta = (ta << 6) & 0xFFFFFFFF
|
23
|
+
bits -= 6
|
24
|
+
end
|
25
|
+
end
|
26
|
+
while ((out.length & 3 > 0) && !noEquals)
|
27
|
+
out += "="
|
28
|
+
end
|
29
|
+
return out
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.toBits(str, url=false)
|
33
|
+
i=0
|
34
|
+
bits = 0
|
35
|
+
ta = 0
|
36
|
+
c = CHARS.dup
|
37
|
+
out = []
|
38
|
+
if (url)
|
39
|
+
c = c[0,62] + '-_'
|
40
|
+
end
|
41
|
+
while (i < str.length)
|
42
|
+
str = str.gsub(/\s|=/, '')
|
43
|
+
x = c.index(str[i]);
|
44
|
+
unless x
|
45
|
+
raise "this isn't base64!"
|
46
|
+
end
|
47
|
+
if (bits > 26)
|
48
|
+
bits -= 26;
|
49
|
+
out << ((ta ^ x >> bits) & 0xFFFFFFFF)
|
50
|
+
ta = x << (32-bits)
|
51
|
+
ta &= 0xFFFFFFFF
|
52
|
+
else
|
53
|
+
bits += 6
|
54
|
+
ta ^= x << (32-bits)
|
55
|
+
ta &= 0xFFFFFFFF
|
56
|
+
end
|
57
|
+
i += 1
|
58
|
+
end
|
59
|
+
if (bits&56 > 0)
|
60
|
+
out.push(SJCL::BitArray.partial(bits & 56, ta, 1));
|
61
|
+
end
|
62
|
+
return out
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SJCL::Codec
|
2
|
+
module Hex
|
3
|
+
def self.fromBits(arr)
|
4
|
+
out = ""
|
5
|
+
arr.length.times do |i|
|
6
|
+
out += ((arr[i] & 0xFFFFFFFF)|0).to_s(16).rjust(8,'0')[0,8]
|
7
|
+
end
|
8
|
+
return out[0, SJCL::BitArray.bitLength(arr)/4]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.toBits(str)
|
12
|
+
out = []
|
13
|
+
len = str.length
|
14
|
+
str = str + "00000000"
|
15
|
+
i = 0
|
16
|
+
while i < str.length
|
17
|
+
out.push(str[i,8].to_i(16) ^ 0)
|
18
|
+
i += 8
|
19
|
+
end
|
20
|
+
return SJCL::BitArray.clamp(out, len*4)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
module SJCL::Codec
|
5
|
+
module UTF8String
|
6
|
+
def self.fromBits(arr)
|
7
|
+
out = []
|
8
|
+
bl = SJCL::BitArray.bitLength(arr)
|
9
|
+
i = 0
|
10
|
+
tmp = 0
|
11
|
+
(bl/8).times do
|
12
|
+
if ((i&3) === 0)
|
13
|
+
tmp = arr[i/4]
|
14
|
+
end
|
15
|
+
out << (tmp >> 24)
|
16
|
+
tmp <<= 8
|
17
|
+
i += 1
|
18
|
+
end
|
19
|
+
out.pack('C*').force_encoding('utf-8')
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.toBits(str)
|
23
|
+
str_arr = str.unpack("C*")
|
24
|
+
out = []
|
25
|
+
tmp=0
|
26
|
+
i=0
|
27
|
+
str_arr.length.times do
|
28
|
+
tmp = tmp << 8 | str_arr[i]
|
29
|
+
if ((i&3) === 3)
|
30
|
+
out.push(tmp);
|
31
|
+
tmp = 0;
|
32
|
+
end
|
33
|
+
i += 1
|
34
|
+
end
|
35
|
+
if (i&3 != 0)
|
36
|
+
out.push(SJCL::BitArray.partial(8*(i&3), tmp));
|
37
|
+
end
|
38
|
+
return out
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/sjcl/pbkdf2.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
module SJCL
|
5
|
+
module Misc
|
6
|
+
|
7
|
+
def self.pbkdf2(password, salt, iter, length)
|
8
|
+
salt = Base64.decode64(salt)
|
9
|
+
key = SJCL::PBKDF2.new(:password=>password,
|
10
|
+
:salt=>salt,
|
11
|
+
:key_length => length/8,
|
12
|
+
:iterations=>iter).hex_string
|
13
|
+
SJCL::Codec::Hex.toBits(key)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# Pilfered from https://github.com/emerose and updated to Ruby >2.0
|
21
|
+
class SJCL::PBKDF2
|
22
|
+
def initialize(opts={})
|
23
|
+
@hash_function = OpenSSL::Digest.new("sha256")
|
24
|
+
|
25
|
+
# override with options
|
26
|
+
opts.each_key do |k|
|
27
|
+
if self.respond_to?("#{k}=")
|
28
|
+
self.send("#{k}=", opts[k])
|
29
|
+
else
|
30
|
+
raise ArgumentError, "Argument '#{k}' is not allowed"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
yield self if block_given?
|
35
|
+
|
36
|
+
# set this to the default if nothing was given
|
37
|
+
@key_length ||= @hash_function.size
|
38
|
+
|
39
|
+
# make sure the relevant things got set
|
40
|
+
raise ArgumentError, "password not set" if @password.nil?
|
41
|
+
raise ArgumentError, "salt not set" if @salt.nil?
|
42
|
+
raise ArgumentError, "iterations not set" if @iterations.nil?
|
43
|
+
end
|
44
|
+
attr_reader :key_length, :hash_function, :iterations, :salt, :password
|
45
|
+
|
46
|
+
def key_length=(l)
|
47
|
+
raise ArgumentError, "key too short" if l < 1
|
48
|
+
raise ArgumentError, "key too long" if l > ((2**32 - 1) * @hash_function.size)
|
49
|
+
@value = nil
|
50
|
+
@key_length = l
|
51
|
+
end
|
52
|
+
|
53
|
+
def hash_function=(h)
|
54
|
+
@value = nil
|
55
|
+
@hash_function = find_hash(h)
|
56
|
+
end
|
57
|
+
|
58
|
+
def iterations=(i)
|
59
|
+
raise ArgumentError, "iterations can't be less than 1" if i < 1
|
60
|
+
@value = nil
|
61
|
+
@iterations = i
|
62
|
+
end
|
63
|
+
|
64
|
+
def salt=(s)
|
65
|
+
@value = nil
|
66
|
+
@salt = s
|
67
|
+
end
|
68
|
+
|
69
|
+
def password=(p)
|
70
|
+
@value = nil
|
71
|
+
@password = p
|
72
|
+
end
|
73
|
+
|
74
|
+
def value
|
75
|
+
calculate! if @value.nil?
|
76
|
+
@value
|
77
|
+
end
|
78
|
+
|
79
|
+
alias bin_string value
|
80
|
+
|
81
|
+
def hex_string
|
82
|
+
bin_string.unpack("H*").first
|
83
|
+
end
|
84
|
+
|
85
|
+
# return number of milliseconds it takes to complete one iteration
|
86
|
+
def benchmark(iters = 400000)
|
87
|
+
iter_orig = @iterations
|
88
|
+
@iterations=iters
|
89
|
+
start = Time.now
|
90
|
+
calculate!
|
91
|
+
time = Time.now - start
|
92
|
+
@iterations = iter_orig
|
93
|
+
return (time/iters)
|
94
|
+
end
|
95
|
+
|
96
|
+
protected
|
97
|
+
|
98
|
+
# finds and instantiates, if necessary, a hash function
|
99
|
+
def find_hash(hash)
|
100
|
+
case hash
|
101
|
+
when Class
|
102
|
+
# allow people to pass in classes to be instantiated
|
103
|
+
# (eg, pass in OpenSSL::Digest::SHA1)
|
104
|
+
hash = find_hash(hash.new)
|
105
|
+
when Symbol
|
106
|
+
# convert symbols to strings and see if OpenSSL::Digest can make sense of
|
107
|
+
hash = find_hash(hash.to_s)
|
108
|
+
when String
|
109
|
+
# if it's a string, first strip off any leading 'hmacWith' (which is implied)
|
110
|
+
hash.gsub!(/^hmacWith/i,'')
|
111
|
+
# see if the OpenSSL lib understands it
|
112
|
+
hash = OpenSSL::Digest.new(hash)
|
113
|
+
when OpenSSL::Digest
|
114
|
+
when OpenSSL::Digest::Digest
|
115
|
+
# ok
|
116
|
+
else
|
117
|
+
raise TypeError, "Unknown hash type: #{hash.class}"
|
118
|
+
end
|
119
|
+
hash
|
120
|
+
end
|
121
|
+
|
122
|
+
# the pseudo-random function defined in the spec
|
123
|
+
def prf(data)
|
124
|
+
OpenSSL::HMAC.digest(@hash_function, @password, data)
|
125
|
+
end
|
126
|
+
|
127
|
+
# this is a translation of the helper function "F" defined in the spec
|
128
|
+
def calculate_block(block_num)
|
129
|
+
# u_1:
|
130
|
+
u = prf(salt+[block_num].pack("N"))
|
131
|
+
ret = u
|
132
|
+
# u_2 through u_c:
|
133
|
+
2.upto(@iterations) do
|
134
|
+
# calculate u_n
|
135
|
+
u = prf(u)
|
136
|
+
# xor it with the previous results
|
137
|
+
ret = str_xor(ret, u)
|
138
|
+
end
|
139
|
+
ret
|
140
|
+
end
|
141
|
+
|
142
|
+
# the bit that actually does the calculating
|
143
|
+
def calculate!
|
144
|
+
# how many blocks we'll need to calculate (the last may be truncated)
|
145
|
+
blocks_needed = (@key_length.to_f / @hash_function.size).ceil
|
146
|
+
# reset
|
147
|
+
@value = ""
|
148
|
+
# main block-calculating loop:
|
149
|
+
1.upto(blocks_needed) do |block_num|
|
150
|
+
@value << calculate_block(block_num)
|
151
|
+
end
|
152
|
+
# truncate to desired length:
|
153
|
+
@value = @value.slice(0,@key_length)
|
154
|
+
@value
|
155
|
+
end
|
156
|
+
|
157
|
+
def str_xor(str1, str2)
|
158
|
+
raise ArgumentError, "Can't bitwise-XOR a String with a non-String" \
|
159
|
+
unless str1.kind_of? String
|
160
|
+
raise ArgumentError, "Can't bitwise-XOR strings of different length" \
|
161
|
+
unless str2.length == str1.length
|
162
|
+
result = "".encode("ASCII-8BIT")
|
163
|
+
o_bytes = str2.bytes.to_a
|
164
|
+
str1.bytes.each_with_index do |c, i|
|
165
|
+
result << (c ^ o_bytes[i])
|
166
|
+
end
|
167
|
+
result
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
data/lib/sjcl/random.rb
ADDED
data/lib/sjcl/version.rb
ADDED
data/sjcl.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "sjcl/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "sjcl"
|
7
|
+
s.version = SJCL::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.license = "MIT"
|
10
|
+
s.authors = ["Mark Percival"]
|
11
|
+
s.email = ["mark@markpercival.us"]
|
12
|
+
s.homepage = "http://github.com/mdp/rotp"
|
13
|
+
s.summary = %q{A Ruby library for interopping with SJCL's AES crypto}
|
14
|
+
|
15
|
+
s.rubyforge_project = "sjcl"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency('rake')
|
23
|
+
s.add_development_dependency('rspec')
|
24
|
+
end
|
data/spec/aes_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "the SJCL AES cipher" do
|
4
|
+
describe "scheduling the key" do
|
5
|
+
it "should match at 128bits" do
|
6
|
+
expectedEnc = [-1029611070, -1587456955, 1398035525, 17593584058368, -473824721, 1118000746, 301400623, 1117979183, -340453629, -1458159255, -1193196730, -96321175, -1019810258, 1780526919, -759043071, 679718248, 665037594, 1300431965, -1623005092, -1212070604, 1338880947, 38713326, -1660133454, 718084742, -764414122, -803127112, 1294802698, 1742734732, 1929679827, -1557802133, -301413279, -1981232659, 1759102580, -872671969, 636803454, -1407446893, -283960603, 619646970, 18601604, -1391999465, 480766576, 944301450, 961753870, -1806371559]
|
7
|
+
expectedDec = [480766576, -1806371559, 961753870, 944301450, -286319329, -615496010, 2062433761, -793409572, -2072105771, -1581352105, -1436829123, 1046125251, -1529599379, 199606634, -1811865346, -1171999210, -614676899, -1612389996, 774215400, 519085179, 1932300365, -1312721028, 819268243, -978560474, -1259908556, -2129363473, -176598859, -1233073557, 8079113, 1953312090, 1140431582, 40343647, -1507275254, 932493188, 1100874369, 35446614, 1689034073, 1980413189, 1132649943, -1540091556, -1029611070, 17593584058368, 1398035525, -1587456955]
|
8
|
+
cipher = SJCL::Cipher::AES.new([-1029611070, -1587456955, 1398035525, 17593584058368])
|
9
|
+
SJCL::BitArray.compare(cipher.key[0], expectedEnc).should be_true
|
10
|
+
SJCL::BitArray.compare(cipher.key[1], expectedDec).should be_true
|
11
|
+
end
|
12
|
+
it "should match at 256bits" do
|
13
|
+
expectedEnc = [1181708080, 1181708080, 1181708080, 1181708080, 1181708080, 1181708080, 1181708080, 1181708080, -272143510, -1448606630, -272143510, -1448606630, -1783784050, -742198594, -1783784050, -742198594, -934361844, 1642512726, -1910396356, 663334502, 1493858749, -1966568701, 526718605, -861412301, -1876490681, -238958831, 2145414445, 1483326283, 871585550, -1187259379, -1503737216, 1794715315, 18246469, -254301100, -1892171399, -681704910, 1034625069, -2070873056, 583939744, 1211570195, -1950673385, 2070723139, -195331270, 587561224, 465606173, -1622119875, -1113695075, -173456242, 2023755761, 63747506, -141046136, -728582272, 1401896912, -857778707, 1900087664, -2065150466, -1555843922, -1601240804, 1461243796, -2088077292]
|
14
|
+
expectedDec = [-1555843922, -2088077292, 1461243796, -1601240804, -349970150, 681329711, -584960127, 1016916195, 431432362, 457480884, -564876537, -1173387270, 1389592494, -172067922, -507584670, -675345927, 199160848, -988794445, 1683696893, -1548180144, 1369923852, 335588556, 906090139, -2056489385, 1985048176, -1588912818, -941389395, -1469689536, 507794320, 570522199, -1284661044, -724887717, -1929777810, 1722324195, 1871042797, -566804688, 1011165639, -1855137125, 1738979223, -896580405, -363759219, 153963534, -1313675299, 1389285982, -1389759652, -154505972, -1389759652, -154505972, -478399101, -1197495341, -478399101, -1197495341, 1541643856, 1541643856, 1541643856, 1541643856, 1181708080, 1181708080, 1181708080, 1181708080]
|
15
|
+
cipher = SJCL::Cipher::AES.new(SJCL::Codec::UTF8String.toBits("Foo0Foo0Foo0Foo0Foo0Foo0Foo0Foo0"))
|
16
|
+
SJCL::BitArray.compare(cipher.key[0], expectedEnc).should be_true
|
17
|
+
SJCL::BitArray.compare(cipher.key[1], expectedDec).should be_true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "encrypt and decrypt cycle" do
|
22
|
+
data = SJCL::Codec::UTF8String.toBits("Secrets1Secrets2") # 16 bytes
|
23
|
+
key = SJCL::Codec::UTF8String.toBits("Foo0Foo0Foo0Foo0Foo0Foo0Foo0Foo0")
|
24
|
+
cipher = SJCL::Cipher::AES.new(key)
|
25
|
+
it "should encrypt data" do
|
26
|
+
expectedEnc = [1991380212, -38165922, 194830393, 500234942] # Taken from SJCL JS
|
27
|
+
enc = cipher.encrypt(data)
|
28
|
+
SJCL::BitArray.compare(enc, expectedEnc).should be_true
|
29
|
+
end
|
30
|
+
it "should decrypt data" do
|
31
|
+
dec = cipher.decrypt(cipher.encrypt(data))
|
32
|
+
SJCL::BitArray.compare(data, dec).should be_true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "the SJCL BitArray" do
|
4
|
+
it "work with extract" do
|
5
|
+
SJCL::BitArray.extract([1415934836, 543256164, 544042866], 0, 24).should eql(5530995)
|
6
|
+
SJCL::BitArray.extract([-123123, 2345], 8, 16).should eql(65055)
|
7
|
+
end
|
8
|
+
it "should handle partials" do
|
9
|
+
SJCL::BitArray.getPartial(26389912904448).should eql(24)
|
10
|
+
SJCL::BitArray.bitLength([26389912904448]).should eql(24)
|
11
|
+
SJCL::BitArray.getPartial(1352435907).should eql(32)
|
12
|
+
end
|
13
|
+
it "should make partials" do
|
14
|
+
SJCL::BitArray.partial(32, 27).should eql(27)
|
15
|
+
SJCL::BitArray.partial(24, 137).should eql(26388279101696)
|
16
|
+
SJCL::BitArray.partial(16, 204).should eql(17592199413760)
|
17
|
+
SJCL::BitArray.partial(8, 3271557120, 1).should eql(8795069612032)
|
18
|
+
end
|
19
|
+
it "should correclty shiftRight" do
|
20
|
+
conc = SJCL::BitArray.shiftRight([-1505830413, 1352435907], 8, 2130706432, [])
|
21
|
+
SJCL::BitArray.compare(conc, [2141601497, -212820856, 8795069612032]).should eql(true)
|
22
|
+
end
|
23
|
+
it "should clamp" do
|
24
|
+
clamped = SJCL::BitArray.clamp([2010473763, 1926277526, 2720643473, 3225629324], 128)
|
25
|
+
SJCL::BitArray.compare(clamped, [2010473763, 1926277526, 2720643473, 3225629324]).should eql(true)
|
26
|
+
clamped = SJCL::BitArray.clamp([1868310588, 3653507289, 867213828, 1392911557, 17593804424619, 3441232331, 3819666098, 3925464908], 144)
|
27
|
+
SJCL::BitArray.compare(clamped, [1868310588, 3653507289, 867213828, 1392911557, 17593804390400]).should eql(true)
|
28
|
+
end
|
29
|
+
it "should bitslice" do
|
30
|
+
sliced = SJCL::BitArray.bitSlice([2010473763, 1926277526, 2720643473, 3225629324], 0, 64)
|
31
|
+
SJCL::BitArray.compare(sliced, [2010473763, 1926277526]).should eql(true)
|
32
|
+
sliced = SJCL::BitArray.bitSlice([1830956770, 3659299964, 4136255234, 2601935920], 0, 64)
|
33
|
+
SJCL::BitArray.compare(sliced, [1830956770, 3659299964]).should eql(true)
|
34
|
+
end
|
35
|
+
it "should concat two bit arrays" do
|
36
|
+
conc = SJCL::BitArray.concat([8798223728640],[-1505830413, 1352435907])
|
37
|
+
SJCL::BitArray.compare(conc, [2141601497, -212820856, 8795069612032]).should eql(true)
|
38
|
+
expected = [2215220552, 2472502247, 2970193637, 3874452154, -1941053952, -922223310, 17590738944000]
|
39
|
+
conc = SJCL::BitArray.concat([2215220552, 2472502247, 2970193637, 3874452154, 17590244933632] ,[3724593415, 4247955903])
|
40
|
+
SJCL::BitArray.compare(conc, expected).should eql(true)
|
41
|
+
end
|
42
|
+
end
|
data/spec/ccm_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "CCM Mode" do
|
4
|
+
cipher = SJCL::Cipher::AES.new(SJCL::Codec::UTF8String.toBits("Foo0Foo0Foo0Foo0Foo0Foo0Foo0Foo0"))
|
5
|
+
plaintext = SJCL::Codec::UTF8String.toBits("Plaintext is plain")
|
6
|
+
adata = SJCL::Codec::UTF8String.toBits("adata")
|
7
|
+
iv = [-1505830413, 1352435907]
|
8
|
+
describe "computing a tag" do
|
9
|
+
it "should match SJCL CCM tags" do
|
10
|
+
tag = SJCL::Mode::CCM.computeTag(cipher, plaintext, iv, adata, 64, 7)
|
11
|
+
SJCL::BitArray.compare(tag, [115834909, 246978874]).should eql(true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
describe "ctr mode" do
|
15
|
+
it "should match SJCL ctr mode" do
|
16
|
+
expected = {tag:[1830956770,-635667332],data:[1868310588,-641460007,867213828,1392911557,17593804390400]}
|
17
|
+
ctrEnc = SJCL::Mode::CCM.ctrMode(cipher, plaintext, iv, adata, 64, 13)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
describe "encrypting" do
|
21
|
+
it "should match SJCL encryption with adata" do
|
22
|
+
expected = [-2079746744, -1822465049, -1324773659, -420515142, -1941053952, -922223310, 17590738944000]
|
23
|
+
enc = SJCL::Mode::CCM.encrypt(cipher, plaintext, iv, adata)
|
24
|
+
SJCL::BitArray.compare(enc, expected).should eql(true)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
describe "decrypting" do
|
28
|
+
it "should match SJCL encryption with adata" do
|
29
|
+
enc = SJCL::Mode::CCM.encrypt(cipher, plaintext, iv, adata)
|
30
|
+
dec = SJCL::Mode::CCM.decrypt(cipher, enc, iv, adata)
|
31
|
+
SJCL::BitArray.compare(dec, plaintext).should eql(true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "the SJCL Base64 codec" do
|
4
|
+
it "should encode to Base64" do
|
5
|
+
input = [64820773, -671820644, 623614257, 1785858591, -135874193, -1906550637, -1401277189, -259576026]
|
6
|
+
dec = SJCL::Codec::Base64.fromBits(input)
|
7
|
+
expected = "A90WJdf01JwlK5kxanIKH/fmuW+OXFiTrHo0+/CHLyY="
|
8
|
+
dec.should eql(expected)
|
9
|
+
end
|
10
|
+
it "should decode from bit array" do
|
11
|
+
input = "A90WJdf01JwlK5kxanIKH/fmuW+OXFiTrHo0+/CHLyY="
|
12
|
+
expected = [64820773, -671820644, 623614257, 1785858591, -135874193, -1906550637, -1401277189, -259576026]
|
13
|
+
enc = SJCL::Codec::Base64.toBits(input)
|
14
|
+
SJCL::BitArray.compare(enc, expected).should eql(true)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe "the SJCL string codec" do
|
5
|
+
it "should encode a string" do
|
6
|
+
SJCL::Codec::UTF8String.toBits("a").should eql([8797720412160])
|
7
|
+
SJCL::Codec::UTF8String.toBits("abc").should eql([26389912904448])
|
8
|
+
SJCL::Codec::UTF8String.toBits("abcd").should eql([1633837924])
|
9
|
+
SJCL::Codec::UTF8String.toBits("This is a test!").should eql([1416128883, 543781664, 1629516901, 26390216057088])
|
10
|
+
SJCL::Codec::UTF8String.toBits("ェア").should eql([3816990691, 17590082732032])
|
11
|
+
end
|
12
|
+
it "should decode a string" do
|
13
|
+
SJCL::Codec::UTF8String.fromBits([1416128883, 543781664, 1629516901, 26390216057088]).should eql("This is a test!")
|
14
|
+
SJCL::Codec::UTF8String.fromBits([-1029614491, 26390216057088]).should eql("¡Test!")
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe "the SJCL hex codec" do
|
5
|
+
it "should encode from hex" do
|
6
|
+
dec = SJCL::Codec::Hex.toBits("03dd1625d7f4d49c252b99316a720a1ff7e6b96f8e5c5893ac7a34fbf0872f26")
|
7
|
+
expected = [64820773, -671820644, 623614257, 1785858591, -135874193, -1906550637, -1401277189, -259576026]
|
8
|
+
SJCL::BitArray.compare(dec, expected).should eql(true)
|
9
|
+
end
|
10
|
+
it "should decode from bit array" do
|
11
|
+
enc = SJCL::Codec::Hex.fromBits([64820773, -671820644, 623614257, 1785858591, -135874193, -1906550637, -1401277189, -259576026])
|
12
|
+
enc.should eql("03dd1625d7f4d49c252b99316a720a1ff7e6b96f8e5c5893ac7a34fbf0872f26")
|
13
|
+
enc = SJCL::Codec::Hex.fromBits([1634952294, 26389914019328])
|
14
|
+
enc.should eql("61736466617366")
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe "the SJCL aes crypto" do
|
5
|
+
# Made with
|
6
|
+
# sjcl.encrypt("s33krit", "This is a secret", {iter:10000, ks:256})
|
7
|
+
it "should decrypt text from SJCL.js" do
|
8
|
+
json = '{"iv":"OE68TjT18tvKwwZ9aGgKsw==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"e6txfS7y6wg=","ct":"RHYb19HUMcZb5/p9u1yd+ofyQRGHIuph"}'
|
9
|
+
result = SJCL.decrypt('s33krit', json)
|
10
|
+
result.should eql("This is a secret")
|
11
|
+
end
|
12
|
+
it "should handle UTF-8" do
|
13
|
+
json = '{"iv":"+Y+RZjk81MN9wkLVRgfLkA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"4TD5tILYe6U=","ct":"NUeGvbXWVEmssnSGORpVSl1OefdLHjU2yPZnxVsPifyD1TJ3+w=="}'
|
14
|
+
result = SJCL.decrypt('s33krit', json)
|
15
|
+
result.should eql("农历新年 and 農曆新年")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should encrypt text for SJCL.js" do
|
19
|
+
plaintext = "Raw denim fanny pack gastropub, cardigan irony biodiesel pop-up. 3 wolf moon Godard sartorial authentic fingerstache, lo-fi Etsy aesthetic. Fixie 3 wolf moon photo booth, mustache cliche sustainable artisan. Fingerstache chillwave ethnic distillery Tonx. Farm-to-table ethnic paleo keytar. Fanny pack chambray quinoa, mlkshk you probably haven't heard of them letterpress fashion axe. Literally Pinterest Schlitz, typewriter ennui sustainable ugh hella kitsch."
|
20
|
+
result = SJCL.encrypt('s33krit', plaintext)
|
21
|
+
SJCL.decrypt('s33krit', result).should eql(plaintext)
|
22
|
+
puts "sjcl.decrypt('s33krit','#{result}')"
|
23
|
+
# Checking this by hand for now :(
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should encrypt UTF-8 text" do
|
27
|
+
result = SJCL.encrypt('s33krit', "农历新年 and 農曆新年")
|
28
|
+
puts "sjcl.decrypt('s33krit','#{result}')"
|
29
|
+
# Checking this by hand for now :(
|
30
|
+
end
|
31
|
+
end
|
data/spec/pbkdf2_spec.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
3
|
+
|
4
|
+
describe "the pbkdf2 function" do
|
5
|
+
# Made with
|
6
|
+
# sjcl.misc.pbkdf2("s33krit", [1788155662, -333625222], 10000, 256)
|
7
|
+
it "Should match the SJCL version" do
|
8
|
+
expected = [1281834603, 873294941, -458308553, 416318112, -296447020, -914288361, -236896704, 960061983]
|
9
|
+
key = SJCL::Misc.pbkdf2("s33krit", "apUXDuwdSHo=", 10000, 256)
|
10
|
+
SJCL::BitArray.compare(expected, key).should eql(true)
|
11
|
+
end
|
12
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sjcl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Percival
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- mark@markpercival.us
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".travis.yml"
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- lib/sjcl.rb
|
55
|
+
- lib/sjcl/aes.rb
|
56
|
+
- lib/sjcl/aes_tables.rb
|
57
|
+
- lib/sjcl/bit_array.rb
|
58
|
+
- lib/sjcl/ccm.rb
|
59
|
+
- lib/sjcl/codec_base64.rb
|
60
|
+
- lib/sjcl/codec_hex.rb
|
61
|
+
- lib/sjcl/codec_string.rb
|
62
|
+
- lib/sjcl/pbkdf2.rb
|
63
|
+
- lib/sjcl/random.rb
|
64
|
+
- lib/sjcl/version.rb
|
65
|
+
- sjcl.gemspec
|
66
|
+
- spec/aes_spec.rb
|
67
|
+
- spec/bit_array_spec.rb
|
68
|
+
- spec/ccm_spec.rb
|
69
|
+
- spec/code_base64_spec.rb
|
70
|
+
- spec/codec_string_spec.rb
|
71
|
+
- spec/codex_hex_spec.rb
|
72
|
+
- spec/integration_spec.rb
|
73
|
+
- spec/pbkdf2_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
homepage: http://github.com/mdp/rotp
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project: sjcl
|
95
|
+
rubygems_version: 2.1.11
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: A Ruby library for interopping with SJCL's AES crypto
|
99
|
+
test_files:
|
100
|
+
- spec/aes_spec.rb
|
101
|
+
- spec/bit_array_spec.rb
|
102
|
+
- spec/ccm_spec.rb
|
103
|
+
- spec/code_base64_spec.rb
|
104
|
+
- spec/codec_string_spec.rb
|
105
|
+
- spec/codex_hex_spec.rb
|
106
|
+
- spec/integration_spec.rb
|
107
|
+
- spec/pbkdf2_spec.rb
|
108
|
+
- spec/spec_helper.rb
|