Files
precompile/pulsar/kat_vectors_test.go
zeekay a466c21334 crypto precompiles: a halt from calldata, two forgeries, and free calls
ring's lsagVerify halted the chain from calldata. A scalar of 0 or >= N makes
ScalarMult return a nil point and curve.Add dereferences it; geth's dispatch
has no recover, so one transaction stops every validator. Its parser also left
scalars unvalidated, and the two builds disagree about them -- cgo refuses an
out-of-range scalar, pure-Go reduces it silently -- so the same calldata
produced different verdicts depending on how the node was compiled.

frost's Schnorr check was a total forgery. An unliftable x-only key fell
through to the identity, collapsing z*G == R + c*Y to z*G == R, so choosing any
z and publishing R = z*G verifies under every off-curve x. cggmp21 forges the
same way if either coordinate comparison is dropped: one coordinate does not
identify a secp256k1 point, since (P, -P) share x and (P, lambda*P,
lambda^2*P) share y through the GLV endomorphism.

pulsar returned the full supplied gas on four exits -- work done, nothing
billed -- and ring had three arms returning zero. Corona quoted base + n*10000
with n an unbounded uint32 off the wire, up to 4.29e13 gas. Capping the charger
alone would have left the exported EstimateGas disagreeing with the fee, so
quote and charge are now one function.

corona's deserializePoly ignored the count from bytes.Reader.Read, which
returns a short read with a nil error, so a truncated blob was zero-filled and
fabricated coefficients were accepted as signed material. Its exported
ExpectedSignatureSize said 4096 against a real 163840 -- it omitted the A
matrix and bTilde that its own parser reads -- so any caller sizing calldata by
it built a call that could only be rejected.

Per-party gas prices nothing: corona's verifier never referenced t or n (dead
parameters, now gone), and frost and cggmp21 use totalSigners only for a
structural check. All three charge a variable fee for constant work. The cap
contains it; the schedule is consensus-visible and left alone.

Vectors are frozen hex with the generators deleted, because a fresh-key round
trip passes when signer and verifier are uniformly wrong together. Each carries
a genuine signature by the same key over the same message under a sibling
slot's context, which must be refused -- domain separation tested against a
real signature rather than corrupted bytes.

189 mutations, one at a time with restore-and-reverify. Five survivors, each
proven equivalent by a downstream check reaching the identical verdict.
2026-08-28 11:22:18 -07:00

33 lines
18 KiB
Go

