/* This file is part of GNU Taler (C) 2019 GNUnet e.V. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ /** * Imports */ import test from "ava"; import { encodeCrock, decodeCrock, ecdheGetPublic, eddsaGetPublic, keyExchangeEddsaEcdhe, keyExchangeEcdheEddsa, rsaBlind, rsaUnblind, stringToBytes, bytesToString, rsaVerify, } from "./talerCrypto"; import { sha512, kdf } from "./primitives/kdf"; import * as nacl from "./primitives/nacl-fast"; test("encoding", (t) => { const s = "Hello, World"; const encStr = encodeCrock(stringToBytes(s)); const outBuf = decodeCrock(encStr); const sOut = bytesToString(outBuf); t.deepEqual(s, sOut); }); test("taler-exchange-tvg hash code", (t) => { const input = "91JPRV3F5GG4EKJN41A62V35E8"; const output = "CW96WR74JS8T53EC8GKSGD49QKH4ZNFTZXDAWMMV5GJ1E4BM6B8GPN5NVHDJ8ZVXNCW7Q4WBYCV61HCA3PZC2YJD850DT29RHHN7ESR"; const myOutput = encodeCrock(sha512(decodeCrock(input))); t.deepEqual(myOutput, output); }); test("taler-exchange-tvg ecdhe key", (t) => { const priv1 = "X4T4N0M8PVQXQEBW2BA7049KFSM7J437NSDFC6GDNM3N5J9367A0"; const pub1 = "M997P494MS6A95G1P0QYWW2VNPSHSX5Q6JBY5B9YMNYWP0B50X3G"; const priv2 = "14A0MMQ64DCV8HE0CS3WBC9DHFJAHXRGV7NEARFJPC5R5E1697E0"; const skm = "NXRY2YCY7H9B6KM928ZD55WG964G59YR0CPX041DYXKBZZ85SAWNPQ8B30QRM5FMHYCXJAN0EAADJYWEF1X3PAC2AJN28626TR5A6AR"; const myPub1 = nacl.scalarMult_base(decodeCrock(priv1)); t.deepEqual(encodeCrock(myPub1), pub1); const mySkm = nacl.hash( nacl.scalarMult(decodeCrock(priv2), decodeCrock(pub1)), ); t.deepEqual(encodeCrock(mySkm), skm); }); test("taler-exchange-tvg eddsa key", (t) => { const priv = "9TM70AKDTS57AWY9JK2J4TMBTMW6K62WHHGZWYDG0VM5ABPZKD40"; const pub = "8GSJZ649T2PXMKZC01Y4ANNBE7MF14QVK9SQEC4E46ZHKCVG8AS0"; const pair = nacl.sign_keyPair_fromSeed(decodeCrock(priv)); t.deepEqual(encodeCrock(pair.publicKey), pub); }); test("taler-exchange-tvg kdf", (t) => { const salt = "94KPT83PCNS7J83KC5P78Y8"; const ikm = "94KPT83MD1JJ0WV5CDS6AX10D5Q70XBM41NPAY90DNGQ8SBJD5GPR"; const ctx = "94KPT83141HPYVKMCNW78833D1TPWTSC41GPRWVF41NPWVVQDRG62WS04XMPWSKF4WG6JVH0EHM6A82J8S1G"; const outLen = 64; const out = "GTMR4QT05Z9WF5HKVG0WK9RPXGHSMHJNW377G9GJXCA8B0FEKPF4D27RJMSJZYWSQNTBJ5EYVV7ZW18B48Z0JVJJ80RHB706Y96Q358"; const myOut = kdf( outLen, decodeCrock(ikm), decodeCrock(salt), decodeCrock(ctx), ); t.deepEqual(encodeCrock(myOut), out); }); test("taler-exchange-tvg eddsa_ecdh", (t) => { const priv_ecdhe = "4AFZWMSGTVCHZPQ0R81NWXDCK4N58G7SDBBE5KXE080Y50370JJG"; const pub_ecdhe = "FXFN5GPAFTKVPWJDPVXQ87167S8T82T5ZV8CDYC0NH2AE14X0M30"; const priv_eddsa = "1KG54M8T3X8BSFSZXCR3SQBSR7Y9P53NX61M864S7TEVMJ2XVPF0"; const pub_eddsa = "7BXWKG6N224C57RTDV8XEAHR108HG78NMA995BE8QAT5GC1S7E80"; const key_material = "PKZ42Z56SVK2796HG1QYBRJ6ZQM2T9QGA3JA4AAZ8G7CWK9FPX175Q9JE5P0ZAX3HWWPHAQV4DPCK10R9X3SAXHRV0WF06BHEC2ZTKR"; const myEcdhePub = ecdheGetPublic(decodeCrock(priv_ecdhe)); t.deepEqual(encodeCrock(myEcdhePub), pub_ecdhe); const myEddsaPub = eddsaGetPublic(decodeCrock(priv_eddsa)); t.deepEqual(encodeCrock(myEddsaPub), pub_eddsa); const myKm1 = keyExchangeEddsaEcdhe( decodeCrock(priv_eddsa), decodeCrock(pub_ecdhe), ); t.deepEqual(encodeCrock(myKm1), key_material); const myKm2 = keyExchangeEcdheEddsa( decodeCrock(priv_ecdhe), decodeCrock(pub_eddsa), ); t.deepEqual(encodeCrock(myKm2), key_material); }); test("taler-exchange-tvg blind signing", (t) => { const messageHash = "TT1R28D79EJEJ9PC35AQS35CCG85DSXSZ508MV2HS2FN4ME6AHESZX5WP485R8A75KG53FN6F1YNW95008663TKAPWB81420VG17BY8"; const rsaPublicKey = "040000Y62RSDDKZXTE7GDVA302ZZR0DY224RSDT6WDWR1XGT8E3YG80XV6TMT3ZCNP8XC84W0N6MSZ0EF8S3YB1JJ2AXY9JQZW3MCA0CG38ER4YE2RY4Q2666DEZSNKT29V6CKZVCDHXSAKY8W6RPEKEQ5YSBYQK23MRK3CQTNNJXQFDKEMRHEC5Y6RDHAC5RJCV8JJ8BF18VPKZ2Q7BB14YN1HJ22H8EZGW0RDGG9YPEWA9183BHEQ651PP81J514TJ9K8DH23AJ50SZFNS429HQ390VRP5E4MQ7RK7ZJXXTSZAQSRTC0QF28P23PD37C17QFQB0BBC54MB8MDH7RW104STG6VN0J22P39JP4EXPVGK5D9AX5W869MDQ6SRD42ZYK5H20227Q8CCWSQ6C3132WP0F0H04002"; const bks = "7QD31RPJH0W306RJWBRG646Z2FTA1F89BKSXPDAG7YM0N5Z0B610"; const bm = "GA8PC6YH9VF5MW6P2DKTV0W0ZTQ24DZ9EAN5QH3SQXRH7SCZHFMM21ZY05F0BS7MFW8TSEP4SEB280BYP5ACHNQWGE10PCXDDMK7ECXJDPHJ224JBCV4KYNWG6NBR3SC9HK8FXVFX55GFBJFNQHNZGEB8DB0KN9MSVYFDXN45KPMSNY03FVX0JZ0R3YG9XQ8XVGB5SYZCF0QSHWH61MT0Q10CZD2V114BT64D3GD86EJ5S9WBMYG51SDN5CSKEJ734YAJ4HCEWW0RDN8GXA9ZMA18SKVW8T3TTBCPJRF2Y77JGQ08GF35SYGA2HWFV1HGVS8RCTER6GB9SZHRG4T7919H9C1KFAP50G2KSV6X42D6KNJANNSGKQH649TJ00YJQXPHPNFBSS198RY2C243D4B4W"; const bs = "5VW0MS5PRBA3W8TPATSTDA2YRFQM1Z7F2DWKQ8ATMZYYY768Q3STZ3HGNVYQ6JB5NKP80G5HGE58616FPA70SX9PTW7EN8EJ23E26FASBWZBP8E2RWQQ5E0F72B2PWRP5ZCA2J3AB3F6P86XK4PZYT64RF94MDGHY0GSDSSBH5YSFB3VM0KVXA52H2Y2G9S85AVCSD3BTMHQRF5BJJ8JE00T4GK70PSTVCGMRKRNA7DGW7GD2F35W55AXF7R2YJC8PAGNSJYWKC3PC75A5N8H69K299AK5PM3CDDHNS4BMRNGF7K49CR4ZBFRXDAWMB3X6T05Q4NKSG0F1KP5JA0XBMF2YJK7KEPRD1EWCHJE44T9YXBTK4W9CV77X7Z9P407ZC6YB3M2ARANZXHJKSM3XC33M"; const sig = "PFT6WQJGCM9DE6264DJS6RMG4XDMCDBJKZGSXAF3BEXWZ979Q13NETKK05S1YV91CX3Y034FSS86SSHZTTE8097RRESQP52EKFGTWJXKHZJEQJ49YHMBNQDHW4CFBJECNJSV2PMHWVGXV7HB84R6P0S3ES559HWQX01Q9MYDEGRNHKW87QR2BNSG951D5NQGAKEJ2SSJBE18S6WYAC24FAP8TT8ANECH5371J0DJY0YR0VWAFWVJDV8XQSFXWMJ80N3A80SPSHPYJY3WZZXW63WQ46WHYY56ZSNE5G1RZ5CR0XYV2ECKPM8R0FS58EV16WTRAM1ABBFVNAT3CAEFAZCWP3XHPVBQY5NZVTD5QS2Q8SKJQ2XB30E11CWDN9KTV5CBK4DN72EVG73F3W3BATAKHG"; const myBm = rsaBlind( decodeCrock(messageHash), decodeCrock(bks), decodeCrock(rsaPublicKey), ); t.deepEqual(encodeCrock(myBm), bm); const mySig = rsaUnblind( decodeCrock(bs), decodeCrock(rsaPublicKey), decodeCrock(bks), ); t.deepEqual(encodeCrock(mySig), sig); const v = rsaVerify( decodeCrock(messageHash), decodeCrock(sig), decodeCrock(rsaPublicKey), ); t.true(v); }); test("incremental hashing #1", (t) => { const n = 1024; const d = nacl.randomBytes(n); const h1 = nacl.hash(d); const h2 = new nacl.HashState().update(d).finish(); const s = new nacl.HashState(); for (let i = 0; i < n; i++) { const b = new Uint8Array(1); b[0] = d[i]; s.update(b); } const h3 = s.finish(); t.deepEqual(encodeCrock(h1), encodeCrock(h2)); t.deepEqual(encodeCrock(h1), encodeCrock(h3)); }); test("incremental hashing #2", (t) => { const n = 10; const d = nacl.randomBytes(n); const h1 = nacl.hash(d); const h2 = new nacl.HashState().update(d).finish(); const s = new nacl.HashState(); for (let i = 0; i < n; i++) { const b = new Uint8Array(1); b[0] = d[i]; s.update(b); } const h3 = s.finish(); t.deepEqual(encodeCrock(h1), encodeCrock(h3)); t.deepEqual(encodeCrock(h1), encodeCrock(h2)); }); test("taler-exchange-tvg eddsa_ecdh #2", (t) => { const priv_ecdhe = "W5FH9CFS3YPGSCV200GE8TH6MAACPKKGEG2A5JTFSD1HZ5RYT7Q0"; const pub_ecdhe = "FER9CRS2T8783TAANPZ134R704773XT0ZT1XPFXZJ9D4QX67ZN00"; const priv_eddsa = "MSZ1TBKC6YQ19ZFP3NTJVKWNVGFP35BBRW8FTAQJ9Z2B96VC9P4G"; const pub_eddsa = "Y7MKG85PBT8ZEGHF08JBVZXEV70TS0PY5Y2CMEN1WXEDN63KP1A0"; const key_material = "G6RA58N61K7MT3WA13Q7VRTE1FQS6H43RX9HK8Z5TGAB61601GEGX51JRHHQMNKNM2R9AVC1STSGQDRHGKWVYP584YGBCTVMMJYQF30"; const myEcdhePub = ecdheGetPublic(decodeCrock(priv_ecdhe)); t.deepEqual(encodeCrock(myEcdhePub), pub_ecdhe); const myEddsaPub = eddsaGetPublic(decodeCrock(priv_eddsa)); t.deepEqual(encodeCrock(myEddsaPub), pub_eddsa); const myKm1 = keyExchangeEddsaEcdhe( decodeCrock(priv_eddsa), decodeCrock(pub_ecdhe), ); t.deepEqual(encodeCrock(myKm1), key_material); const myKm2 = keyExchangeEcdheEddsa( decodeCrock(priv_ecdhe), decodeCrock(pub_eddsa), ); t.deepEqual(encodeCrock(myKm2), key_material); }); test("eddsa_ecdh regression #1 (wallet)", (t) => { const myKm2 = keyExchangeEcdheEddsa( decodeCrock("95P1ZRBAFZNXJ1DVZ3EANBM5KZ99AB5DNNY28CCVNWM902E9B7H0"), decodeCrock("MWE4WM4D3FXRQ66X785CHX44XCN0ZDT2X3ND9CTFSVFW2GPKK2VG"), ); t.deepEqual( encodeCrock(myKm2), "5R9JBB5HBHC05XHXXFQVVN9ZKSXY955QZ2TP191793PCJ2SBAES3ZS3S4ZP2711XH81YN07WHCADX8B65V2DWEP1YS48SSXXRE03JKR", ); }); test("blinding regression (exchange log)", (t) => { const messageHash = "7T0M81R8NVB13SYYBDPY0XTP1ZMG091WM6YWFZE8E12DCDD41J242K75EH0KYQRMQJE278BCH8AYE7B89QZYGG9WBN8RHY8TVVDX9MR"; const rsaPublicKey = "020000XXM4C51WSNR83AYQG2D0HH5Y8D94R7WRZ7T6JG1TSMHF449TR0W4E2V68TZDWHWKW05T6Z132DEQ8K38EPHVSD77PJF8C9GSQ482JK2CAQ2PRYX1BQTY4Z1EYZ0Y6VXBY6D27RGCREM3G2X7FXMZJ1ADMVPPFYCSNJYWW2WP4NSVRJ5787K06AGD9F90RT7MKMPPQK0Q69PQHG2001"; const bks = "VAXMY73TB736XCAM3PJR51E52KH2H3D20RGBWR59X25RRNBKV0N0"; const bm = "1BQH71QPF60K9TPE5TNNHDSEQ0N6AK9SEGXXXTW4HHWMR58PF8CEYN8C6NHZ8H19A3A7GRTJCGHHYJJPKX3RQ1SG2MDHWZFP98CDC8TTGZ3TN4FZG7J5MYEJ8239TV1BPQZSFEBYXE7ZJQEBEGW0SWJ6QHX2WM5JFS2ZDW1NXZ720JJVKD0MHE2Y0M3BGQE0SHVV5YMPZ6EME"; const myBm = rsaBlind( decodeCrock(messageHash), decodeCrock(bks), decodeCrock(rsaPublicKey), ); t.deepEqual(encodeCrock(myBm), bm); }); test("taler-exchange-tvg blind signing (post-regression)", (t) => { const messageHash = "H9RYMXXSRMF2PH8ANYJ0FPW0NYV51120QNJ8HBVTFQ0EN6MVMYMZ5M3KQFDAVTN1S3YFZT42JJ4YS77DAWXHSEC72Q763E7QY0VT8TR"; const rsaPublicKey = "040000YFQZJJMK4EJKC9KHQWNMX4E9HHJQKXNFRGFTTW9AN72EJGY55EKCQJ34D8X1Y65DEE5N0D50E1NKFG51V2JJH3DKBZTRG4MJQP1647QDR5FRAM2848013FAW813CNT40EEN9JJM205XSMY525E2NZ9P9RQS1N7D1T05ZNEPXCKG2YPNF0SCNFSRJVJG0WS36BJJN9WH62H8MPBVHJQXXH5HN1FKDZ11GN0KCY9ZX1BRM3HTN66529MMB1MVCDFQKTBH18NZM430XHZFRHR3RQ5A82HNG8649VH686YHA1FNJJAHEZ1P1RCFY93GCJ31W2BJ56N2NYZJJ4CFNAP503D3VYE5HFWFB2XVMW7Q3XXM9KX0PGZMZBN2BRDKNCEYPXPQTYFSPFB1N36KJ7EHA40R8YQ04002"; const bks = "D76VVVQ678V75M07K07MGN11Z3DPNFRTEEGPSSN3XMEJKQ6WM0F0"; const bm = "G9HCGGFNAPAQDCA41FA80VEQME90HDSQ4FZ7BV3A3RNYJS3C9BTM843E07FMH1V5M4Z8DHJQ8Q0BFH8RNBE08QQX1MB67D02ZRNVTJKGSKYMTPSQ4P5G4JJ36EVCQGSJ0GHG20XC93XJQC4JHJ1S0HN5X14VRMMTFXPHM5ZMNZZB2T21QY21CKHVBV907NH9P5XDYJXZQTV2XK8XNMQXT1Q3NCGEBVPQB2WF85SFSWZ0PS1ENHY5CGTKXE8K5NCAEAADQKGZCWJH2E2M7HW901CP863RV4PRA7HPHC29FWZ5EE8M3SKNY9V79K8CGK83WY6A97EAK98597FS10PTHFJD7NSCDM6EF9WAV70611GAQGDEDVAGZ7V48KWZ8FNC0WWRACBKZT0WPA3GPYMRZ9X8K8"; const bs = "PMTZ3MWWS4XKFV308HX4PR3NKTJF7TTGDXMR7V4VB42JZV58GT18SB1A1WXKJ7VTK9E92F4FWCEMMA9NTR9EQPJX7G91CBS3N7J9746BF301G8XSQ0M459RGKD5ZX95S5CAG56E61Y29X0HJWB9NC3MT19946NGVZ3027H0MMS5YPZ5HBBD6BJV7BW273YEBD6Q0BSY0WSE8YKG6B4F9KG295ZNTV0GV6TSDQPT4W32F4A1Z1KDVT83XHT68M0HWGSJ9J3MWR2205H2WKRRCAKX87HSWK1HSEZ1EQB5NE998P16MRX8KJWGZFM2ZHNEV20YREP1W4BKETD84JPT050QDS6VJRMNMK4MBF5BCCPCYC12H8F9WD4Z05F0WMMTH7P4Y5FG8QW3N0K732G9K2MS00R"; const sig = "SH9V61328M82B0VSSS760922R2Z79WYD6AZRVX0QYS6XYMBB9T8A228G41SK3VZCT826SC489TKMX7G4J6XP3P9VKYDPERP0QYZ0ZH1W4PGS9FARF3A8QHHHRAEQPJYWZM6NW1T7HXAWNK2R256YRJVF703XB0VJT0CJT8PT3ZBM73E584BH8PXNBJ14DZ8K4JGGNQN7WQC2HANX9G452GPVEC898KY6K1Y8D2P6KCHTBHFHVT35QM9NKNERR068QMSMT0FF546SGVFKBCA3SKHWYP94Y845RSR08KFV62DHXXM7EBD664Z7S7RCSD97DB7MHKZ3EXPYHHSF2FZW6NG14GJ25B1ZH51KAB9DKHWYR3S1XTCMXWGJT572EFCE9T90F5R54Z6RDXPJS7FDBWQ6TR"; const myBm = rsaBlind( decodeCrock(messageHash), decodeCrock(bks), decodeCrock(rsaPublicKey), ); t.deepEqual(encodeCrock(myBm), bm); const mySig = rsaUnblind( decodeCrock(bs), decodeCrock(rsaPublicKey), decodeCrock(bks), ); t.deepEqual(encodeCrock(mySig), sig); const v = rsaVerify( decodeCrock(messageHash), decodeCrock(sig), decodeCrock(rsaPublicKey), ); t.true(v); }); test("gnunet-exchange-tvg blind signing (GNUnet v0.13.0)", (t) => { const messageHash = "93AEW8G9BYPKCY169HWKVR618X323PPP876898FVXBX5VW0M8K6VT8ZPKATGQFD0DGJJHT920K3KGWSWC4JSR1VJZ97GBZDNGEJCKH8"; const rsaPublicKey = "040000ZGGYF6G19PWK6GZ5P3Z8MT00V0FP5AHNVFVTX1QNFK327J0KZHMMXP68F1DKAWD1JVH2Y1ANJNNH6GA6XEFGK5NF638692ZZ0TM2Y034EX0SWNFGJXQP1EXZ36QAC90F4YP72CYXD4BEXFJVPHZN4XKQPZFNFCZ434JYFVJP2MEVX0K13K8Q4KVWCT8GZBNCESXY847YKJNCSFK7YTGW454VHPSCNJRQXTBQK4TBV8GMPH0P2NMJAC8ZQGR6436R1HG6Y73Q8MFHV1BE8YJHFWCSH3C4Y3WF9V2Y3B7V83ZGCAK95JBHAYD1ANP1NJ0CE6Z9QQNTHD3PXTCPH6SJVK8FKWGSBDVCNXJ85RRT71DFT0QVV31KBGTK14N63G6S5PKPAJWJZ3Y995Q92MJGV5XNSV04002"; const bks = "Z8SR97D48Y0GG4BRC9J48REEKQZAE2096CDA4CYZD0VSG17KWCE0"; const bm = "4Y96AZY2HTDEC1JAYH1GKDXTWYZRG12VJR6TAPHANHGW68YSFS74TD2BFH7GHETFKX54NXN0VT0KVZTX7E43A65SQDH3JC9J1ZB4R93RZ9E021RXPAXCQNPNXNQ09GFCZEHGFMWKRX55K5T1G00ZJX2JVAJ7GM62A1ZV193P3PVY7BXQE8NHHVKY2F67DDD7EXZEQECRTYAES74G36JG16JHTPPKPDVGMKM188VBR4ZR4R83K851PSC8NM6Y2SKRB79HVXHJBZG5RDQGJZKVXGB4RBC6NJRM8GPTFKGAG14K8W8WCCSPF2MS68N9P2FGXN713V1NVW1EBTNENJCM948YYRGYY5WYXSPB7ENRC7JC4HP06ERESWKMECFFPZ65J64HA908YA0XWMGDG8MPDN1M0R"; const bs = "0AFGA8NGZQY5W36RJTGRY74FAN3RTC6ZTKVMGZ3Q8PXW0V11CFFT66AR6EFBKWMV08TPSGWD81HHQQADWF1JBBPYBGSPVY8EY6YB8K05KT8N7EM50GV8WX2BS3JB0BYNH058B1HARZQ5Y6VD3RAGV86MX22MQ14EWW3ZHPTZET6T3GT9G9T00V0YWWKYM57BMDKN12TSD19V8Z2SDBP3KHP96ZR6XMYFPP57MRS7RWNNDSC3APBH8PQEX6ZFX71DKC63YR63XTYHJS3QSG1W5B71HMWTE8E46J7P9Y07T4NRCF22MNEKE6WT2Y7NFSCJNYGP10E07X4J4P3GRH0PAM5ZK621K055B1GKW50W2130KVN524NPFVEK247CHEBHHNGFZEANZ78GY7XM0CJNY5NV2M"; const sig = "FPS5TNDAZKDTENA3RGQFEEKZZCBCBYPDA9HKPDYFDD77GVC6GDPV20KPK89MHRT81S33XWF7ZDEJV6QHJK4JCR9FR4K2TF1BHXGAKANASVAJHGEEM1G5F807F1NB09VJ2CRGG33E4FVFM1G8M1FHHFGJYGNA65N3XKAP4RCJ9M3B69H2QWSQR3NX8QPAAQN0QWNJKZRHFSH1JNNTD0M49CDBQH6Q6KE8384EY4GB57FBMTC6HX760391PZK0WV3V01B2X10HJPHTZN7BDRCA6XDTHF58Y82NTG0TBFTC597C8V31S68KP2AJPQFEAZXEDJTQ4N3WPKRG5VGPKTC0VXVXJNNYA197CX6BE300QP14AQMBBB74VY7RGV6YMPKJ1KWH3P2ESWH1T4SQDM9YJQ7KY4"; const myBm = rsaBlind( decodeCrock(messageHash), decodeCrock(bks), decodeCrock(rsaPublicKey), ); t.deepEqual(encodeCrock(myBm), bm); const mySig = rsaUnblind( decodeCrock(bs), decodeCrock(rsaPublicKey), decodeCrock(bks), ); t.deepEqual(encodeCrock(mySig), sig); const v = rsaVerify( decodeCrock(messageHash), decodeCrock(sig), decodeCrock(rsaPublicKey), ); t.true(v); });