sjcl 0.0.1

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.
@@ -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
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ .bundle
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
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.
@@ -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
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:rspec) do |spec|
6
+ spec.pattern = 'spec/**/*_spec.rb'
7
+ spec.rspec_opts = ['-cfs --backtrace']
8
+ end
9
+
10
+ task :default => :rspec
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,10 @@
1
+ require 'securerandom'
2
+
3
+ module SJCL::Random
4
+
5
+ # Number of 4 byte words to retun
6
+ def self.randomWords(len)
7
+ SJCL::Codec::Hex.toBits(SecureRandom.hex(len*4))
8
+ end
9
+
10
+ end
@@ -0,0 +1,3 @@
1
+ module SJCL
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec'
4
+ require 'rspec/autorun'
5
+
6
+ require 'sjcl'
7
+
8
+ RSpec.configure do |config|
9
+ # some (optional) config here
10
+ end
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