// Copyright (C) 2025-2026, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package pulsar
// Frozen FIPS 204 ML-DSA-65 known-answer vectors for the Pulsar
// precompile at 0x012204. ML-DSA-65 is Pulsar's production parameter
// set (NIST PQ Category 3).
//
// Round-trip tests mint a fresh key every run, so they pass even when
// the implementation is uniformly wrong -- a verifier that ignored the
// context string, or one wired to the wrong parameter set, would still
// accept its own output. These bytes are frozen, so they pin the exact
// accept/reject behaviour of the FIPS 204 verify path against a change
// in the mldsa dependency, the wire encoder, or the context binding.
//
// Provenance: mldsa.GenerateKey(MLDSA65) + SignCtx(katMsg, precompileCtx),
// self-checked at generation. Sizes: pk 1952 B, sig 3309 B, msg 32 B.
//
// katForeignSigHex is the SAME key over the SAME message signed under
// the P3Q slot's context "lux-evm-precompile-p3q-v1" instead of
// Pulsar's. It exists so the cross-slot replay refusal is testable
// against a real signature rather than a corrupted one.
const (
katPubHex = "5576d46d8f19bf469c83fdb9d27efb407619c302c2effad8b90131f996812f92c12bc5e0e95a8b604c06c89159e6c3247c9075780cfb5b08ecdcf33abce7ce9df050df070e82acfb8e3202ea21a12dbb93bce302d577bfc3c602d5ca40a50c3e4b550a394ba6fccedc65ac2a8efa746d2796cbe6cb2e745b6521fea3405f3c0d7fd49473979ebade28218b388c3bf44641a041bd570f4f9f28436040bb7f46485704526e7a9a199f669c390a3ae0bde25796d4a76be922f1a1acf07d54657849e2b33b57c8c476cbe2c63484ba6ef5c26dfc42745620310e02e5dd6a5a84954151101c28bddd51dcb559ee7c819e2c413535b5297e2e6e69aacbcbdfbb7af25d64a186a4b3136b32477cd9c881659ba320c4b33cbf953fe0f565d2bcb318ec1aeeaa2213347dea4722078773ff0743d69fb924f805cae83102c846c25937242c873fa4953ddad95d96993e2215329dcbe34ce5498ff2f3983d7e16eed39b5b15292fdae627d313d092452af3abbeb19a2076dd6d99325db4808b5ea66d27219372d3faafc6b36be6001271de9d4b8111e8450f2ab509d7e4eccd1c66e1b98f800b5c16e56442fa4211351f971cfc825ccdf65d74ec0e7b2cf0f16c22f453d8e8641f37640b882619cb867502f507ea4becedf0a5b283f708be4f31bb315b233e6940ccdc31b4f1c8cc7a851b2fadcb0c601fef4b4d58ce04855a95d73e5002a79adb280be5e18d9a7e322691e8a6b9861f651923b811c7880d6981580c1bac838e78697ac568759ac7ffb8aca2a271c6244e655b29e620b898bb7e0ba210bc45543179f4d20f03b71dcc32bd6c0797a286200465289cd8fb909b043de42eda5e729e6c5d94dd7d0b38593bf6fb192f92c66b072697234058dc5cd5482958be1367438584ce381173944c6e9a7e567006cd2fe952d64104f4a6f3196ca15c0fcdcec1220c115cf444d3fa6215b2cf7d705f35b88f6ec5b81950514f82d6913b019882ca39ad55825b19931d8b0a7a6c879cb8d2d9ce2eabee4486817fa94e6c7c624aead36e65d0a0c6984c61b3a8c5c9dc0a2e6885a33a842952e532b837e6f42e126c954efca76c1c4fe035a4063fed1b3f943f18ef2ffb5f151588cc9eb4bb735354b2c04162ba671cc085bae3fd3e90f0a2e470582e49aed3fce70a794e1eaabdd5de91ed97bb30f064532f7ffeeba721b5dbe73da1ff8f10eaf75da079e48c2bb25400c47c9b5dd230e6aca6ba1d6f072acde5a9e0dbfb17ed7b596c5073c9426a12e5248ef8d09af16eca028ab1d7ce5e062b04f56e1430bd0f644f5db422d14bf290e2f9ce30f0fdd1d1c43ea1735d5abcd74a0ee1f998480a8c54b2eb785debe02cd096ade654d5d1d009d8deae6ff3fffa5e5210490946ad35766206201f480b2a745b2f5680bb3109064417fdd984f2677ab499ba02739242fc16e205cfe693da1b66508fff8c9bd33094cc672ce7d23157a0ab88d74fc4aa64da9a8e58074dc078c0fb084c31bbd1e8dc68ebef5a7baee6929555e84a5335517efffa42fc106bab7a793438cda8d00afadbd602158927211684141b575ea25fb1e14c1f13e268ec08200f5c438a339fa2a27bf1866d05c8a3b3a57bdef024ce026574242f114e0ca3b872dbdc17e646b0d5a7f272b7346ce2bca9b67a9913582c6e1305b94ce51e310e55d7cec7838231d513652b11da8f23745aad7672bc85372229ae0ff1c018feea90f12f23c924251505fc400ebf6e62cdf5f6615463226e2b0501105cc4dfb056b3d3da221ca37e4f9f02e38ef620c97d8ded0f62e17f334d1a6076dad6152be6232daa45ace4e0a9d3460201bb22286bc9dcd9d837a68f213f7d2196136dbb6eef4ea355ed7ab5fb446fce418facadf081a863462e57335a27c7d48f1beb6ceb40dd2f7b17e9703110f5bdc987a646dd49a78521bcbd62e9f3c5faf6acea623236acb5cf275595aaec4ae958506bd88222dcb2197d86e62191905670bc7a244539fe57f05883d13a1edfaf27cf711e81e6a06405c4c425885884403d121593a6dde225d4e5907f8778ec4cb1b4f2a1d8d93ef10458c567e6f903e48270c1983f3fb053a640363e3ad05be0040e9c4eac0566521674811341f2d68cf196b60a955da8ced9b196a46dcaebff108f6d01320f12ee684c773a369df26307fbfb764d652498dad68d1d89b6e04f2206d7c860b44276d81e32575918a9afa6eba76993ff5250d747b7b027f2d456c2d4cf7f0f2813ec6e5c6f7c10c44b59fdc7ac45180c44fb941fb60b15c14b312a82fc31d0e593a12431c8e58938b74f6ffff85796b0db3bfdfa5d43d4ed288851b034dbe20b31054a0cde74bf89fba2bc451d771c5576138c2bdbc354e89fe948ccd9beff8c7373005708e12c4661b0d82707f6c14bb32e389597eaea779e07f6c6f4df24f7968cab6554c4cc618d4b587ef172277d7b7cf66ca0072f140419f3b62473c2d9d3d3202a1274b7f47d4e1cfecf66f2251c113beefdf25bfd44157c6246c61bfa8042c4a29d5b5b87e5d39248dc9e0758e446a0f28eda16ebc0362ffa7dc9c6bd6ed0d67b45516cdfd691ee751d2d38efa89ea1e16a339b894f605f6b6707166322d6fee8e1678bbcad90e6149e999b91430a91bd27f2dad79e93061612e2581a0921d38394b6cd684641220e80efbea874e066765a71459781c40c8baa5ac633b82e6bf89e7783cbbacd45d1ded359e465ad940292f64092b13d156f0698c36904e6fc5f5e0bc5"
katSigHex = "744f830ad6d24d7b18fec543b39e29140a69a508904aa25a44e8f76c1edd92a52198f064802dd6c94f3158544f7905601d5afaf50fe2fc1b6ef64731dd522f0862c3233a0337de882ff5ed7ef8295692a30b9ada01b8c64cbb18aa97fdf32450c37d767bfdb7ac6aaa3e6383d5fdebbdd4e43cccc2c140fb3901c4387c9e80ce1f718b2bef008c16a70f42229c09aa09f1c66531e1c7d9a279ca1d45912a1f0f16c2d0d5eeed022b57dfbdf3fd5ab798a38f68db85712f7068a97e88fb7fe9a09d2d8f38a41d80b8391942f049e953bc1c1e8a7d0ec0b45cd48bbca5ac28208c4b32c6f377a07da9f3ff830f20a552a0cb9e0e7bd86bf6ce86a64efb9ded13ffd54a6af00f981a2e5f93012e99d50660ea9f69544fac0d70f7a906fc47b28d251f6322a3cd12b481ea6b2fef6f546363e3cd7933a4372c65b956345446b5ed5d9df50c109adab4965cb925d74dbd54e186c16057537e407fb7e9606851e0772c8ca50c530e20545a9d550d0c6893415c3cad55110a8848ffc4f6a961bfcb9272b45c04c59d2fb02f54fe77996023a4555fb6be0f5a67510f3e92e7d40fda205cdba9e30841ef6133aa744f54443581bbf5ff2531ae970490edf752ca0de5c4e0b7cece5a0c7ee14bb5dbd1ee27bde642410060a34147aa7a381a8ede8a8b9778cd3ed585a52030f1c93da7ec0bb08da87c47cbd6246230c6f9c89c400064a3115ade0cfc977e158b38d06f7735e12587b3209b1425970388a4fbcc08d8f298059aac168bbc90e5afadf26e5bdf033baa9af7360e65763c777e6177c4cb4750f98da11577102de6f34b2ec0dbbff642198b038b211f4985be439656e6992d1825cee2b81ac00e48b4667c7ecc4dcfd8930ff3e5101311ee12eae2c96069f1ad0045889276728c98dc1687907db1cbd948c4b1510d368ccb1813aae3e2f5262885d5ba50773cfb5eb2474c8436cc5a48b6b17b3f719e71dd9997531d27f3319fed736cb5007d8015a7da14952e40c3e5251279f277ae3d5dd0a6922ac6d6bc3c01abc68673a7b097bf66b587afa16b1c39ef37cef75db52ce7cf53781f27b820268206e3b5ee84e87c6ef10a9fc7f38531939193b36e184650e62b38b2013d0fb97d4b107008e65d767fa31f411b54d5c6dfbfc7a85307b448aa541889f6ae9501267b03f7867498a008bffb5a5fca5310926461729896868d35ba5b81c682647f47cb67ca8c63cb3370d9229ecf37e7c4d0b60f0069af7003eedc50d21623d62e51f4c502df3b6f2f1be9ee3e9d3f76e2ea6871e1597024c965f0d7469a8e4f177052ce94868c8b54ac859ac578a64c14b65272a69a74a9a11393dd8388aea2292c23d41453971ffca8fc218c39c49b67ada668648d72e55c833f050c0f2b96acc50d83dcbb82a006392de8919690d6aa7cf8cc0501fc2ec39bbbf6868db7672c4766bcf7313aee9935ea229a4215725e9c3840f8997f2a29064ced956c280f3c64da2deff1528a6b070f8e0cdbe6cc408fe2c5bf8fa9a86146cdc6377911662febea8679102faa3de0cf2b02debc960ef27d1ea00e80dd172880096324e1373a8090dce80096562261281d08bc9f01ab603607de4f89ab94300e15a74eb1f99245cb61ed1147e061ed7d1a3b96318527c652ca7f0c1f34a024d3eae1d27418cf0436adb8d3d4061dafb29fdef3fdd2d28de83269816a15e91a782a472d6d08d5ac6d2d5246f0e480f132e236cba0c2bdaf685e8f388d25ed35c35b11181d34bb6bf2d2f69b7053beb0d55f2014128f11cda26ced60e2d22a10e72956956afe71f5e95f189edcf912579c4ed12cd64b89b6e2cad94c7e9ee75300e522b0dbddb4abe8d43f1223bb0c483fd4681e46bec88dae5d818c2c501dd4b2386a08f1996491eb6ab744fd420404dce6fcafe778c5b97426bd6b24dc43d9f16b8a8aa0b5a906f893a742ae0496165900e9baee77d079bb43ec5c3d0405d1304a5f81b9478b6c3a8422b9846160e037eb75bd93b8be2db92931ae590aad379507783573d484ae638f0ca832e7017c8a55cd4348a2d4077d65d4bca9197e277fa8cd4a9e5e55bb7e286a5c32cd650f3f5342d831bdaf110a8903967718267bc8f51d1b9b5e01742f8f527bd19a4c961cc7ec1cda1ebed1f952d9fbcb4cd45cbe8db52ccb57853d9667912f428aa158d8006612e425a347a6af85211ebbf4c447c561b4fa0af88c9a0e622400255412aff7698315e249b60a3aefa8715601565939737fe0d5ab914f06c93b4109abf883ec36c5d010ebb5c15d7bc343d3cd7d408fa44dd7f58f66b69a48a651456e36521b4338e450ff83e503e527b5468a1a60fe2749f17b7b93106fb3449f812da7c1ec5c8b812b781449fa496abfd23179b1180dc398c48f7ef16f4d7bc693ed600d04d599ae7708398be4102cbf23762ef0471aa0527404f9174c2869e854924be4e23a6797b7a21ccc7634446676fd16f8fecb0e34c8452897febf7df09dfb50dfae658c43e5cf5cd8f7c46d2ad4abc3d6f578c87994af21b99b08a0a65f613b756cfd2328495bfedba3e7a0e11927c655c536597779a76bb02e97c76aba81f148dbfc686d2d13dd253ab5d5d8db82a317a420232044486a9276f436d59f2391eb77b7e64e8812457d3b5ef136c177498612db27f55a82726668f893abcf924903fe504dc6d04801a8043f47dae029c8238525b476a948e2f0d78aa9d38c4aa80606db2ae1b816671cf9d859a26904031c11a668dc8f2f807ad4a9f224437d2279597f13ce7387df9e9f870796d11f64027d0ae185dd49fde4816fb312b2fed16c39703ffa2e17172d36cb2dc4cf438b55e185873bed202f2f3aaba050d1b2308f10f6454c844e65665345436a08e9dbe634018779018b49f56f718e9743ae46ce379f09df64cd9e1944df81b2799ca8d626f6c59704326b861a59356f0013482dbcf6da434cb5487fa832b7aebccc15cdb16d6dc4a4f765bd2e77a94b5bb1abfaf2eaf3eac48f2516a521bf43f38ad4404838d65b0c4cd498f8cef206fbf8a96d08098c1b89a59e31a632ff463318029953e20880d537bff4f7277f194192208b5d25af72a59644b5a4f603bc47e386fec6fd8296ba46b17a285b304fbdbc1b6eabb684d6a09431dd745a0bcc0e713779e353039115b19ef7fb8df43c26674b4ece3bb92cab1baefad6b922f1bec64cb21cf369dd35c29a5e4697f2c576a723d68c5c517d4c8f54480a00713f7414e47713e1ad08bc9f4a378b57df41c3d974475842aa377bbbe9d465942afbf6d6effe4a6b4e3e85ed6113934e4d53258013bff86bfb637e6839192f572ff001dd9b747cf0f2da62a26b4bfd670b052ac3bb9b7a0ca5c990a7f95069e71c411a9daf4ef91979f6fdd3446ea501de0f74a398a50872d2cb59604448529e220590103694f97fd875e0cc526d07fb4380a38796ef75b4c4190057873a28ceba743caf169aab2d2408d1c931d674caa6e84fe4321cce6a4b4c356aeedcad33369e9c0f0df741aa18b9fc14bb914e3dc55da28684f911519bd27e2b080ad238b7468748af1c13e61044a8fe2b863b5bbdd3db9dab938e9fbb23b5fb55cd8d5ec04678ec2f9341620421edf535453eaef6fef1ba41674021eaa1fb320327b727918e172b6dc2fdc7bd6211e2da16ee3bae3664b0b3da129c9b942ec49aa3e6685ff30a39d67594d4bd8d807b87247c35c463a9846531ccaa4ac56cf408babc9e1fe2d5e70b39eb0133863f89c56d288325713be40c7172bcf5b5b94ae9c27aef10215ebd1961ea8da0c2f9cd4f29f9b70cec468ebf0af2039618d38df5b60adb89567afb1410eb709bc555ea391d9c8a499845f86918b03684d57fea849b7a71fa209424673e5974a0c445f2732b8227ddac1d80144554a564450441ec99eab38f698005e549c4f8b3534d49c5fc6715263399852c7a2861d9f604475cae54c61a50b8a834af192e7bc23775741a5c05a7e18d9b63ffebde43e65049547e44d2954c760575673d3a63c3291a177fae0fe34e9424b5c9b1652cace0b6115aecfa435bd6875c1ef5235576186afc19b986f3d59f4640fa78a6a4df70bf86ddbcb45eb937350fa6fe6d80fa40843ad6a7a0d24ae01c0be808eac2c15dc2e2e6801b27e615585fecdb3ac41de9e7ff87bf4c314b9da3e787da041b1838d98a496c7cb41dff661b4be0c584f8755df98bbecf27ad88bd3d9039ba8a58dfa43f57e7eb7ba6a00c3ddedc37aa4d9202e7ed6101ab5e5ca9005d21c5d07f468f479842e76a2ab38c5c65cad2b725f639cbd21f71042d57602140a17e4c26009454cd9e10856184d008de1c7e5d3eabee813094235a96b74183e712e02488568e270dba6a04e9c67a8fd4ee7f66416e1b96afce19f850e3c2a13316439475d85dd2defce7811a89187c994c6940c4ff7c35e05efed6584c2d7ed70da79f5c5bb0fdc47eca805e21d938e33a50bb47bff19b292748b64e9945b2a294a51b22138c3bc7a189c3ff44d6771889a0d14b979202b78b1c3c8161faf48c399a5364db404e5cac87b2b08108108058c333c07d1ae7a9e348870292dfe236f14a5b6ad6acdf335a6d7086cadb0b5164e8ea1f476b6c9caac02aa6eaf7233943ac00000000000000000000000000000000000000000000000000000001080d14181c"
katForeignSigHex = "c8ab77688197283be646017663c40b696a161224e603a07997bdb09be62f740e398e96d9e8c412c90c1ac6e72fe4f6259b4fb0499fec4ec870133d794b0eec4fb0f79c9595ce50ea935eeda1488e9a0db2fa027b4fa520b58bcc31085b40e46a37a5738061656b17aed61280169505db0787825c3d916b3f7d800ad5a94846a4773752d045cd056b6648840babec8e1432a168c3f6b9b2090d09185412ef5a4a0f9a25f3deeaa6306574af01bcc916326f75cd97068c493b148d5590dd250b2c8e7bd32d45495066e9697c952dddf6222a2b432861273e2e8af5bbcb79caafb07088f221c5f811d92a7c4de5dcb5ce69ce4c88d95191746b541654f73aa3a5c4bb9785233c9e1807e59502100013ac95f7b8a3b2e4efd48b0c438317e932dc52c5f79f20e5e97037c1ba8bcc9c6dfcb2391f38ea8285b29db350724446ae3995b81ce6d86613033ec233bb89cef131ad46ff4200ebc178834a59053f8d2fe344da5aebc045f7ee82e871b7536e3b0fceed17fe8f4e6c2c5576d3f5ce9af0498cc5c87a4f6f2e1822490928dad5b4683bc7047be64fa01f4ab1dca18018f29b7eb66b2e9a0ab470552468a07480c5d52ada5163e3505cd50890b9076e6c1ddb1911949cc59aaab4e37eb212364e73ea976b6baceefe9b36319585d14b1babe20df77cce5c80944d8bd1f312a4a44b065d9a314bc4de2369babe19995aa6f77d74a4daea21d68565cedbff5d03a6f2e92bebab2f92070f075785841195090bbc11b40f867b9d72e76628b33190cb71e7296e625cd9c9dd4caebf14656a2100d2b310b38cd79e4bbe11226f089dfd24d8a0714dc2d62fa5f4659172959c03b0a98a65d1523e0a826525faf7c9fa33c8affe7bbf6735a0291842eb5a2082e6acdc670a9d6f39b4592fd37ccfc1465188cf324074ea59b35b4e5dd39429362334bd2d58b54e85852dd963e4a58f281cae41960d80666855b85849d18a3fc789eb6c9b68c8d11b5746a01611a4900fec712415b712a42eabceb83493814029679f1c2721a8d991e57caf682265cb6fd2bda7cc6b86632700e62c6d725e0d352ad066da26e7f942595ee934432f32f10dff5cc06f2f4155ec32bbfd210134e48cea1a4c54475dbf32a38d2e1038ee32f7ece502724b25f350b28edc71e868915030e2f6e27789f0767f5eb0661164f17d1ea705b6bf056f733c33ade15806993d14e86d706b20c97d56c3d5485035a090ef94d3d1ff2f3495fad41a3b379ea93d7a5531a06808d8312b4d5737220018c1e5a580238991b18d0a122023dadb9d03ad3901ccd3dec7a9abc860d0e3692fc52b3f4a7b266d950c41a3e3c25a51f560c3745cbf0f8f4eea1113bebbd6d3bde4ca67272815af084a0dc7d2c11cc65e17502e6351e36a98e4e560097b51cdfe9fba33a44fd8e6d845733341653ea78e44bdc5c7d3cf34223423cc49b2a9cb72bd1396904667a27c713b6dabf007d758d2add968e5e55be528b6ccfc963a0756f8a303d64413b502fd377a1b01e03ae786ea7706dd245b9677634d1dfdebb0eb243cf9e978075f01d05c4774fd1ec4130907c777d79e374ae57b82eb81d01a7bcda9750c43728b8c2d319ef2c3989e1835b9374ac4cf1ae2e8f6d3c2a7c8d2225fc6c3274706c61ed25de3e8d2683f2954422d20ff7bc36eadc11f85990b66f69d43fc9053d4644e6095eb44e388ed79010cdec66392fa0ebe35c679b9527b36eb43cd808e8c58dce6e2c5cb064ae7a363ece824f66acb49f99a99bc0987fcb49231ee9ee0f68f0550a93f90c019473b3d6e67e47c1c29b074d5b86da084e554bfe9a375b28ef4040c7e08b4805d49755e840a42eb8d49e5f344a321aed583d1a04d1e4f21a3c5385a31433c6a56cf24a1ab04a174178bb66d951e3929f6582bcf9da756aaf8fdd58211ce214527e6c1e243cb62b56b167a17d53abbf8e6f3599024a3b3d7795658fe3fd3cc857b351c18bee4bb8c215e24385258b23ddd8186947eda62fd843411456fb5e8a9dd10d83694ebb56889606c3f34df085178860b811f053253a15ad3c62800f7cfa06fb076d48dd9cdbb9386547d17c5ad0b31f97be62efb5fa3d0c78659219ab2f02b1e0d738e0c274d1180de0704e72f7ac9ac44ab69d838130ab4a80021808406f40de5f6cc85baf76d43b53bffcd51525805b041f0144cb168eb387a9797c6f2b0d9b0aecc9e06feffa596636561421ed8556af6b3203f34f5f4251bdc56c7dfeb46eef780edaff7fcba3df31b5756f62760c8fbefa1842a37bdaa5403eab821675fffda4b2ef976d05fdfa677494708f3aa41c3dc61e4b784740d92c7c919bb145a3b78cc28c78cf6525d5bc44daf417b084c38a0ab161889d3725a4bb20eff0aad47396e38a41444b54ca2814a805e9ea4fea67452046425359fbaf5477c98dcd7a67f4f7ef1a385a664b0c63a4ef8e7a32977d9e1f953e8484797682b25bb0b320e8ea4a7533f6c05b8ac58328dd8f18ce5ccb88c7eb4a8b71b2937cd72b4048bb436c6b04b9c4e271471ea18741cec59625baf4b1862d8f858255511c2560641927c8bddcd979b69ce9d5d3c2a66a636d4588ff6a19f10681bb508d0a534197b412465cf4f46f01ea641953fadd112a3f6a5730533e92d30b7b8a202e14a4bb96f2322b52868d4e1ca4af7a6abf39dcd17e2d97e12054a954dc4fb85e679b1a5adefd62430aa2c27679c74593de3f89fceb9dedc2064539ef798c55afc58d0f1ff8dada61b3049bb7ff03b2c4736b095c3e79ff6c7e75e66eece42de66a08b04d666b123e55e1ccc73390ea1779202e988df72a109d1151adc2f02d0464fc149e7ce54f46847acea3832b5eed0e1dce09ad7037dbddfb10b3e163d34db3969d501dbb17d942451610054672c501719c2e09d24e343a95c4b5d681546a3c837f1d30f93bc134a42d88acb1be98e6712250e0157d6ccb9fc4381e85576f98be82f4699770ab8ff5915d48181992f721a9f4ad3d149effe4cb069b15360e3603ef0b7c76e32dcace545573f87b86e2d280d8a1a9a3ed80c64fc292782271f8ef4162dac8c7f3b13eb566ab3b3cbd4824e8cd08f990a6a64e93d66b9ca7ad21a104582c71da7f6e485fb37c5acff5b7a3b4e5b105802dc1682174f37ab910fc7bd74a3d0fb209a897404f56c9150a894b0888d27b3f1825077ac43c95e8a20f5bc89d07aa0ba39bb6c77e4705c92d378a763a57e4f6ced9580b04f4c93e7e1d8e61316254b21fe9474f15f022e699729ef1996f0a4f83c9c5517d07b851bfb9a7f9085a28f831f524bed7d9ec28041338a08a2c0c6b4b858a78c58b5920e049ed2cdc74b33dc853b24b2da8a60065d835011ee3ece3332feb3a9a984e32bd755b3c3c9964f788c3e2b4cc0668f65411a14bfd5ef67375cbc6ab62c2f5d5e14319cd74afa951f8d88e4c6548889b3c312763a938167367cc734d041af1a8f3a6b2e95c3ad0d39b29463a57b0d1243520041bcef2f51a20a3064364aa830b6a9da0f2fdf84d3b0d2d8774736a0fc03445f07a788893b4485f57a8fbd9e3bf348fa223a0940b712aa800c89a71fbe8ef66d424028ad90138604e1e028ed1abeb988676a2a1c03fb2414a0d80f4bdef08645cb7490aaed1f9b6af831a9d2e6c8c2f3b9ff8a95e67f4458df2b5e758fc50a4c01be49f1bb4a45a012dbf04abe57e9a861eb8d07faca3f517dbc1382eddd378261a5a42ef2a7c84dbf6cf64be9762c58d91aae5cd101ad51bb15425964646455641b51a3193844072fc966fead9d2f242fbcc313aade67fe0ed18da984617745bcb41829361be99e770006a4e54aa318287fb375c1d416e33b29b3cc5d33e15842e1196279314e44ca69e77cac4c7e503f8727f0c0223f8f896ccd6327ed1df890ab4fbaabf806f069ddd8236b751ab95da113ea90a0a4575ade1033dd20a72dc7e0ba7223e9db921d9a3cada83d5c3a1ec8beaf8eb671075ad7bf4525cd8e6437a72525fccde6e22c85181ca1ade797a21e8613a07dbe06da029d8f7210dfae9407901d5861f95642bcc3dbc58f5c06a7df6ded4f8763126ee677f5d19b895e51ae9cf82247b6d3a28a17e2172319d2c503c4589be8454f1a6c885c0afd1f9c77748b68c3b72f812a962fd897409e26bdff5583973d4507ff39bbd6a35f1fff143bc4e83ba458c6f7a935f7b05bd2b9bf6cd642c4db51fec3bfcfffbff6241549d7b34b4a4acce89117cd970133cd81029d9afcfb0b6a92f1f5c976926567b9ecf39b13b984321d30bcb4eecd3569233e5b5fcc164b776176f3e07f9f064ff7979654d74d2b90c6820233257d0c1dddf71135c6ae364e372529b7ab62ee5242312906d7f7bb977e4cf915b6cb8639c79cf20c42dfea3ce49a8187ea6e6bd5d746fdba8f5e836edc27fefb17ff65e6ac0d8865de43392098cd6a093a65d6e34443ac59aeab1753f991af22631add831ed65a27e510e68d6c42ca67825f4f771a3cf4d71bb3dea24f63a941e143e646fbf5532ff30fb6cce44d1145a7b6f4939c9f527293b97a0be1b85d71315e48e2027cc66fb37b12d3994f97d3e097970c2d057bbbf1e964397fafbffd3e464b4f64e7f9347c9ca2abf0072244474c787c85c4d30329465c619f0f1749565e63767eec000000000000000000000000050c121c222b"
katMsgHex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
)