encrypt command "at x bit" being ignored

If you find an issue in LiveCode but are having difficulty pinning down a reliable recipe or want to sanity-check your findings with others, this is the place.

Please have one thread per issue, and try to summarize the issue concisely in the thread title so others can find related issues here.

Moderator: Klaus

Post Reply
n.allan
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 153
Joined: Mon Mar 12, 2007 12:06 pm

encrypt command "at x bit" being ignored

Post by n.allan » Wed Jul 08, 2020 9:29 am

I am currently trying to use the encrypt command to reproduce test vectors given to me by a regulating body. The algorithm is bf-ecb. We are given a few test keys along with the plain text and cipher text.

Key = 3130313231 (hex) or 10121 (ascii)
Clear Text = 3132333435 (hex) or 12345 (ascii)
Clear Text Padded to 8 bytes = 3132333435030303 (hex) -- (3 bytes of padding requires 3 bytes of value 0x03, 4 bytes = 04040404 etc... up to 8 bytes
Cipher Text = 66B5CBFDF7E4139D (hex) (non-printable)

The padding is solved for the clear text but the key is the issue. It looks like LiveCode pads the key with zeros up to 128 bits. so the original key 3130313231 has the same result as 313031323100 or 313031323100000000 whatever. I can pad with zeros up to and beyond 128 bits and it has no effect. even with the "at bit" clause in the command.

I have tried setting the "at" bit because blowfish can (is supposed to) accommodate variable key lengths.

All the "at bit" seems to do is throw an error if the key length doesn't match.

Code: Select all

function fromHex pHex
   return binaryEncode("H*",pHex)
end fromHex

function toHex pData
   local tHex
   get binaryDecode("H*",pData,tHex)
   return tHex
end toHex

function e -- x,k
   local x,k
   put fromHex("3132333435030303") into x
   put fromHex("31303132") into k
   local kl -- key length
   put length(k) * 8 into kl
   encrypt x using "bf-ecb" with key k at kl bit
   if the result is not empty then
      return "error:" & the result
   else
      -- return raw, hex and used key length
      return it & return & toHex(byte 1 to 8 of it) & return & kl
   end if
end e
We are talking literal "keys" here and not "passwords" so salt is not used in this context and can be ignored. ECB doesn't use an Init. Vector/IV so can be ignored.

I have tested the provided vectors using blowfish.js http://sladex.org/blowfish.js/ and Online Domain Tools http://blowfish.online-domain-tools.com the results match the test vector I have been given. I am finding it very difficult to reproduce these test vectors in LiveCode however due to my key length.

I have also tested LiveCode against the official blowfish test vectors provided at https://www.schneier.com/code/vectors.txt I can reproduce these test vectors no problem in LC. To reproduce these I simply concatenate 2 sets of keys to make the key up to 128 bits. Works like a charm if your key is divisible by 128 bits but unfortunately mine isn't.

I have also tried concatenating my keys up to and over the 128 bit mark but it seems to restart the key after 128 bits regardless of the length I have set.

Does anyone have any ideas?

n.allan
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 153
Joined: Mon Mar 12, 2007 12:06 pm

Re: encrypt command "at x bit" being ignored

Post by n.allan » Tue Jul 14, 2020 2:13 pm

I couldn't see a way around this so I have spent a few days writing my own blowfish stuff. This is very rough (and fairly slow) at the moment but will suit my needs for the time being...

Apologies for the code but I want it to be deliberately hard to read. I have left in some comments.

This passes tests against schneier test vectors as well as the ones provided to me by the regulating body.

Code: Select all

global m32
global bx
global kbx
global i18
global i16
global i256
global i4
global max_int
global min_int

on openStack
   -- init variables and boxes with digits of pi
   
   -- helper globals for modulo maths functions
   put 2^32 into m32
   put 2147483647 into max_int
   put -1*max_int into min_int
   
   -- pre build some lists for faster looping
   put empty into i4
   put empty into i16
   put empty into i18
   put empty into i256
   repeat with i = 1 to 256
      if i <= 4 then put i & comma after i4
      if i <= 16 then put i & comma after i16
      if i <= 18 then put i & comma after i18
      put i & comma after i256
   end repeat
   delete char -1 of i4
   delete char -1 of i16
   delete char -1 of i18
   delete char -1 of i256
   
   -- init boxes
   put empty into bx
   put empty into kbx
   --p and s boxes as inegers from https://www.cs.cmu.edu/~dst/DeCSS/Baccash/blowfish.e
   put 608135816, 2242054355, 320440878, 57701188, 2752067618, 698298832, 137296536, \
         3964562569, 1160258022, 953160567, 3193202383, 887688300, 3232508343, 3380367581, \
         1065670069, 3041331479, 2450970073, 2306472731 into bx[0]
   
   put 3509652390, 2564797868, 805139163, 3491422135, 3101798381, 1780907670, 3128725573, \
         4046225305, 614570311, 3012652279, 134345442, 2240740374, 1667834072, 1901547113, \
         2757295779, 4103290238, 227898511, 1921955416, 1904987480, 2182433518, 2069144605, \
         3260701109, 2620446009, 720527379, 3318853667, 677414384, 3393288472, 3101374703, \
         2390351024, 1614419982, 1822297739, 2954791486, 3608508353, 3174124327, 2024746970, \
         1432378464, 3864339955, 2857741204, 1464375394, 1676153920, 1439316330, 715854006, \
         3033291828, 289532110, 2706671279, 2087905683, 3018724369, 1668267050, 732546397, \
         1947742710, 3462151702, 2609353502,2950085171, 1814351708, 2050118529, 680887927, \
         999245976, 1800124847, 3300911131, 1713906067, 1641548236, 4213287313, 1216130144, \
         1575780402, 4018429277, 3917837745, 3693486850, 3949271944, 596196993, 3549867205, \
         258830323, 2213823033, 772490370, 2760122372, 1774776394, 2652871518, 566650946, \
         4142492826, 1728879713, 2882767088, 1783734482, 3629395816, 2517608232, 2874225571, \
         1861159788, 326777828, 3124490320, 2130389656, 2716951837, 967770486, 1724537150, \
         2185432712, 2364442137, 1164943284, 2105845187, 998989502, 3765401048, 2244026483, \
         1075463327, 1455516326, 1322494562, 910128902, 469688178, 1117454909, 936433444, \
         3490320968, 3675253459, 1240580251, 122909385, 2157517691, 634681816, 4142456567, \
         3825094682, 3061402683, 2540495037, 79693498, 3249098678, 1084186820, 1583128258, \
         426386531, 1761308591, 1047286709, 322548459, 995290223, 1845252383, 2603652396, \
         3431023940, 2942221577, 3202600964, 3727903485, 1712269319, 422464435, 3234572375, \
         1170764815, 3523960633, 3117677531, 1434042557, 442511882, 3600875718, 1076654713, \
         1738483198, 4213154764, 2393238008, 3677496056, 1014306527, 4251020053, 793779912, \
         2902807211, 842905082, 4246964064, 1395751752, 1040244610, 2656851899, 3396308128, \
         445077038, 3742853595, 3577915638, 679411651, 2892444358, 2354009459, 1767581616, \
         3150600392, 3791627101, 3102740896, 284835224, 4246832056, 1258075500, 768725851, \
         2589189241, 3069724005, 3532540348, 1274779536, 3789419226, 2764799539, 1660621633, \
         3471099624, 4011903706, 913787905, 3497959166, 737222580, 2514213453, 2928710040, \
         3937242737, 1804850592, 3499020752, 2949064160, 2386320175, 2390070455, 2415321851, \
         4061277028, 2290661394, 2416832540, 1336762016, 1754252060, 3520065937, 3014181293, \
         791618072, 3188594551, 3933548030, 2332172193, 3852520463, 3043980520, 413987798, \
         3465142937, 3030929376, 4245938359, 2093235073, 3534596313, 375366246, 2157278981, \
         2479649556, 555357303, 3870105701, 2008414854, 3344188149, 4221384143, 3956125452, \
         2067696032, 3594591187, 2921233993, 2428461, 544322398, 577241275, 1471733935, \
         610547355, 4027169054, 1432588573, 1507829418, 2025931657, 3646575487, 545086370, \
         48609733, 2200306550, 1653985193, 298326376, 1316178497, 3007786442, 2064951626, \
         458293330, 2589141269, 3591329599, 3164325604, 727753846, 2179363840, 146436021, \
         1461446943, 4069977195, 705550613, 3059967265, 3887724982, 4281599278, 3313849956, \
         1404054877, 2845806497, 146425753, 1854211946 into bx[1]
   
   put 1266315497, 3048417604, 3681880366, 3289982499, \
         2909710000, 1235738493, 2632868024, 2414719590, 3970600049, 1771706367, \
         1449415276, 3266420449, 422970021, 1963543593, 2690192192, 3826793022, \
         1062508698, 1531092325, 1804592342, 2583117782, 2714934279, 4024971509, \
         1294809318, 4028980673, 1289560198, 2221992742, 1669523910, 35572830, \
         157838143, 1052438473, 1016535060, 1802137761, 1753167236, 1386275462, \
         3080475397, 2857371447, 1040679964, 2145300060, 2390574316, 1461121720, \
         2956646967, 4031777805, 4028374788, 33600511, 2920084762, 1018524850, \
         629373528, 3691585981, 3515945977, 2091462646, 2486323059, 586499841, \
         988145025, 935516892, 3367335476, 2599673255, 2839830854, 265290510, \
         3972581182, 2759138881, 3795373465, 1005194799, 847297441, 406762289, \
         1314163512, 1332590856, 1866599683, 4127851711, 750260880, 613907577, \
         1450815602, 3165620655, 3734664991, 3650291728, 3012275730, 3704569646, \
         1427272223, 778793252, 1343938022, 2676280711, 2052605720, 1946737175, \
         3164576444, 3914038668, 3967478842, 3682934266, 1661551462, 3294938066, \
         4011595847, 840292616, 3712170807, 616741398, 312560963, 711312465, \
         1351876610, 322626781, 1910503582, 271666773, 2175563734, 1594956187, \
         70604529, 3617834859, 1007753275, 1495573769, 4069517037, 2549218298, \
         2663038764, 504708206, 2263041392, 3941167025, 2249088522, 1514023603, \
         1998579484, 1312622330, 694541497, 2582060303, 2151582166, 1382467621, \
         776784248, 2618340202, 3323268794, 2497899128, 2784771155, 503983604, \
         4076293799, 907881277, 423175695, 432175456, 1378068232, 4145222326, \
         3954048622, 3938656102, 3820766613, 2793130115, 2977904593, 26017576, \
         3274890735, 3194772133, 1700274565, 1756076034, 4006520079, 3677328699, \
         720338349, 1533947780, 354530856, 688349552, 3973924725, 1637815568, \
         332179504, 3949051286, 53804574, 2852348879, 3044236432, 1282449977, \
         3583942155, 3416972820, 4006381244, 1617046695, 2628476075, 3002303598, \
         1686838959, 431878346, 2686675385, 1700445008, 1080580658, 1009431731, \
         832498133, 3223435511, 2605976345, 2271191193, 2516031870, 1648197032, \
         4164389018, 2548247927, 300782431, 375919233, 238389289, 3353747414, \
         2531188641, 2019080857, 1475708069, 455242339, 2609103871, 448939670, \
         3451063019, 1395535956, 2413381860, 1841049896, 1491858159, 885456874, \
         4264095073, 4001119347, 1565136089, 3898914787, 1108368660, 540939232, \
         1173283510, 2745871338, 3681308437, 4207628240, 3343053890, 4016749493, \
         1699691293, 1103962373, 3625875870, 2256883143, 3830138730, 1031889488, \
         3479347698, 1535977030, 4236805024, 3251091107, 2132092099, 1774941330, \
         1199868427, 1452454533, 157007616, 2904115357, 342012276, 595725824, \
         1480756522, 206960106, 497939518, 591360097, 863170706, 2375253569, \
         3596610801, 1814182875, 2094937945, 3421402208, 1082520231, 3463918190, \
         2785509508, 435703966, 3908032597, 1641649973, 2842273706, 3305899714, \
         1510255612, 2148256476, 2655287854, 3276092548, 4258621189, 236887753, \
         3681803219, 274041037, 1734335097, 3815195456, 3317970021, 1899903192, \
         1026095262, 4050517792, 356393447, 2410691914, 3873677099, 3682840055 \
         into bx[2]
   
   put 3913112168, 2491498743, 4132185628, 2489919796, \
         1091903735, 1979897079, 3170134830, 3567386728, 3557303409, 857797738, \
         1136121015, 1342202287, 507115054, 2535736646, 337727348, 3213592640, \
         1301675037, 2528481711, 1895095763, 1721773893, 3216771564, 62756741, \
         2142006736, 835421444, 2531993523, 1442658625, 3659876326, 2882144922, \
         676362277, 1392781812, 170690266, 3921047035, 1759253602, 3611846912, \
         1745797284, 664899054, 1329594018, 3901205900, 3045908486, 2062866102, \
         2865634940, 3543621612, 3464012697, 1080764994, 553557557, 3656615353, \
         3996768171, 991055499, 499776247, 1265440854, 648242737, 3940784050, \
         980351604, 3713745714, 1749149687, 3396870395, 4211799374, 3640570775, \
         1161844396, 3125318951, 1431517754, 545492359, 4268468663, 3499529547, \
         1437099964, 2702547544, 3433638243, 2581715763, 2787789398, 1060185593, \
         1593081372, 2418618748, 4260947970, 69676912, 2159744348, 86519011, \
         2512459080, 3838209314, 1220612927, 3339683548, 133810670, 1090789135, \
         1078426020, 1569222167, 845107691, 3583754449, 4072456591, 1091646820, \
         628848692, 1613405280, 3757631651, 526609435, 236106946, 48312990, \
         2942717905, 3402727701, 1797494240, 859738849, 992217954, 4005476642, \
         2243076622, 3870952857, 3732016268, 765654824, 3490871365, 2511836413, \
         1685915746, 3888969200, 1414112111, 2273134842, 3281911079, 4080962846, \
         172450625, 2569994100, 980381355, 4109958455, 2819808352, 2716589560, \
         2568741196, 3681446669, 3329971472, 1835478071, 660984891, 3704678404, \
         4045999559, 3422617507, 3040415634, 1762651403, 1719377915, 3470491036, \
         2693910283, 3642056355, 3138596744, 1364962596, 2073328063, 1983633131, \
         926494387, 3423689081, 2150032023, 4096667949, 1749200295, 3328846651, \
         309677260, 2016342300, 1779581495, 3079819751, 111262694, 1274766160, \
         443224088, 298511866, 1025883608, 3806446537, 1145181785, 168956806, \
         3641502830, 3584813610, 1689216846, 3666258015, 3200248200, 1692713982, \
         2646376535, 4042768518, 1618508792, 1610833997, 3523052358, 4130873264, \
         2001055236, 3610705100, 2202168115, 4028541809, 2961195399, 1006657119, \
         2006996926, 3186142756, 1430667929, 3210227297, 1314452623, 4074634658, \
         4101304120, 2273951170, 1399257539, 3367210612, 3027628629, 1190975929, \
         2062231137, 2333990788, 2221543033, 2438960610, 1181637006, 548689776, \
         2362791313, 3372408396, 3104550113, 3145860560, 296247880, 1970579870, \
         3078560182, 3769228297, 1714227617, 3291629107, 3898220290, 166772364, \
         1251581989, 493813264, 448347421, 195405023, 2709975567, 677966185, \
         3703036547, 1463355134, 2715995803, 1338867538, 1343315457, 2802222074, \
         2684532164, 233230375, 2599980071, 2000651841, 3277868038, 1638401717, \
         4028070440, 3237316320, 6314154, 819756386, 300326615, 590932579, 1405279636, \
         3267499572, 3150704214, 2428286686, 3959192993, 3461946742, 1862657033, \
         1266418056, 963775037, 2089974820, 2263052895, 1917689273, 448879540, \
         3550394620, 3981727096, 150775221, 3627908307, 1303187396, 508620638, \
         2975983352, 2726630617, 1817252668, 1876281319, 1457606340, 908771278, \
         3720792119, 3617206836, 2455994898, 1729034894, 1080033504 \
         into bx[3]
   
   put 976866871, 3556439503, 2881648439, 1522871579, \
         1555064734, 1336096578, 3548522304, 2579274686, 3574697629, 3205460757, \
         3593280638, 3338716283, 3079412587, 564236357, 2993598910, 1781952180, \
         1464380207, 3163844217, 3332601554, 1699332808, 1393555694, 1183702653, \
         3581086237, 1288719814, 691649499, 2847557200, 2895455976, 3193889540, \
         2717570544, 1781354906, 1676643554, 2592534050, 3230253752, 1126444790, \
         2770207658, 2633158820, 2210423226, 2615765581, 2414155088, 3127139286, \
         673620729, 2805611233, 1269405062, 4015350505, 3341807571, 4149409754, \
         1057255273, 2012875353, 2162469141, 2276492801, 2601117357, 993977747, \
         3918593370, 2654263191, 753973209, 36408145, 2530585658, 25011837, \
         3520020182, 2088578344, 530523599, 2918365339, 1524020338, 1518925132, \
         3760827505, 3759777254, 1202760957, 3985898139, 3906192525, 674977740, \
         4174734889, 2031300136, 2019492241, 3983892565, 4153806404, 3822280332, \
         352677332, 2297720250, 60907813, 90501309, 3286998549, 1016092578, \
         2535922412, 2839152426, 457141659, 509813237, 4120667899, 652014361, \
         1966332200, 2975202805, 55981186, 2327461051, 676427537, 3255491064, \
         2882294119, 3433927263, 1307055953, 942726286, 933058658, 2468411793, \
         3933900994, 4215176142, 1361170020, 2001714738, 2830558078, 3274259782, \
         1222529897, 1679025792, 2729314320, 3714953764, 1770335741, 151462246, \
         3013232138, 1682292957, 1483529935, 471910574, 1539241949, 458788160, \
         3436315007, 1807016891, 3718408830, 978976581, 1043663428, 3165965781, \
         1927990952, 4200891579, 2372276910, 3208408903, 3533431907, 1412390302, \
         2931980059, 4132332400, 1947078029, 3881505623, 4168226417, 2941484381, \
         1077988104, 1320477388, 886195818, 18198404, 3786409000, 2509781533, \
         112762804, 3463356488, 1866414978, 891333506, 18488651, 661792760, \
         1628790961, 3885187036, 3141171499, 876946877, 2693282273, 1372485963, \
         791857591, 2686433993, 3759982718, 3167212022, 3472953795, 2716379847, \
         445679433, 3561995674, 3504004811, 3574258232, 54117162, 3331405415, \
         2381918588, 3769707343, 4154350007, 1140177722, 4074052095, 668550556, \
         3214352940, 367459370, 261225585, 2610173221, 4209349473, 3468074219, \
         3265815641, 314222801, 3066103646, 3808782860, 282218597, 3406013506, \
         3773591054, 379116347, 1285071038, 846784868, 2669647154, 3771962079, \
         3550491691, 2305946142, 453669953, 1268987020, 3317592352, 3279303384, \
         3744833421, 2610507566, 3859509063, 266596637, 3847019092, 517658769, \
         3462560207, 3443424879, 370717030, 4247526661, 2224018117, 4143653529, \
         4112773975, 2788324899, 2477274417, 1456262402, 2901442914, 1517677493, \
         1846949527, 2295493580, 3734397586, 2176403920, 1280348187, 1908823572, \
         3871786941, 846861322, 1172426758, 3287448474, 3383383037, 1655181056, \
         3139813346, 901632758, 1897031941, 2986607138, 3066810236, 3447102507, \
         1393639104, 373351379, 950779232, 625454576, 3124240540, 4148612726, \
         2007998917, 544563296, 2244738638, 2330496472, 2058025392, 1291430526, \
         424198748, 50039436, 29584100, 3605783033, 2429876329, 2791104160, \
         1057563949, 3255363231, 3075367218, 3463963227, 1469046755, 985887462 \
         into bx[4]
   split bx[0] with comma
   split bx[1] with comma
   split bx[2] with comma
   split bx[3] with comma
   split bx[4] with comma
end openStack

function add32 x,y
   -- addition modulo 2^32
   -- overflows at 32 bit signed integer
   local z
   put x + y into z
   if z<min_int then add m32 to z
   if z>max_int then subtract m32 from z
   return z
end add32

function xor32 x,y
   -- xor modulo 2^32 function
   -- overflows 32 bit signed int
   local z,s
   if x<0 then add m32 to x
   if y<0 then add m32 to y
   put x bitxor y into z
   if z<min_int then add m32 to z
   if z>max_int then subtract m32 from z
   return z
end xor32

function pad x,l
   -- padding PKCS5 scheme
   -- https://www.cryptosys.net/pki/manpki/pki_paddingschemes.html
   if l is not a number then put 8 into l -- default 8 byte blocks
   local xp
   put l-length(x) into xp
   repeat xp times
      put fromHex(0&xp) after x
   end repeat
   return x
end pad

function eb v, cmb
   -- adapted from  BLOW 0.9 in Runtime Revolution
   -- by Michael Kuyumcu, info@noemanetz.de
   
   -- this can be used internally by the k handler to init the key boxes
   -- so it can otionally return a combines 64 bit binary string or an array with 2 x 32 bit integers
   -- if cmb parameter is true then it will return a combined string else it will return an array with 2 x 32 bit numbers
   if v is not an array then
      if length(v) <8 then put pad(v) into v
      put lr(v) into v
   end if
   local dl,dr
   put v[1] into dl
   put v[2] into dr
   repeat for each item i in i16
      put xor32(dl,kbx[0][i]) into dl
      put xor32(f(dl),dr) into dr
      get dl
      put dr into dl
      put it into dr
   end repeat
   get dl
   put dr into dl
   put it into dr
   put xor32(dr,kbx[0][17]) into dr
   put xor32(dl,kbx[0][18]) into dl
   local z
   put dl into z[1]
   put dr into z[2]
   if cmb is true then
      return clr(z)
   else
      return z
   end if
end eb

function db o
   -- adapted from http://sladex.org/blowfish.js/ext/blowfish.js
   if o is not an array then
      if length(o) <8 then put pad(o) into o
      put lr(o) into o
   end if
   local l,r
   put o[1] into l
   put o[2] into r
   put xor32(l,kbx[0][18]) into l
   put xor32(r,xor32(f(l),kbx[0][17])) into r
   put xor32(l,xor32(f(r),kbx[0][16])) into l
   put xor32(r,xor32(f(l),kbx[0][15])) into r
   put xor32(l,xor32(f(r),kbx[0][14])) into l
   put xor32(r,xor32(f(l),kbx[0][13])) into r
   put xor32(l,xor32(f(r),kbx[0][12])) into l
   put xor32(r,xor32(f(l),kbx[0][11])) into r
   put xor32(l,xor32(f(r),kbx[0][10])) into l
   put xor32(r,xor32(f(l),kbx[0][9])) into r
   put xor32(l,xor32(f(r),kbx[0][8])) into l
   put xor32(r,xor32(f(l),kbx[0][7])) into r
   put xor32(l,xor32(f(r),kbx[0][6])) into l
   put xor32(r,xor32(f(l),kbx[0][5])) into r
   put xor32(l,xor32(f(r),kbx[0][4])) into l
   put xor32(r,xor32(f(l),kbx[0][3])) into r
   put xor32(l,xor32(f(r),kbx[0][2])) into l
   put l into o[2]
   put xor32(r,kbx[0][1]) into o[1]
   return clr(o)
end db

function clr x
   return binaryEncode("MM",x[1],x[2])
end clr

function f x
   if x is not an array then put abcd(x) into x
   add 1 to x
   local a,b,c,d,z,r,s
   put kbx[1][x[1]] into a
   put kbx[2][x[2]] into b
   put kbx[3][x[3]] into c
   put kbx[4][x[4]] into d
   put add32(a,b) into r
   put xor32(r,c) into s
   put add32(s,d) into z
   return z
end f

function abcd x
   local y,z
   if x is a number then put binaryEncode("M",x) into x
   if length(x) <> 4 then
      answer error "abcd length not 4"
      return empty
   end if
   get binaryDecode("C4",x,y[1],y[2],y[3],y[4])
   if it is not 4 then
      answer error "abcd 4 bytes not decoded"
      return empty
   end if
   return y
end abcd

function lr x
   -- splits and 8 byte binary string into 2 x 4 byte signed integers
   put byte 1 to 8 of x into x -- trim to 8 bytes
   if length(x) < 8 then -- pad (should already be padded
      put pad(x) into x
   end if
   local y
   get binaryDecode("N2",x,y[1],y[2])
   if it is not 2 then
      answer error "lr not decoded"
      return empty
   end if
   return y
end lr

function toHex x
   -- helper function to encode and decode binary data
   local y
   get binaryDecode("H*",x,y)
   return toUpper(y)
end toHex

function fromHex x
   -- helper function to encode and decode binary data
   return binaryEncode("H*",x)
end fromHex

on k p
   -- k handler will encrypt the key boxes kbx with the supplied password
   put bx into kbx
   local v
   put 0 into v[1]
   put 0 into v[2]
   local kl,pa,ctr,ph,pn
   put length(p) into kl
   if length(p) = 0 then -- no password supplied, set to null byte
      put fromHex(00) into p 
      put 1 into kl
   end if
   -- need 72 bytes of repeating password to xor the entire p box so loop the password
   repeat
      put p after p
      if length(p) > 72 then exit repeat
   end repeat
   -- convert the password into 18 x 4 byte chunks
   -- xor with each item in the p box
   put 1 into ctr
   repeat for each item i in i18
      put toHex(char ctr to (ctr+3) of p) into ph
      put baseConvert(ph,16,10) into pn
      put xor32(pn,bx[0][i]) into kbx[0][i]
      add 4 to ctr
   end repeat
   -- blowfish encrypt the p box
   repeat for each item i in i18
      if i mod 2 is 0 then next repeat
      put eb(v) into v
      put v[1] into kbx[0][i]
      put v[2] into kbx[0][i+1]
   end repeat
   -- blowfish encrypt the s boxes
   repeat for each item i in i4
      repeat for each item j in i256
         if j mod 2 is 0 then next repeat
         put eb(v) into v
         put v[1] into kbx[i][j]
         put v[2] into kbx[i][j+1]
      end repeat
   end repeat
end k

function cabcd x
   -- combine x[1],x[2],x[3] and x[4] into a single 4 byte signed integer network byte order
   local y,z
   put binaryEncode("C4",x[1],x[2],x[3],x[4]) into y
   get binaryDecode("M",y,z)
   return z
end cabcd

on testEncrypt
   -- tests the lib against www.schneier.com test vectors
   -- the ciphered columns 3 and 4 should match and the word "pass" indicates test pass
   local tPass, tOutput
   get url "https://www.schneier.com/code/vectors.txt"
   repeat for each line tLine in it
      if length(word 1 of tLine) <> 16 then next repeat
      k fromHex(word 1 of tLine)
      get toHex(eb(fromHex(word 2 of tLine),true))
      if it is word 3 of tLine then
         put "pass" into tPass
      else
         put "fail" into tPass
      end if
      put word 1 of tLine & tab & word 2 of tLine & tab & word 3 of tLine & tab & it & tab & tPass & return after tOutput
   end repeat
   put tOutput
end testEncrypt

on testDecrypt
   -- tests the lib against www.schneier.com test vectors
   -- the clear text columns 2 and 3 should match and the word "pass" at the end indicates test passed
   local tPass, tOutput
   get url "https://www.schneier.com/code/vectors.txt"
   repeat for each line tLine in it
      if length(word 1 of tLine) <> 16 then next repeat
      k fromHex(word 1 of tLine)
      get toHex(db(fromHex(word 3 of tLine),true))
      if it is word 2 of tLine then
         put "pass" into tPass
      else
         put "fail" into tPass
      end if
      put word 1 of tLine & tab & word 2 of tLine & tab & it & tab & word 3 of tLine & tab & tPass & return after tOutput
   end repeat
   put tOutput
end testDecrypt

Post Reply