diff --git a/src/libexpr/primops/wasm.cc b/src/libexpr/primops/wasm.cc index 05b8a3ca38d9..b59cbec93e90 100644 --- a/src/libexpr/primops/wasm.cc +++ b/src/libexpr/primops/wasm.cc @@ -460,7 +460,7 @@ struct NixWasmInstance while (!args.empty()) { auto arg = &getValue(args[0]); auto tmp = state.allocValue(); - tmp->mkApp(res, {arg}); + tmp->mkApp(res, arg); res = tmp; args = args.subspan(1); } diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index f95d8a866194..c00d56c62c3d 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -28,13 +28,13 @@ BinaryCacheStore::BinaryCacheStore(Config & config) : config{config} { if (!config.secretKeyFile.get().empty()) - signers.push_back(std::make_unique(SecretKey{readFile(config.secretKeyFile.get())})); + signers.push_back(std::make_unique(SecretKey::parse(readFile(config.secretKeyFile.get())))); if (config.secretKeyFiles != "") { std::stringstream ss(config.secretKeyFiles); std::string keyPath; while (std::getline(ss, keyPath, ',')) { - signers.push_back(std::make_unique(SecretKey{readFile(keyPath)})); + signers.push_back(std::make_unique(SecretKey::parse(readFile(keyPath)))); } } diff --git a/src/libstore/keys.cc b/src/libstore/keys.cc index 8b02e7a66819..604b6e36ff40 100644 --- a/src/libstore/keys.cc +++ b/src/libstore/keys.cc @@ -11,14 +11,16 @@ PublicKeys getDefaultPublicKeys() // FIXME: filter duplicates for (const auto & s : settings.trustedPublicKeys.get()) { - PublicKey key(s); - publicKeys.emplace(key.name, key); + auto key = PublicKey::parse(s); + auto name = key->name; + publicKeys.emplace(name, std::move(key)); } + // FIXME: keep secret keys in memory (see Store::signRealisation()). for (const auto & secretKeyFile : settings.secretKeyFiles.get()) { try { - SecretKey secretKey(readFile(secretKeyFile)); - publicKeys.emplace(secretKey.name, secretKey.toPublicKey()); + auto secretKey = SecretKey::parse(readFile(secretKeyFile)); + publicKeys.emplace(secretKey->name, secretKey->toPublicKey()); } catch (SystemError & e) { /* Ignore unreadable key files. That's normal in a multi-user installation. */ diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 57952b1dfd4a..1145c2574e56 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -1269,8 +1269,7 @@ void Store::signPathInfo(ValidPathInfo & info) auto secretKeyFiles = settings.secretKeyFiles; for (auto & secretKeyFile : secretKeyFiles.get()) { - SecretKey secretKey(readFile(secretKeyFile)); - LocalSigner signer(std::move(secretKey)); + LocalSigner signer(SecretKey::parse(readFile(secretKeyFile))); info.sign(*this, signer); } } @@ -1282,8 +1281,7 @@ void Store::signRealisation(Realisation & realisation) auto secretKeyFiles = settings.secretKeyFiles; for (auto & secretKeyFile : secretKeyFiles.get()) { - SecretKey secretKey(readFile(secretKeyFile)); - LocalSigner signer(std::move(secretKey)); + LocalSigner signer(SecretKey::parse(readFile(secretKeyFile))); realisation.sign(realisation.id, signer); } } diff --git a/src/libutil-tests/data/local-keys/mldsa44-message.hex b/src/libutil-tests/data/local-keys/mldsa44-message.hex new file mode 100644 index 000000000000..318cdb0f5b65 --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa44-message.hex @@ -0,0 +1 @@ +3B8513E51D75912EA8311333F6E7D16EEBF43515FDDD417ACDA0D5DD97C2E9711BD9A8B92AC448B9BF1B37DBC74636870213E004DDE33DE43E3EA9652E504AE00CDB792D6FD381CCF913F93BC280B87706042EE2A2F64C9506178DAB9041CCB857F95B7FBD3D8C30F582FA2A7944FCCBE93AA7FB09A1D9685A376AFB04764FF43D727FBE4BA2B1AEFF37847C5FA6CD71139122DF360A2BD6B8A7216FEB8B6879FE5AD146B50F5C0C19DE06357892107CA755876CF04D4E0EB934CDA8AECB8C066CFC0E6F2374C79AFD122D8419E40A854FCF3B7792D5760CC9F4BA7CA95A1F47621F1983175F4CE2CD1941665A170373B07702CD12EE26867F26CF6F5694B33F79889C1C58BBFD529D4E66B85BF633986311105D9999CFFF3C723F15B2E93033D19D5D8DB06685C1D49C66E2EE62F8BE3B815886C884DCD6154D83DD7DD1EF0430541A54B56E1ABC98D9E1766FE54CC050BCE7A2ED6088ECF112FCCB221D9AB613D6C73A22487B222446E75071CEE91219A6FB188803DAF88F3D9C30903E028029524459F766664BD56FA5C859172A8E438D0A249DC409582FBFA189945191C90E40689B5C2C9F24CA99DD915B0AB730C73182220810C191EDA185968A31E5B20100D21048F1BFC5B012355E56F7F9B4552BBA790393C9E051B08C1CF14F3700F8338854BE0D5B81AB85B6D1F112427ABD76E6C131DEE68A55911DA4726B4B66E426719871B72B3CECEC57EA1D1E726F54FE873CB51B2669CCFA0CEA49486D0370D3F06381977845B29BDD5847B284617B67ECE06EBB39D58AF22FEAFCDDD7CA449F9CA180EDD641DFF5F7EEF1B15CFCE409C82112B2A30C74715157D8583BAA8ACE09A4AE696B4388FF9311C7AE46DB4A0842388861984E444B0BEB315E407207BF9C378CA60427415082AB01E757805D83B619CA42692606964AB290AC930BAA94F81F2EA35E00210D7AF1889FE58FFD9B98C569EB0600DECBDBEBA62534BC410B4AE676551BF5481F04D14247F2E282F1D8C568D516F57A6F744A98A71F26DEBD387A816880D561009A7FE1816F53157493C64B13797A86CB4EF72B7DF5E39FE652B29A075615B723D8E24F9CC1C9669FC78E8BBF0C3070D382D77E37F939E3EA1CA24BD6F2DC031E855744EA4D08A3CC2E24B7D9CEBC899D898DE45A343D7B1CCD9DA4649695C47E68597B95CEF9616631B2757456B088C107E16BB75B6B7801ED12E4AF6ED57FA4990D89567D907EF5453FC5AC3E692FB14C133A15395D8CF1AFF9264DEEA6A5F75FB3DD8561D4D542F7A515E75D27FA1460D35514CDDE577793EB2B53D3769A5A2723D4397D8F84A22707F491D51FDCDB4CF9C38900CC1B33ED5A15E677FC49EB37EA073A03470D235D56E0E81245D2A8D1A24F1C61D2442E5DD7808AB3E1F808EF06D6A7C8AD7D9C16255C45FB780B6EE5C8C76F0539F20E91D0E880E42449B99CDB611EB3B8709911555653E0D6FE455865AEFC9B94E451248A5F39478FF16C783C1CF9BE63D394C46304E98A1698F1092F0FD690C1F6B8D51F82864C35FC163FE16A78C80874683B3FBE914DBA70A610AC6E43A5314DE3B5E40233CC0ED482F451A4FBBDA99D7872B507DEA5AB9DD7524E9521B8F067E3DC28226580E71D421E633CEA92C3F5A6CD27330D142A0BD84A821AEA50F2E6313C36BFB34F6A9FA6C31B08B183E75A6D38E6139E21A3199BDB72D0208DE15D2714C0D1EC312D8CE0C555B12DC5E74A1BA2A8CBAE19FAF20D23F0E0DC4B65FC7449CE98CE02FD1603942D9913B13C8BBC4E1C858A55A7F5AD8ED4EA4731210E5E69636A51A39837283221550FA780E20D3712FD59C365D8B3203C6639254824EA3D40949449C2CE4B7649F02E5A16E9F50E0F8F560B4B9FFEF7B41472E4AD71224FB0259175F01CC76809A56364CF6734AE4AE7976B749B62D20A84668A37541BAD54FEC24A973FF5A6FBCAA6AE71097C1A9EA938C81E774D737028B5E6C3C233AF53D56D4C82D35783B0B5E2C10ED3FAC06B294C6A046E82C14A441EEFC3A65CDD8CB5816CC9E743EA133D37A13897B88E17798C1F9FBF65D4413734C6BD6BC1E7571B59C6621239F749EB2A6943C4F87E0BDB5A848DB3F8E57BE47E03DF8DD63EA77A653116C36A72FE1AD397A5E0B9C03A135394A96862BC4C7089CD8438111D83CF4AFC8433915E7003EDF070455505B1023BF0AA590DF177EA65A822DA76EB0A44DCFBE66AC37604FEEDB65AD9A7B118ACA8FA231C615FCA306647A9955D5DBA47CA17F66EB259FD5F0D0CB9D822DE320E3E7F383033D45CD36998C3C0D5110AA68E7DB8D9C0562CE02B57F1BD3333C92A087FA7680449C482F1B7C4DE3A28B6FFC9EC0BEB093A8EE5E83C7AF8574D8B2D76FEE88C10D4939A69C1144F3B141DA64F480ABE613F29F10CB83C97E42D43050700F257CE0547D4AA6C2B322C9A9D24D45F269B52922D6955B79258A93E0794F340EAD938F10575E45D508EA97EA89E10E5D5ECC23746F1DA2B48D47B2C32FBFBD5B1D439AE0AA94BE9D3998307949E8C0D84DB390369A4152388439A515EB7F6D3963D1C34AC95C10FEF2CDC5B14626EE325DAE329CF9212CD09E544CBB83B15B0F4976A0381B2E8680409967C721F08CD0E538D7467EB6B01419EE694FEC61886A94F7A1C2F7D36B34E4B143B93546CF0794391D0C1BFFF6EB49A80B86536B419442AD0DF0F8110A0234E346759209BC1574BCBB3DF5CB07A2F899D401D5A0183B36E5B2F15C33C44F7712C713A2EF852DA9D1266BA67879F59E6A24CC5071150C06E965272765F69B2851B67FC0960D1D663482FABC2F149C0CEA5742DEFC912D8297B9B00CEB522CDBE29ABB1486DFE5BD03B8E1AEA793C09962028982C27DB31CDAF6A08BCA211F2621A25FEFBE0E1F63EA155CBFADF88938457A3E0A785E7E327A79229643DFC250689F9730DC0603A01D01E140B03D85FD9CE45B8C8187B5C8D32BF5C1AE3C75CB560CFD23E6162CA0F6BF922E17515E703AC0C2B99B286D65B38D46F8B70A5FBF3FF8920EBDB0BE5FADF6A4EEED69462A14ACCBFDEBA5B3F80BAAD4A475CA97AB9E8F975D7B632CF6CEBE6F4F1079009821BCC35EA5FE4EC7560D71DAB77D0E0D45B557FDF177E6D80B71FC2A7D0A057D859C2183D7ED60F68D98D5524B2878BAD8DC5915F6862443309B3C16F4CC602B6FBD032037E6E99EDB5E8425CB27733788E0E6DD25653A88BC596AC17C3C4501BE9079CE5FF19BCFB98E7B311EE0ACAB6CB84349CE2EBBE98B5321D3A6932D568FA30667C2DFEFCC2AB4FBE14EC5EBDE2D1154A982D4A4C5084CAE3FCDC684B56FC9F70ABED9BCB151D61E72E3B4263992EF9A3B489D2086ADC5418F9131923937EF9574FF8ECDC74CAD36A35B528A49CC4F716FFFBC95054EF6898C91096E887969D56E0DF279145F99E7ED926F7D3741E2890FCA1BA31D4DA37778A31D51348AC912D889CC3C554F4B7BA2C9E2A8B67F3C99F23DF9519C326F3A3A57C85FCB3CB1C04B25FC63DBE4C6F92BA7D57C87DDCF30F2E89DE65B1448C4FDA8112C38672378466A8685A03F7280244475D4F75CD24B73F0B6FEB4F82AC1BB9C935E64EB3D917CDCD96A194331B9D742EE85D5F4619106761775F8A0551FC4AFD8E1F959C302CA4BC958FDE8C18B76BF9F1A07FF61848E8CB837FDF7ED4635C742EADEA879765CF6754788E02DBEBE057DD5F69AD7178AA78A62D02FF93F9342492BA77F90E48585A4EF06EC3C08FF8867F73770987EE2EA5A7F8CFF0BF1D58C33B4E91D4715FCB5568F19CA01E5271751EC21DECBC7072238FE959D99DC14BEB918C15310416489C60347AFA12BE8F00D26DB20B08E950518096EBB9FC2B89E3EBAE5EAD5343E3D0CD26D50DC2F3BA7BA3560427A4379AEF3A6875E7E715C335413CEDCC393257D7945642A3D88ABAF57ED2CFC061CB1FD97B97DFAA1A77270FC9AE977CE8384D721666F2C41015871A138F5F0E258CE4D8B9D50487A46E3D861B52B860A4CD84DDE1F54D45A4D8AE7F1F841857FE4262810E3B496D152E6763AB969DBE94A69E2BE65D50880EF31403421AB60CD1E91DB8114D0643F86B3B317D5B38B8DBF19AD591EA401BFA73CF157F42D85160E4BFE44F79B02E7B301527794AFCDD0894451B6B16F190CE6C31C27C82730E93B57C7939414D210D05EB827A0E882C364B97F2506B06DC5EF8269C9ABE3467B29036027632299F86968771F24F89F409CC80B0E9269EC9B7F2AB62E1D3B79477DED2040391F8B6FC8018EF35BDCF095B07705253AC46859539936FE925209F85BC2FC259E5FB791ED35D2FAB34034B62948701723D51A7A02BEAFF0B178A59B0C3233908319EE309E390A553E6B07F399F86737ED162A9F638F3F7C9055CAF78B0165BB33CEAE80806D3D5E747DF9422B30467C60309C71FD775F219A6E9DCB877EC327BD3333D064C77889881816B2A0D9EB2E2142765E3912EE77AF0347F8E6C5768B30AA1C166E67CED69ED594EBFEFE34E2678490FE0A03D1C949924833AE076F1CF405B0E5BC42B2B24070620AEC3819E746F60045E27A90F18FD859111A1F56F0E0711408E57BD877CA73689AF551A1A2B36242F5084F9E181EA65194CA8D25B91B676C8DDADD4989EB18957082AF97E16D239E4FC862585D0EFED63F05B3906FE3FB4A9D331EC651A21B57609CAD16E4D557585AED19B455F4AF9CA12EFBA53289321D99947D38C58E8B597CC85CFCABA0052AAAF619920194DF0A7BD444ECFB981FBD8948B6FA00024E747F1B4934FF1B70F60BE73D5246BB66508E7D4B03F30A74C5FD4C081CA61111E848505D77E56D77B6E847E7605E1D0991655D0B11EA96D4DC832E9276D2594DE3579B6F405CCBAD998F25AAC7D6F7E49FB2EA65E4046973B7A0BA33830706EC831FBE6842ACCC8BDB311F8B6E4E7586C6A1997DBEDC5DA1CFDE0C0CD896EEA90A93E94D5DCE962920A94241A62951B3AD92CA61A001707C6D0C26D8C5ED251D72B5B4C00223199113497F3F58BABDE6B6D1FA0DB4516EBF53FB60675FA972AFD8AB0C5410089597908EC31EC0D467CD737672489D0DB88F19C4D8A7CAAA1FD6584013C088216D291A870B7CE078842C932B116F8FCAFFFC6B84857D31B02EABFBA38755010AF884E602038CFA24039F420A57E9461B89EF9514CB80A6433B2E140590F417C636FB14578B09AA950127052BC06CDE42A19C97AF1B37F61CDC610BBE220B4B18CB0277363BE7A8218EB05CC19D82B446DC3600EC0CE2D8BE21404F232B39556DE8A2BE74B3BA88B278A481F3F6276D2B8436E7777933CB89872AE0B4AA10C600A442E8FABE488DC3BD8A1FC86C5FD91204E933F149F9B0C19D6CCD317E363C887CEE43DF396214C838217129F558E6445C5EFAD69942FEF812126CC300B5E52EA4152152A43570FFCFDD4438F1C2E3FA3FCDE76364D09DAE30F804AA61E4958C6A72ECE953261243C25FB736E13FF026CCCEA7A6425F9190FE7478C689335F77042578F1F9A0C8E77429B2F6619C12B9CE9DDDB16BA9B1D364D68A1C0D867D755618C303E9BEB49A80034FF432F6777890765D06A8A59FD73952A0AE3B48EAB42DE5FCD914B3301B948656FB70EB360584C554F84A9B6B52F1D7B719DA4920D70EC0DF790BFC4DE57EA79203F891BEF07C7AF76C2FF974FD5F08D55298AEB3369A5F9D2FDBB2808C2174E1CF98CA5BD73A5FC88D8FBB36ABE0BB2B9C886F6A60673ADE5468E94045088717569565B88A955DC2030F2A7168B406192BF7890348DB87355144F124FC52C7B7F123EAA209E723258BB835F7AC8C13559DE5A30CC0783B31476F9FBDCAD97A38F6D70D8C09A3FECF04597B840CDEA4F102CC0E769BCE8EFEAFF445F8B6377EF73C42C6418D1611AC6C4EDB4F66EB259D6855E539D0B68BCD188AA22B405B1DEF98E26F326C0D46E7F5EF3D278BA779421F9643C41717E9AB85325EC40E178B996666F6E03D4523BC1A0C41CA6200FF774EA032DBF474569FC29C879FC950F447A9AF288B2EC7F2426248386DA7BC480CD22825025F35388EF215A82F9795F44279F976BA1DC1AF63A292012D0348B57ACC1F35BDA36E312059365CCE2BA4D473753BA65D27041C07E5C860905581C54EE3D3C47C19698E2056ADBE29D9853C132266BEC887994E908B4F27319E97DE1760264367C806EA24043DF675A497570CF9FF2823A93565373B9C72F39D825E5D2362C1208236124A9A57FDECC08A2CFE32B4B3ECE4F17A2146D59DDA41748C022AC6FFC19589C1BDEC0D251356BC0CC976C46829947914132456BA53E40E47BF7B54A8DD4393B2AAEE4865F9049E77F12971E899340766C3A443654834A006520639B1DEAD364B5F5DAC20FB4CB866899EEF03FA605DE92D2356039EE310570F43B2B17B2816E02D7C48E72D248A19A7E258588BBF4A04C7A4E9E59D53B7A844C94585566058E1F77AC33465159E0718E367568B652054C90921C41A0E6AE0A0BE0CBB2BA30D1F38E3BDBC14031DE978F3F3F844685641847128537F81C5B526D74782FF06FB1CEBBBBEE1A6A4D5E16CA155DFC391C7E840FBC226BFE8CAF7C56450E9F47A8ACEC3C79A1C50974D46A7D84C4A899B2987C13C0D89D5CED475C81F88F3FB7DC9A8EBEF6AFD1989244E8597E5846E83175E585C67BE2366AE2EB4A39574E5C2EE9D6CAADDA0E981E428FA20F083FD89296D946EC6EA0B2643B980447F0DA21E6F761BE30D87F0ABBD1F3662E477203E7323B147934548FA707A22CE4CA6A12A8BEE9810B260ACDAA537B40FE47BA07677DCEB10283DFD0796CE43BA5295D3712F1AEE94ED980B6E33D975905CDFC8C43485542017C0457A7385A8BDDEE0A42AD800DFAD4FD4FBCC0D02D06DA8608D3F8C22AB06B0AB720EC82E69E964086114372E00DA1F54E6DF9C14DB99CF0D98DD6F1CC63004EB48D8EAFF0226B487E0D89CAF7B414DEC5C5252AFE1F9845CFDCA551E7144E0FDC3A26F5EC66BA7498F8E1E6FF6CCD7FDFBD051B73DD89DA827A15AB9603415FF48837C433F39CCAE0990888FA1BC0E5873C552874429814FF59E989319B0DA080DC02BF5255BB34E67A5E0BF188346B034746A4A4C13BF6478919EE2883453EA5F9102F87C32DCEE0F9E9B039DF9E1948110C76D9B39A900B89827F239C2ED02A97EB8FA17C7D0FBD20573F524780CA093D8A57536FD69189B2AC05D3EBEE38393CF7B9AAA756D2685FE5B0442343B78E566A12D4670C21519636F84FE66EA3D09C6295FE0E20734F5FBE5F902727BFAAFBEB418EBFD49CD1F5C8CA1AA63227BE76D76BE3EEB37997F9D1A903DD161961519F820D2D1AA7074683B188B86D2108C23DA7408811497DF86EA866DCE255A7518388C73BEAFB1D18F4F538317206A23886E633BE6AE4D966BDF72837C0FC3CBBE3FBBE0F598FA97065AB6DEBB03BF097E026D91E diff --git a/src/libutil-tests/data/local-keys/mldsa44-signature.hex b/src/libutil-tests/data/local-keys/mldsa44-signature.hex new file mode 100644 index 000000000000..d4952f3420b7 --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa44-signature.hex @@ -0,0 +1 @@ +12CFDA699CFF51B6BB67C36C067BB8B26A2AAFFDF75487E7843DE75720F389B01A695206D9558505C4629322889C9073D002CDDD1FDB42D30625544ED22B4D43552732F56C7E06E192B02B9A791C2DB5C605EB3184DAFFDA41FCA4F998FECBEBD4743B43A1FAD7B755A262BCE5D605417AC150C4223B407CAF423ECA1AB8BA1DDA8E72FCC62CBBE67C804A6A82C09395DBA4EC531AAE9F5E4A84632110591CFEDFADAE629F1A168F3E91EFE247F9984C0E6CFC605F7253CFD3248B48BAF98D5A0DA0165599C1A351CEAF32F43F319B4CFCC83A898E92716593607417F0B701103C6335557B10D21D38723CFFC015FF4951CC78582031D84E866646249A85DD0648BC57DD2F1289E27514AA62CED865240A50F76DDE51640D80ECA8F9EC641EF1398925E11B5339AA1B36A4AD059B3B491FF3BDE9C55B8B65685CC62C507018E248182902222D69979159AD2DED90FB33810A542B7685AF4B2F9396A91A251B1CDC2F4B6D6DD6FC60F510ADDF804075A6BE97F267C773B1C23BAB469763A1CAF56E370E0AA3301CA2C96DB07947E9737B42187C3B40200226C787CFD65F021B82788DD8FCA7A97AA7BD1D252CE313843B362497645F80394B811C2F3C64B710F5193F76EB63C5480BDF209BCC347979071738FA028B1529A620280D450B0043EE873B559D147CB4CC1BA01E614D2E4AFC454A1A19526DBF748743FEAA17D754C877F4C7E411BC5CF033C629A15B0D1D740CFA8B223F775CE984E32571FCDA67A67807E0186EBAF978D31ED2336C50A04E4B5EF99502C390542C268004BDC56A1065AC14F9762B59422C225AAFF2EC75E090700A32B3E22C64CF0D98B306147ECE1B38BC88D6ACE621B06E6D668908646532DFA628C5C2B2C10D50442D86A75F2DD7A30D503482A83327F3D2346EDFC51A8187E915A43513E026FF9C460ECD6194B42F9B47D0155124BCFF55E2625640890FF4B138427949B3BC51023A649780C11F4DAD114A3408A125FD9E36F6B28DDF1E070D067C6B51C463059C7448FD0CFC86FB749E0E2E3CF02B88290B5564A3860ECD6C85D128704559C01F791A4429686F21C183D3BDB9984CB77699AA372C5690EEA5A191BBDF8B0942F95751D289F423DF170F176BB661ED8D2AB784BC5B6A344D82E261D5B34B6AFC80B957C1B943648BC46A2A79B4ABA54553F3EB41B9BD8C610D2FF82C34C491E04F678F33E5B383F8E6AC4822586887724F71AC5F161FC25B8FC14D9FC6DEBC25ED2741186080795E253397CD73FB8F27F89E25D60D4B8F40524D9A98B1E3194D2B1C283FB805DB34962EB8AEFE59BBF8444F86E0C644B3589BFC4A3D898A73FEE7326E8C415D5148882F570DFFE375FCC422BDF0F68C456C5484050097BD714DBB3F8777ADF4DF29DA756A28FB2F0A5B919A1D67BC748FC7EF031453C0E3CFBBC963870AE46B7D5B4C06DC828E910DD0622FCC21511B476DA150D9AF7462F4FA634B33260089CC8DBCE5977BED935704EA495F90B569AA8E801F84DBBFE14E8A6C0839B74D917361406BA619BD1FA7085845906C8AED1DC118578CB32A390888FAA7EB234A51ED90601A48ED2A12EF8FC6E743C947399B56D62554E8CDC7687AD9870FFC48F10243E2721031D510443483F7963ED4102625289406311490579A8881F19D520133F95E30CC693C88294F8ECADFB82F7FD20A4BD20DF4210B1ABA449A9521DCC6977DAB0EAEA29306FB7F69E9C4CD54E18149E71CA25D09B76B489C1CC7EE04183EE91214C48C40567C9A9259484C994AC1B38DCC3501DBBBBB4B56C8E442B630C8198F0929DEC00895084F3DB0E02001534146426B88AF58759E7B8ED9A19C5AFF32341931EC8F9018EF84B78BBE67D7873D50CDD8188BF9B8E4785BE4AF4E556A7D51D88CEB8BB1BB7B4F3901BA42CAC5DC0D97A48B19B5B76306DDC1CD71479ECA9A785BAAC6CDAC243F958148A7B4E5088014485593A24008FF164B7AE1B7329F06CEF7BEACE70825A21836A791382C80D35B4B5E3953CFDC53F3411C9F24786F8A14F7567E70C52FF205F1AEDBEBE6006DD10DCFA1968ADE2E53F9651D1C06E3B0E55415DCE2B38601B82433D52108EC8AF384FA54C12175C5B344318CE1152C31601CE86AEAB9BD6C9B960967175A5C947FEA79A458DFA05A27648F5D94304336D7ED633B67A4545C31274427BF3A76F5B4411664D858EE96FC564058CD287030EF45228123D7EAA6A1F4261E94E6C21D13763C7FF4FFBE23DEE2F5805C2E2E32A9549B8F9E7A0BAB1F1D7636132A31BF03389A71A9CD9708EC9BC23F42D42B8E9C51B3AF13893B36FABFBABD0EAF87CACE3B26D8983E70C47312C1255BA030969B55FA05FE7DF89485742A816FA13E7FFCE19C0B2F4B02CE2BA8C6D0E5C2BBED204CBB6D042B244487C60B80D4C2AF150C45D0CDD56C043C14E795EEF4926268F8062F720DEA3EE6D56D0BDB4FE7A7C8E926B08ACAB9F8484C0A71C02DD4606672661A5E32B96A722DEFEDC2CF6853D5E962566D7DF1E8B3E013E427DD8FB18A20ABAF9FD778B12EA781EF293268BBDB21352199FF80D3FE368A838785FFDD66E65AAC6ECBAAEDB5CFF8EA0828300A891333B8F8351C3D5D6FE5C6C51AD15B0FCAD198B0954BBAD081B90C4BAA9AC2059C31F36E8850F3038BA3797E72187A672940BFC68B8F8BFBE4953D97156C3FB79FE43A89079AC4DDEDFF6503921D4752670C832F5EB23B026A5178123C2FB725632550060A91E7AC74D981C69BE2AA6186B42D6234A5D30BD7514C0665F385CC0A014F638B300D82B80CF32E5ABEF0F16AC55BD6A157662ACF38050D8617A339C68C3DC41B263A8385053386F3F837239879D6BF49AA513D1FF7C96D7962ABE3F48F680285D563791DE253187B879B36445842DA6D2D6FEDDEB6AE374EA9A7BE48F62DF175FC207F9E0BDCB173A99A9860975FB35C7E5175A232570B9A013F6605E3165658BC03B32F096F9FB417AE6D8CD1451B8D80022AAE91194F2B270A474A931B8ADD9B0A26B2AA3430D293EEFD911714250E6D95147D3166CB387B948F7FACC76F0B3AD96427AB286C712F30054715B6D788A676A0D95D96CD4D92F4C1EBB57C8A12A93B83F4AA95384B0A4F20A55D200EE76B097F2F4406178CD4D3A0D672A87327A278B65D033217437AED9FFB605CFE7DE6353FB498FEC6C81E1C4EBF0D5CB8121B383ABADEBD720D7D96B52FDEF7B13BDD4A634F6CA6C3D08DC85DFD4472FE53A13CDBE655DE63F1DFF26CEB8FFD7F68FD724970B9DFA60AA0D08B181B20A43E93FD038893D3F0B700031D2F3B4E58627074A9AEB0B3C0CCE0101D27282A3A5D6C8998ACC7D426373849595F81A6B2C0C2CFE40723273E4D5D6F7B7C7E82888F9EA3A4A6B3C2E00000000000000000000000000000000000111E2B3F diff --git a/src/libutil-tests/data/local-keys/mldsa44-sk.hex b/src/libutil-tests/data/local-keys/mldsa44-sk.hex new file mode 100644 index 000000000000..f9ee333878e7 --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa44-sk.hex @@ -0,0 +1 @@ +333015CCE8FEFA00B284EE715465E9BACE20202DD5207AE59F6FDC96F8D7F29C504E7D18CAA52B5064FCBAAA44DE8540EE2017CF09C62D4702EAAE198AA01A7EEDD006182392C4A57D2BB9D6A36CABCA8754B248000F5F608D3706FAD1EA062F6FF6B6C404FE1415F6EC45D868D4A60B7A309B8390CAA0376242BCE14E6E853761166C50B22819448592988110362E24B940C4300EDBC22C48368CA088655C020A0AC605641869010725E342841B131053C6048A08850CC14101434808C9806416440008128CC42C9204468BB0884830711320490A188658B28DC4200123392A0CC888020072D9922C240260DC2810611085C0427109200222B2681A4971543031C10290D42044192840A0B46C5392640A450250106814978053826D24C680D9C8915302026108418B4080E4422ACBB42008888421204822C0111CA72940082804148084B20D8CB229C286681C4030049720C096650A446C14274A1BC310E1C2041C18926100041A8925224421132121E0020E142985D8A6041A93005906849CA82964A84883B64193384A10A50DC0361042C68D0432111288314438111C02081AC985132481893666031612C1044E40184AD84452182964C8C64850400DD3162824A42C4AC265DBB06812C58C818011CB9484C2280ECA1202129969A3C4019996619C1026D1482CA10201CC4024E41271A212420C1931DB1205C29228C034820937885924894B3431493082629825D9826C91804D11B27001B448D838281B276CDCA881DB428C9AC48089843193262944446EA318859B140D930812D1340A93080AC0020E1838659C3642E2A09108024ADB9605C2362E64344620B78C1848620A3711033030C388810298289A90610497441C296092C47088960512A689E3447018439293C28C18420061B2809C482E20124D130365C9186CD2344DD914802308045C028082466093C8295AA60914300021C541CB247160B60199942160142299089183464813186C141022881824A3966101887020A78121B509C1360D00A265CC8430A048510A1480A4A851DAB211CA482EE234509B368D10C60401440D51127003C0504B08658A9864D3C83123B7918A14080311040A49410CC805DAA6251007044C025054886901214492344E5116281CC48C041106541811C8C860011911249601D2402C9986014034469C3802A24421524241118971D0104591287160B420611030E4A801142184D184085844299482811036621407081396411401468C9E2D477152D34275ADB0B36638F85512D7D382CE50064F7AD09A348F69FBF34C22DAA2DD185261A3140DEA243DAA235C624AE3CEEDC182A7DFFF60AD24444568FB7DC58DBD70DEAB54FEFDFF742162C282EA39785FF788ACF423309F49B48EC9F7E1C9597FA9595A8BEC343EE8E09964DA239018A274B93A5C39C260C89747E35BA2F7FA6662876A767F6B121F9CEDD48E787A2848736D2C070B0F8C59B55140626BC99609616B34749380C71404F861AFA2407155E0C9E8CA6DEC09D1B3B85593E17BAD5A4B11362E76C0239FEA7FAD482CEDEE9CDFC5C70B72923FA7215F4EA87A4D1E12D60206CE3419E811E41BD36F5022AFE6FA335DCD24B6654B76679CD449A0A49C36FA35D3322AB626A0AB2055039AEA7B93AD06027397D793D617B9EC4D60251559E4FD6841CD40A8BAF1B931BE64477D77F9B9CE593DAF4ECB1F40F3CFFA399ACEB19E3E70BFFED3652B95543763F3C2F796D84B5521C587572EB98B635288A1DF9FA4C7A8C038DB568C0B9F760E308E0C7B60A67EF1AD6D4BE16A9D5746E063F3C48D253390F95FA3CA5A39A44B69E2DF56B737950DC78E5110FA9308F23F5AE472409FE0080C97630CF3425270866D7561BA8AFFDCE6F7F4BF63D8C3F1616485CA6536C1C70590E4585B6C4B572085013DD08511C4938F0910AD317E3FFDC38EF9CEF3024E6CDC13B91169317F2DD347946627C13F260194368C9C08E9E14F2DDEAC3C5BE1CB108644AF3A034C33E496B299E8A905D91292445CDBE4C1A63263CAEFA6F9ABC81E7EECCB4C549D06FDB970B0015FA0496CD35073968E7E0E6453D1D79CB393105F587A60ECB37CAD30A6CD67EFA9DB3C1C42BC44D1BE73AF517727B692044F3412B32DC10330D5EBD46F208417174EB047CFCABFC08A0D4B4E1633E2017FDACB9EE8239F3AB63AF978C14D7AB10D69E07ABDC02FA7F9DFDCF439CF22BF88A7EDDA4314275B8C18D8DF04C81010E9DBAB2A8CE2D4D2B1A4D8B2FE75ED4B51BB09CD8E8E55D9F64FCA3979D158AA29294FBEF61839DEE3849579BC4A0E23E33063C6CD0FE9C429D7D62F3AF2FA33047FFA1BBB8385A99C04DF844A5B2AB21C16908E882ABB74A91C7CAD3EE31FD5DFD0F9726EBD64172DCA81A6A4CBF7670FF460BB21F582367074BA0E61CAE58013446072ED9BA006A51D1AAAB6B25C798CF661C94C7BB6FEB746CF701414ADDF3C8091E90C55399E8DDEB7CDC416CDAE1EDE10253DCE3BADF031BE694372384190307710783D5EA751EA353D408FACC87ABA5E9FDAA1B9C211731B1030603F089D4082F201772FD153D58E647D6869FB528DB28AB7A0F621D5F4C8DB8BBD893C365ED1E4ADBC3153078C4EB0D7EEE7840C755293EBCAE217BC0244D2FAD26A2AF8AA85AA5D710BF48E357E4B8C8021230B5BFD64DAD840D60F7ADC8713F3A3492F606166973465BF05F91A3672D68FD19900EB4DA032C5A674C606871907A3B4D6E328A46DEE3CB9BCA2FE86DF036681037B3777E0D5FC16DF8099F54FAEA59B4ED96835B4ED97BB878F2DA58E3DA24BE2D06B0548A4636C064A014FD083E5AA5CD9075713A4C9A59EB0489D1772FE28D61FA9A0527A5BB2A27BF0A4CAA26437985A7667952C7F6F4EE4E5339CB0324D046FFDB751DA1E891E1FD9F47B38294854576DEC23BCE333641A45AE1F0F1A9936E7BADE9A717EE359A2C96E17F55E3D88AA7EE5AB74545084680370A541FC993F81FA579EBD1E06C7A48C1FA520CC466C830C3D4E3CF84E3342D6583DD06D945FBF6B576904F096916C18D1683B9243D47F21619AE03B266FB168E1F92633CCD654DBA8D2C71F2D817ECA58629C45C71A14ED398432788FDB2D8E6DF48C2BE58D5AFFDBE52718EBEB520BBF902A4F63CF527098743286235FDB71A948D9FD1A7FE1E9E6D3A1F4620B180EB95F2BFEDA3C32701B5203AA6402369CC230E2547E641044A4051B0F9362587F20EEC73DB22116F5EA6E9412227BB85AE030284F4BB50FFC46D00F21E88A718B1933532DAF839EFB0260D2A30E1CEC519C5650A8CBFD2F9D700D433E41545C763856348D7F9BA05DA9DC7DDFD17D66AB5EBD879C6D0D04C26B75985AB3F11242BD15B6B24CC2AB4A1688DC653C6A9B1FC853A29646A5F195E5BC1C972FE0761539A640C561F0B31318852511D39EE6DDD1601C01B942F7E6C242D8DFE54FDA434E142F6CAC60AB6AF30E689F6636C83917E40EC5314B51F15CDC17CFE8701D50A829154EB6323BC40BA7B50357CD2625BE6EB53B49F7EEF13A2D5F7B4C954114CEA1F9CF57A4438BBF0E61E6DB1B6C0C8E1185FD003B142BA301C3B0BBFCA32F3480FE06F562F8D9CC6073 diff --git a/src/libutil-tests/data/local-keys/mldsa65-message.hex b/src/libutil-tests/data/local-keys/mldsa65-message.hex new file mode 100644 index 000000000000..60879c7f5a73 --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa65-message.hex @@ -0,0 +1 @@ +283C1E3BD96D843B9B5C508BD42851817D0B8E5BADFEDEC49E850D07B322AAF50EFFD4C2B807AA6B15D31AEF14BC79CE74DA1450EEE9A0FCFED74383D89A0FB54B65474DF6C55C915C7C454DFADC9CE209E5A1C2D8F55B564DCA87149906E85A2115CBB19E82B3159DED464940EDC686ECDC8AC1F430CB1616E6D0AADBF97EA3C6853BC16388BF93A696F3A40C723D1D75630D18AAAFE05DD72E395D165AAB909152BC7D0B3BE9FAF53470D58DA2455043E604878910F5820247FD4C82B4C8166B814652C380037AEA97289F31E2A4D47BBC11DE711712D8A47FFE0FB5D4921DD4A1B73277C10D55C4769E9BE89A010056B32115D19DB822B3BE13D0D6C8F08833113A33E3FA889CD1E37C2939C596B84FD4D7A65DC62E0FD59A2CFF5DDF3841A0D8617F5251D42D597EDB00AD8EBDDFBE71AF0E09906095908D85B728E21AADE429B8F7A55529FFE2E136BE5BBF9D5A5254E2788C1C6B58CF06D57C50B70F903C37C04AE90F34A0E93C2B75E9309C650AD56E377257E4A474A107DAF6133B0E561FEEF825A730C18C55CF71C1DFF9D7E1CB8F8BC566B02A2FE5F119D1C0F6B9ADED54E2077D319961349E2381138A66BAD89BECCDE8FBAB02F675564191F62A7851844B46B4AF7CB75C74C111B320A43B33ABC7EB6E0B32389A97B7F9E8F6D5F6AFD6A2B8C69966A0865AD81A34469AAD6F3E3767ECDA4FF43D11DF1B500212358FF6574DCE137A6A13B4C5BEFF6F4A7AB207FBFB2B65EC072471CC400479544B19D88A7FC04DB56B3A63CDD8E174650A52E395A44E2B0D1A75189B837EB5CDE08CA732657A9D5D48AC4A26397F6120C0F44BF6D15AE1F34B3E051C1E9561B5619C4C3A02345A5648B5EF8541774B1F913631E43416692DC7A966C0D0E51338318B9E849EF357F1D97F0C3B88A89DB2FED50231CD9241FF20EB2E592534D555F1782EDE294AF49368FE7775158A19F5038CF5A63B04B0606AC7CE9387BFEF51F521C6A29EA03EF37B3D367EF3ABC6EF7FB5181585CB76B71ACD7E673E70D19E7D6A21DC7999AA1BA17B71B1BBCB2DE92F0C04585E6DBC16FE403B49BCDF6EECEFF1492195F5FC830D778242E174F755163A47AD5DC090C68BB6D2761CB89324BD5226B220442476B96118EE3348CCD0B658014F042C3F15A46A65B96CB6E52665B68AAE45ADAD188A4BD99DD63431F1703F2C02DEF9DA47016B60CE5CAEC293FEEE2364393D0FE25AE048DE7340810539C2682F49E415891AC3EB549008F9D22A4CDE573A6AB3D86E75E6F382F50BECC0F0D75681ECDFDC465DCEED157D5840D4CAD37E2D41F51018E91C29C15BE7E9B001D2E849CD9DFDCB0B99307ACBC28A9FA74F69DFBCEE92D920231EEAABE8DF8D49B8D808F7E82334B23B1BD3CF303C0807D4A93B743369DADAE031F1D1B006276DFFAB07CA9273518ADE1226C86DBA5215EF9BB2104D8DF5C0A39A6B3AAE12C561E441898351F8A287B98802282A7D754C6CA0E375680BAE892E59C334FA0B13E13B5046E206BEB5D3111A1BFC17241A66CF6645C2F300B22A23904106CBB3A1D584194C44E445B2B162D7761A35D21970608FE89CE098FA88952A28B87018AB873451CE31947AF6B803265BEE8847544C48B21E763BD626534BE1BFDAFDB5D8BDC5FE618A1E62237F06247307EC46695405266E48D5708696DBED93B7F9FCDC762E4734F19C5A72B7FBF4E7C26D0240DE99B9D6DA2C0604FAF0FDE591191E73EEE6E00A2D24020DDC009A4FDA6B7794C17EADD66DEAC356387459F4A93672514ACF533A01C3BF8C6F27C19E823E7953E5A71B046B69434121E1CEECB172349D9F1D8E53BF5D3CDC821940B12BE43806610A67DED4116ED92312973DA042A5AFD8EC83BB45DA5E4C86F016DA426653B81F6E2E57220D8922D8D32E1DAAC2CD98F483177E9D57758F6289EB5E3447AC512F41FF6DDA9A32EF6A2012BA6AC1D6724E4A21EFB783FA1FDC09F155FCF443EB8D98DE80341BE31672CF019776519953DEE85277323AE90EC23489BDB0A5BE6CB8890C0314B45AA1C1542AA192BC5365C7A1FABB61FB74999BF3358FBCA46A9D709354CAB760F5D9A3B373A7D48502F7C345621A432F000D54C3630A8EFE5434FBFF2794B417AB29BC3EEA6109C95DFFFEC38D11D9669D982809E2638AB2178E157C70328501BB51573C81E0C728163727EEBCA58C69B16C31AC96706903663D1EB2891F0084EDBB69197B8BD3CF44BE794B66F0EF36409E9B71B772BC256BD2C754AF0CE78F828EDEACDCCC084DDEE91F5295D4D62E92CEBE71AF8312CC6745E684D8B1B864110E203D1E8105FF104BF5CA3F246B51579F056871F99EA3CBFD2EE1CC1998D3B35E7600262DCE9737306A4E26DEC99627B29D70846BC2880F466AEC193C2F7A991BA808BA9204F4108AD43381AEE936EA481DFB9332EF5B6731932A22DE220B64EBFC1014B4DE45AE31A373C72AB9A2718DCB3C479366962CBDBD99D7B226B4FE9B5E3B515BC3B684658FFAC91B1924CA6ADD489320A6C2274E6BD86A63AA3D2C6C8FE04F840D4ED65E5CEE558EE4989628FC81F052218D7CADC05EAA9915E053E588AEB3AF4CC7ECCE9AB4AE236FE7AC16727F44FD22B41B43909C4CF91C70130A11C57691AE08A7407F13063CD00C490D58C70A28EB64AAFE3F62B8F4086BE1A1F07E2FB9F404DD7DA82F61CDB35AA548905464FE120389417F6A968B864F70E1E1BA967654DA61BCC51D2C75A52A69D5EE3E44784CC25C87F5849456C1A29BD4A407F81D309486D5CDB1C06F8B7FC513C1572E212315E8D9D7C70ADBAF2F6E868DB7F46B3E2B2D1D5F688E349B344F005F43862F28288B987236485EB1E63D5CE65CA3DA7F25574887574AAFAE5B0F2025BCC1ED8B54E2309273909673B574A9183C90AB5474BC213112840A581D0C03CCBC13269055987607F84F3C46885A0B62A2CDBB5EDCDC38E2514224CAE928E1B0D61FCEC0D74CE5F7EE8731AD9F7273364FF481FEBDD9EB8AD3FDDD3B90658F29FCDCB8FC915A5724CC7837C8670CDF2F7DB4307952DD8C8F1B601B2E71B170265099B97EA1F1EB7F6DD4DB496807EBEF2B4EEC008BDFC3B55A5AEE7DDAC4F9A8C2A0CF53FC0A7D6AB5BC581593E7EA0ADDF5F26A5A32C71FECB5891F5CA13BC6EA6F315212C9E51EB9473353FFAF6BE47A4B1E158BE317F4F3E21CE12837 diff --git a/src/libutil-tests/data/local-keys/mldsa65-signature.hex b/src/libutil-tests/data/local-keys/mldsa65-signature.hex new file mode 100644 index 000000000000..ed2ccaea6f59 --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa65-signature.hex @@ -0,0 +1 @@ +6068AF79E1C882A7E1C8C872DB3F0B4AA138795600B0C8AE6533ADE2C6B48E008FA0D554E8D99B4F74AFF67E0AFB8375971C21718CD2BDCE658C41AF6E98B48CCE49C3D5516E78550900BAE613F4B359204F19B2CBC0F32905C1935EFBF9CF7FBC7412B152C684BF835AC8336113A468B99FE274455A619AF43A490ED5E865ED9E6446488D861DA1C60BDF0402F9803D123B08E667ED67AFAC005F82092F873FAA7134093FD9CCAFDFED93D2E36C850982E6E2FF7E4BA36F3A46477AE5962E2CFDBFBD228902A73BE084B1BDC6DC0E778E572D000AE68A5371ABA592968B2D5159CEBD64146813201329710CA95D1148998552618687948F8196BE6146C275648715652767210EA791DFA8744781F65FA42493567DC9C70601E0466922DDA717AD52DF58ADA25D6A0043662F45D578BB32CC96A707F8B7F71E31A2E670969ED7452B00131F697381B082A542266FEAD0662DF489EC2540DE3AA7D40E2D3A7820BCD5D8253D709C4A0A98F302F9DCCBA6AE5CC2C02C9C5E9B7A5CBA36CA6F984042DDEEA279E37359C975173C761765035FB13C9E56CEC9E2F4FCC32ED3D8157491A0D34073F4619C3D0007FB5CB1E61B47E2BBA8A7FE261778D3E0EB4EEEA5B3B0F57B699C1BC64D64733F852A3CDA8CFA7740ABB4D5145CB40CAB1F4F4D396337F43AFE8D7CB19C0493BADA9C5D1E50EF1B4768D5C08DE86F3A2C0ED3BC7CA97E4EB8CD5B6CE22CE5A7C2F98E9EC2FD9F5D16EE0FD9A8A0F2D4DE60009525FA1E7FF734F117D546A2F5F5DEF36F4A3366A1D2AD9C4E0A219CE9A9565FD3787ABA67D5E0454E1E325A9F44872BD21680C8D15F7D69ECB3F973568B2CD5E879B5BFA6435F0CD1E1E8E0C310A36644DE927C731073C11D268094D61B8A1F23038505E0A9CCD002084CB7FD1619C03436E95A18B32D449C3BA54BDA86B3FBE85657986A24B7CB9471095557EB2AD5F3BA82D6A2126023B39308EF061465FC266C4DCE877FC2FD79B9E57239AF5532D03B08F5E9F80BE37D0BDAF7391EB7872466EC573A8023259F19A6BDFF23D91A7C2F46C2BF5D23C64F0A8DDD1FE2298496682293B28E15547761913059CC50A4D01E229B8EBA9D9103DDF06907CCDEBA3A8AA04157607F541479620568F46737F957AF3A711BA07D09871AB89E3782A650A6A7FD7ABB4DA2DFEC4D8396B5F94B7FB3B1421E52B185F60B063C3A658BC67AF01D0FD435920E0EA08E4AF65005397BE5016F04CCEFCDFC9CB1B35B6F8B19A6E9D84AE5C1D17F917306D680DFDAB0C1A4B26E6D274B4535F28423C6D353D16376413108DFD83E8DC50554AB8F295C9CC6B8A295E7BBE86AB99D90C08792DC03345B062777B6CB468DD99D771371099FCC65C60B9A68F5B298BBD2F7222784CBED95F59CDE6B9F59574635E9FA2EC4330E40DE8561AC19F9ADA14B9C262C569162B8AB0F7BCCF8B2419EB330A27338699AD527FF64CE4BB66F9AD6EE6EEC7F9FB25A77D482DBAF96B3A5C9DFBD174961A01A03DB2B1214B1707ED13FDBFBA60CD28BCEC942E733714331E0497D393DE2F53B2B64688D461960712EBD546B9A707C8C5851086B8CBC0F0CCE8AE3923EFC57AE8A3CD8595202A1A00EE97FA4C991C62C7A6921A8DA02048AE0569590CBE02B77AEAC474571609DB4C8D3871487D50FC2549D92FB0ECD50B9479AB7CC259F665BBDC329495F774AE046E2A0A438464528FF12F9942CF3078FDCDB1463F15F23403146ACFDEBF54219C408114BDA5D65273D9C5038FEADA233511F6F5A82DEA6ED90436FBCAC08ACB3CB623C5A6250F9094AAB86D694827265B9547CC0E658AD92294DEC5D652F82FB330503F49C20B9D1B0836AF78E000F81FDF62558384D6FF713DE94B11DB282D3DC7975128EC6BCD24C508F9DA27587C2CED52EDBCB71220BBF36AB51D0C2E07F37DAC30D6E739861F2895509F2710756B0CE4DB5C1B5CCF46F919B6F2F71E640808E07CE5BA85124F61322AB47FB77DB7ECEF21D364466170F310607F9E6EA3A0EBF59084897E094075ABCD260C1AFD11A3DED5478F2F26922D6FD29834415FF1AAF9A2F014A8DD794ECA9659B3EA5BB3BD0FBDFE1F980F82CC69BF71BAFA5D58088C3E930F946CA3263DF8F416AD28B96590A0573031110C3627B55E50030740A50839844DDAC0AFF1BA6DBDFFD9AE1D1023EAF7519C37E8E93BBAAFB054D2A23F072FE13B53648DED2619F61A126C65B9BD5784ADD1935269EBA8E29C3ED3408F2C92A3BDFBEA3079B746BEA8B589F9CF8B017E8F0654F203798B3CEBD51934F17AAE95FA1AABF46AEADC26AD3894BC5D11DC0542A6E96389CEE07B5347A4B93F979E01D7A59EFB244D473151DBAAA5B418441394EDFB4AA047454D95DD1968E12C42EB080100009CCC5906150F5DCE08440150DBA5C88C431EC0E11B7C4C32C1A7F0BCC0F12428C02A1A4F4FB11C134EB15CCAAFA1C064D708DADF3E57A6E7F303FE9EAF3BBD3BE58360F2DD301E2AA5F576951B4E47D8287F39270C8259BDFB3B8D21EC2297568AFCC6FF801CA95DA454CE9B2A3EADA4F66A4A335E56F6F30E03EBE3BFB5801039CD85C8EC266402A33994B3979299FF16E7EA209F36553E78F41CE82F6C29D28BD214EB3132971DE05D2B143FEAEA2757FDFBBC2233826C5D4EECF21428A634B9AA76879539E84626BD82DE5DB7930984877FE00E598CB15DD74B88BFCDE50BB627268737D9B5704C117F4042778F8571CB7FB736C0881723D014445A46EF52CFCE8CD4867AB5380D395EEDCF843CBB47C9FA2ADC0483B173E47AA407D05C7DF9A7D64F9DCC469726DFA8FB2FAE8A9DABD028B8495B4F72D85A8331C370C60BA0F1E5E4D1CD88267A250E351447ABB91CF53449BEAD23C29B8D2A6284893BE2D383C6CB38C12305C1A63243A8709B03BAD65C7FC3B15F8CB3DAD600B81D5D807B0A0D7D0DFE8B0616089AAD0E4FBF0375177782983895C7B527FCA4F274A83C10ABA7315E4ED2D915290A2611955B19B45342B9355583ED2CA87C163CF800A053116CEBE54E8BC97EE66B0CD9ABFA7B0AB6DE2666727627A29CC5F5815AE5F4ACAA482C5FFD611D2B67D8AB273BB15F9B2AEEAABB1173F905BF200E7FCA2CD83D0DF48122FA46F71C0FDFB06E0EEC61513A0B2DDB84990CC80FC74FAFB62D5EAB69195B2E3EDFE4604594E91495454A9F66CE33F7602A3B48D7FC0FECEC5BD4D43ADD6AC1CC23C38386CFB5C64DE0F2BA9E4D99A353F4BBFF4BE02C1A9F28EADFF8E7B1FFBC29E204DDE4413C375C36D1F2B40D2957028B1D470ECF8528D2516DD8D9D6827C3C267B6B829456EDC5250B490D6243267D1289448249EB6FC35E4EEAB0662F9644A9B58E421D18EF2D89665A404B7949F9C76189A03C7FFC19DB8F1286A49871F46987F8EE550B92412226FD372E68AF9AA41F58199CAA6ED8F97B359C2F7B1D8F9F0136778D859A92C83179B45C1960E8588F22868EF285286F0B05071169BE5B46F13E49C5CF6BB93B7C80C3FF6FF8FFB6FCCB1791E5BFE2BEBCAC933437A898B4C007D3F3FD5C42CD6E0A7408064A6CDA630D12CCF72D5F962475C260A941EA172901FB79D46D4F31B323D04DCEB7FCDA8EF5B61CC65E978E916127E10CFBE1500D20BD087E88BDF9CD90A21F360079D7E25989D7CAB09E3789FE039CC78CE67BC96A695609DD6A7789DEC80F0BE2CA0A76392D13CBFE4593B5C47018138E352DEB2AC6E41F2B36DD568FB1C863E8429938803A838F06B04B0A9C03E058959BE58C1E1E929100728D56B891902E1F9FD931A0F9533117C62369FFB9A00A80D49B20B30EA238D9007D91CE934873C57ECF74971123FD1644834BA99AADA864B09DBCAAA367D354D0B2A39FF97804E2EFF9C404E05B21EEB0C8DA93928188EAC83E0E36C5C4B8A0D70250BDA41B22C3A2F6F300D3858466AAF6836C9283CB62E7F0D6EDAA1FBA3AA0898E3C603E5B5E17E069149A92EC168384844156BC98405D0078E53EE8B63C0F8F94231FBEF4F692187B5382023371A3A9840C6748A30EF86215CC2A07F20566D488B637C70D06A29153D69FEC3A03E42E66CCEAE8EFD609E50B6FCD7BE4E252CEE22BDECD7EC8022930E167B1A47B1F7BC0E6B51D2F58A6B2E9120418CE857A7547C33BAB8D5B125D171907125B9E6F0A474CF8E70AA17D24B32BFD3FC9F7DEEC5C1ADD3C1E191EE321528E922663C0080D5DF56D4572FC6777DF887D3E57ED52F8FDDF515793441555454E2BAF6660912EA4C100591761F38B2DDE31E814861102F719CDDBD59188F7B734941C43E4FB3A227D4E84A4301880B338B631A7AEEBDF54F4C49689FBAB422519A38461DFE3B6B919D3570B9414254F9611C616D85BBD6027017C1E71FC4885013FA851C0BEDE83A66913863C22128054D431741E339D0C9C8F033383AC5AA0530919C657F3057A8875214351021272F3971A7696FAC1B62B3A438920F307193BD08194919452F4E416AAB86BB322CF48BFE35ACFE5DCBA0B80E75E0CC6809DA136BCAD33F5F26A037FA1577F71079D4D072B0F7FDF1CF5F6009C0BEE128430A4A9436242E0E96947E1DCAC2723EC522413EDBE7B80B4D7896B3BFC4222C4160B0C0D3E1212D4C545E9AADCE0D1024617D7FC3020629596E819BB7F046679C00000000000000000000000000070F171E272A diff --git a/src/libutil-tests/data/local-keys/mldsa65-sk.hex b/src/libutil-tests/data/local-keys/mldsa65-sk.hex new file mode 100644 index 000000000000..8f9cccc06849 --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa65-sk.hex @@ -0,0 +1 @@ +EE564C4459FE8CB79A589325F7DA284B0685BE468BCD00439A7FD1EB75027DB22C3C7D2770FC3A4E79275901B32BC4E0EE4D5D884FC88F3FFDB81A9DDD00F3237230A12CF0D54E341285AE80DB80BD862CB21FC582E197C8097A11934A5DE63F3B663CD99BE601656EB9E27D56FBFBBBE38A7B746BD58FA34E65790DA88A030F70176352665727854760745823608022744313876685532623652744768578428337438617405738152074310424824643303541762316746606522673500876402582424231062014318615864371664326545430807247117362061768647140887228548155637813667108317218751042261165872702021201734526616768202017851386182805282338684257756711817037301316076613715010543364068745666462844431341255638064375435052185763302885267265787467273241160368308500544037325353486525717575251843765237572244588015208222037043303784867432458284057071457834018488546568770716155414875865740668060234514635511531250673066534261558437230000731184013200111321553606241330045062675233773288103033106763150884652087885410854273210822581364803555085064232365704775602336343664843341260310526521623852340634457864272746136116180200431145551702148674627241018023845421065675004573078773247041568481607061628830378841668760344070163067747583430870362037684776637525204052215840574131654740885034258448548665812743161135213727830886740735321655550633213675401005282737885020232726568868730511827303333187132051654063466630025031782834370470801865688473736811287187726280705140281047133613210450317004561025210477411068801886300526758257078257765881631878827153368518554583126474744735208465728215002161123065832325034318245363732833316200578534641677238254738430125032457837781834245701843455140812471872428158610157161866368270880056714782710036620562200476612132668524356425670643254032608262111623142301773736256208825188685537231403043140631684750654540275035645286775600557236775545363813633535335434233472227832086422758270346875478474252240164221201666518571286851446530767884454880635646641633738850361250137484325502526664473172685547167828335038352400242141236722417603550140382058487218866442326476102641850631468373647135152227380365638224013370761242854443230528816003523571238881827167775454028367602116562117802008538326831805004033046727857680145426777806171274617505467524313866534740722666531636011416488032683058372734745888670805146168012702105764622180112514176202617362466512076863126342530518568100456237754584137085761574301304221873647015856684537063270402426412188011174253623844525774375415506265526273312335515271240253074831074438432131474833108342228481656781886416050685144448783638723574581172187380550836566108035006184688850785637587486365280874714434614850035716383325065016302527706761565632721061344741184810054411325376215660082103624147781216461553888502178433867475753468813364138808084022063534388681581525737261467070334068388477137142080583424847112441844223064872437821148541631123687413031186634035034112867877265661028776644765453737708350438770604730610858814035262247715578137204463281740471564647355245271081032084767811732687747747036450524583780271267782766511371623341030862360028868580837017610663515666600685300606576215333073557666583D08E9D6AB7411609822EFD78C4FF8242397F7CACC41721F2DEB10546E50931F0A97AEEBB5B28638FE50172947AB9CA35D7BD407002C7A2122CBD1F1155E61DBBFE66787B338D6E5C1D296FFEB8633CD1216BE1502C319319CC40E7E2837261A54F65220849E6B28A50914A53020EA82D74222301B0859DE82543E2528899BB9A45816EF877028F9355B24FAD7754C7C938481684322304561660D01989FB1D318A7D8F05A05A76C902BC91424D2FBE092B974CDC5EE4F3277DF432E63D124009FB13CEEE0482CE2A857AA81D96518CE844F963E24D2D31AA8F4AF8DF0BEE0F55A4E4060D5B9A986943DF3A77FD2D611B8AB652B2F188078BC90A568EC67C682A18E85ED9515879C196693E4A5F752945E1FA0F5A54E47A2BC37ECD1FD84E8A767B7217ACE2488DEAFE710C1BE704179A736792C1071E8289B67B29445258C6C47D5AD4284874278AE24DD2BDF0AC0D4504D0A9A0B1BD0ECAAB288574001C84BE357ACCEEF524BB8D4E37A1136109F51D3971808F2A1B3F00B2C63E9C25AB7EB33E956FE3E1D5E828FACB5C4BB0099E409F31470B84F80785CFD34F44B80728D8C2179DA029EBD336F250C269A0DC0F667AB063B97D71C651F71CBDAD18CA9276C7653125EBE41BE8C30180B96D0424FFC80650C98D5F039FDAED5B3C32859BEF76EAF9E11323AB3BFD0646DB76EC96BEF6DD66A09C6D4ED9CA4F533BCF1DE26F995918B299256A8E46D347832286328749EB391E7730B9D8DF43C5331EDCD95705CB66966AAF171BEA3F37577FFB422F60E59FE925F3368A4858F4DAF0E1B875679583B131F27D1D06A50A55758097CD51E2FB6B99803896D1503342E1131FA1C57E4E9115790BA0B702E02CD0258D285B48F858D48CF9D5C6A05E493161CC652CFD0CAB161AAA0D76EC1B7BA8F69FF5DBF65ACE102579719D409D879EAD09B7D666316116A862341D56B245C4B883C7E18B33DE41BA60131E39D4200214E05E26C1998AABC5B05100AA81930A2E654C656D390F97CBF79256C499583FFEFEFF49BFFE14B7D5840A6408710B4A2D5D4E42468B92415073E30ECA5731CFFD09A4C352D99C6B4A2D20E44E3D5D64EB187DACA4750ACE16D5F1C3116B53D16CA83E66967BA4EE380686D33EC69738BB9E803EB2184B87052DFE821652AD7B61739CD4B064C22972707733914B94C5715E100F967EEA0E5F68EC7671EC81BDC1C81DDBAFBF1625584E3D4B93DC19EA450860C6D4F5E013FD78E4EACC24E1E1A2F6207F95C21CD2ED635E170B955A837706F5FCA2D0303031F880EB878B890ABE4A1BA516ED286B78274467416BBB1BE233FF4995892101A0D39363C160EF05A558FD74400FD579504FC0468A75A30EB1C6FDDBA841500A149151AA360F8A1154EA906CF4E1B166DEAA19A5FCAE8458D261B5FF34220F06509015516009A3A987AB1E860146E99CE85AA5A459BE0469AFD7EA66D4BF63A9A13853AA4C142BFB3887DA8CF307A1C9DA9E05AB97C56B2080F91DC3F8A81BCA52BB04EA85443182214FC72140CB130C2A05BD8A7A5CF0870E534E404346887AE973726316F55C77E921420FB8D993EC62BD119D374C1DDF06FEF2BC67559EC607C0A37F77B6BE2CE30E638B0DDEA0A1CB7608402262615E98B429CAA0B80707E7C9D4B1DD991BC3554C11D59FFA34D66F3B9ED545D82B80B6BE3CCC5DED06B03946FC9763CC57213BA17BE16D0F6F9B788AC83253A0CF7DFA088DB82747AF7E39C4274B0B1F36D2EF636B34E08F2EAE45DE17076B847713A393141A66814D22520A1F46A8E100F2F6F1645FFAB99F6E6EAB91C33BC18146FF7E876434264C1CA19E7804D277AF9D1AB9010B46DD71E137DFCC4C752ABAE55559378EE5C5D025D344BA8D93ECE909C23A1D3371B0ADCE27BB3EBF31473915085339296715528F08E768E310512BB6C70514C0C47054D150F90F0B866DC1BB51A67E1C01110C2E7D4E3F3729D86C91E76F2E5F7D8F5EE75777C19279D1B49BC6CC2B4AA47BCECBB6CC949D1EB3B1130B4F2DB5862C7FBC768587EECB91DED98F146D6D990DD20B6873C5AC13542322B319457B5B47BCD709EA2BCCB3704F12625DCC26BB2806C34A256CBDC1D11BAB7CDC68B07B9DE371AB7782DBA9A120BD4978F28782E8AC67B2093C6886E755EC0C76E648A039D4A7644B0B6C7593D508422219FBABD4939C5DB5EC50D73869E6C7F2AD97D149B03EE67B733FA0206281F7995D1CF1CB384B687A767603986681F84330822CB13E96C1185C5EF70A62321348C4F8AA44AC355C2118CDCFF39391D6751284EB0F2FDDEC5FA8B29D96E11ED47789A8AA1253AC4A8786F927064E63F1B149B47F05CFE48B876B49CA65B384B23DA727BF8C1F5867D325E598FC702D159FD98F4948BA8367F5D9ECA9458C0A08AD9047116AE720B14F69E33905744F1800A53992D14EC60E877447CB54C408F29ABFE290EAD53FD237A3CE4D51731C8EB075B6296F61D9EFE0C7451B7FE0CBD8CF117E58A45DEDFE645109A5C3B78F4B188D44394EE8CC6961CCF11020BD4F89A38EC99892774D62CFE2657AE4796DEE7703022D0378A9EFA33C527817E2402797C4D72139A37ED334047DB781137A736F5BFA7858F970BB2558ECF89389EF469083EDB4D504CFAE350CF7A65619185BE264F01A64FAF6EA33E0DC7B78859C91C5B08265D6F01A0C9F87478FF6F65365C7FB637B746E945DB3E2C894065EF41182AB02DF2A3C3E93A2153CBFE739E638F8303F74A4294EBA9C387BAD384801E3E9C52301A4704B92B3C3A0E36E1B06AF8317B8AA5A65797B30797C29B0A2E6E74AE76E4FBC72DE6FE872D1C551E5A5D2123636EE08F82D98BC0012CBD7F8C61C794FFACDDF1A488E7C2085E8AA879A97E6A5A25E9C19C18AD833D21EF9DD67422F69B19D4AF6664983DC06F043C46622AD391FD3CBF2C68830D1360816186B733E4D81A6BBD8FD36727F2B31CA3FBE66367FA62CE0D066AF28C1F779F1E241ECE21B511F5C73B7BC9369280405536084271110AA2A992ADE03210E24498291AC13D43E57E63EAA187B78F1E75B0A4C69C3D508E5564B074C039E578AC43D811BC1DB37FA85AB33F74C475102548C5F0507E033639E8DEBFEC064DBBE65BD24EC1B19C98700DCD1D5F62D05CB98AC3E41C6FD45A9F8A402D42B0ABF83B995661DDA3F0418AE8D4873840E3B1CD354D52F20B0AEAC365C5D50C6CCAB3C91FFF57AC7704424678AB497348ED3A8F8983FFAAAD5621DF1EB71BF0EE82DD58DFC75D78B3D46C74FE3CC4A2DDB83B64AB72D89F87907AF5DF8A2E35C197922628E1418CCDCDB72E7AF48F47D22DBF3D3F68234B4E9B615C9E613DED3328015093280014650CBE7A876B0F38B21DFE35380071FFE5EA45D0629B08E9033211EDE3935D08871E25B6DDDB95EAF59A1BA5F979C66E61AB6A48B8F5A76A205C4943D0679200371ECD7A8BB63430144AB3510CD0AE4E0DFBD3BCFE9A8240CB9A13D8C64EBC4864EA5849361B3689D98FDAA8106657CC diff --git a/src/libutil-tests/data/local-keys/mldsa87-message.hex b/src/libutil-tests/data/local-keys/mldsa87-message.hex new file mode 100644 index 000000000000..68f0c1f8d64a --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa87-message.hex @@ -0,0 +1 @@ +8194B208815B58E017ACC96CE1FDF3E77EA19A092BF4FFAAE288977B62EF19530F3CED556DD2F4DA10EA7C272A0F84BBC6A80EE5CF61D76FEA1FDB753669CB94D3F37C66B8B9908C876A6A0263E9CABEFECDE42D83EC478BA3A60EFE5F7B457BEDE010F5CE8389AAD691D217ED7A15F81D3BF17BE4B874E4E94AE94263661E5981577C79E2E8F9F049C9E6F7D030D68CE872647DD5C7D36A59F3DDC873D273BC89A347C306FD6B82B9C743B822CED7C6125C14D723A7FDC91B83764D6BB2B78C8108C5A8F6E9E9FD4A8725D290EEEDD040487A2B5FF5C54F4B3EACF0FAB50ADE9AD4A6109E180F8D8874CCE8F64807C773710375915161271964C00676717117701C1B98B5614244BE0C7DC01DDFB30B4423626CCC7BFAB56C5C72E05CCD990535EAC7AA544CEBD5DECFF08B07CD848C451CD31077A60138C66FE4A1372013AF97848EA16BF8281834D912CDB3C02451FDAA01707D318AC38B32A27C641FAFF19DA44C2B1F8136468C514201698C6B69EB49C0E711B053E4B0AD23A13FB56976DB7C5A1E2A109BBD911220D1163B70AED4E231CE958A6DF7C3773CBA3FC759AD22583CDA3B3F4B1D1855727FA8175BEC68626998628BCE1857965E762DB3130392C8E87127D9113D7A945A64A3C58D21ED6A6E53CBEB760ACA64B44D7DC6B272BA154436384857D6B63483D995987D0BE4DB3CE026CE19D7FF20BA7FB0C872FE6DF0FC20D172FC294A9521E4C2752A84E36415EFC41F62B73516A83572A16CD819464EC01D6170F9CA01FF89854FEDA7552C201CA08B44BCB01A81416CC62A4A1EA633AF1C80B10480B67A09DB13D1B75814FB9CEB8A7F4CF56B41CE65F1B0440ADB9D560645BB51C90BA71FD83A27F2E8E7331C0B3525BBFD3AF5D8D17A1028D552440305BA9E8B3007D211467C87EB431349751986974FDEA210A5D1EC599B1DEE9C5F266A05325C4CA2A384045E0EDFC6C42A162D1671B16A6D0AECFBD8D2AA5616A58A67B1073E60A22FF849B94CADFDA0A9BF03F2339326C6D7714392FF7C9AEC3D510C0B806F832E0860A9987842DF4E7FFA546D969467B296E7218A6C6803D991C1FB2BFB7C9AFD2C9A869B45BDAEF9FCAFFB02562BAE397D08881B6DAFC98EFCEF56263BDCFD7AFCAA9844CDE5BA1E038E3A35F7FFC9E7E83608F9F797A8C5DF538000DBB18737E5F3021F12967085027FB31675A8E27CF032D8C314E36EFFCAABDB3D6BBD9DB6A5AFDEDA7CB919C0FA1CDD65967370BA91EBBD79672CE7C4CE7ED92C566AA2DFE44989E5637468ADAB3FF0FBA73C7DA3D732A80D9C82FF2E95414FE567C5FFEA1885A2141748ED39F95AFC675B7D061D6340F15654BB65875EA12E50AE6208A8A64C79AE59E1E4C989FDC801095ED0C492FD476F6DA6369133FBF6FC127637C25C06C52C41981AABB05FFD8B4D9882549D41C6E52464AE6B78BB46748D95298688169A8CB26D0659E26BD41C12AE4D7A6F83913CFCBFD8F692779948F2FD17847C0F399A12F2D82E7DC3A4FC5A41E311033871A419A595C1B0AC7F8A9C831C87682E5EF5C050B3E127ABE1928088A3120236CB0F847FB3DA04F9EAC5D4FFD95F552585FE54E647CE48F624CD809ABB9B72538A76E372ACEE2DB2DB081FFBD74B78622C3C2416668DACAE81316EE08DE0010AC1AC4B51C28261AA14BA73F47DCA2892AD0E7BBCA534FFD6C7A5F40E98416C4FFC9DC500DE2570A7F8CA4A6664745476400722FA30FDA786AC2A7733295A745E20D768D140689AD008ABBA4DBAAC013FD81E690DA08D27646E066879F67953B317041265B32C95A914C3875762168C15A46DAC7D0E8B63323D1CFED611AF938F031D6347C1A5AD849C779804BF64806CDC7A28890956D17A4CD30B61B13120ADC747BCE382698FCDF7B5D3DF06B006487DAF08325C5BD7C000E6B15173A53A6F569FB4C6ADFE1BE5AD85E4E016D161FD247E06EBA1774C7C0D6AE19E4F3C53DB96EAB167AE2BC7849BA9AAA9D7E42AE285008DC680D05A080663F17583B78F572FBCC441B4E6FDB24587BCFB7F52DFFEDF6555DE9482985A2B654DACDE0D0C57A529FCB7E30947DBDE2249192B856D540FCF828F0F35812B73A74AFBC1DCD58EA0E881ECA6EFCE61F5641315AE0C0276600E88B39CAD402716A3A6B16B3C40F137F7252EFCCE6297831E3D4F5C98CF1A59B63801CE0C86C6167EBB0986518032B470AE7D265C2C991056C0227357A6D2AD2D03EB6FF462E6744B8A286773EE4340B0A6026A7C475CA1A8F530F2FB11A1A7227C7595C0E35B7318F96EB8CE410587B31D85F84DF42AA298AC524FD5FE6EB943F7A97975F65E359F505FA6EAF54EFA4505F169CBE49ECBF5EB8B1F19FAC3789F58AE1C3C4B8DA48750DCEBC0208E24CB6C4998760E12F113E5C4039BE5867C3B1FC678191A678E9E6877DED6B2B1BAEE26059F76FF9766D1C836A3D92B0DFF2EB39D71DA7C4BD10BBF970E74E4B94A899E2EA8E5B52FD991A0F564EB724E3677ECC290FC3A581DCFEA54A5D82907C72D2216286284EBF14399AC329A1BBC606570387BABE66C9FC6912DD1A672723DD38F7FA7D2B3A6AF686E7768D91EAEFDBCFB174B67DA56ADC9E9DC0833545FBA0286504818785B7DBB9F5502943688A2996125062C75C324D898202D31614EBE700B9E62C1485EE10144C02BFE2E45EA170D6A8212D0C5A1E81290765A5CC17BCA5431D9209FB003E438D7F116AC36680E7A8AF3DD1912A2E4BF02714B4219D836D7D734975464A100479C2572A960EA83DCB97335F853A288C82D8441B04B815D4A9B7797BA44C8EEBFEB30BC9B6B1244432296C47722D24F6FEEDC1C5261EC7759C0DEBBA42DA6737DEA57CAA21277A54AD7A29DC2DA1D28571CC560B746D917B6D2CE12105C1BE5BF599F944A296B344F94632B78A24A28D2EE18C01365CC1C7FA2F40E46C639AD021A3F0D03F0166FDCD8C6846358BAAAE115D94A091E00FF66A2846199480C1519C684324D2B3DAB3922DE136433BF03048D5652DB5274874D8D38419B4F91BBEB2AB8235CBE383767B49D7DA54D8C9FE420B12A04F740D1E9E0F18563A560D69F8460F1D3A423B5B85B4A1C245D673E139CE7FC26313F4B1C8BC78074F092B2D0C1DB0D8B9F3CCC1CD75C43435C5DB0606576F65731977B91EC900F70408D149E8D78810EC8A389923F2EBDADD038AC9B37C00104313F4942EAD62F28CE0B4A9509147B08F8E821677B27977ADA65671BB9DE7B8B231DB2098179F7EA0B04BAD7A8981238546579B34C2522E349CABBE1C03A2D89E2F32D1C4CCF6E719B6D8C9D0BE04496472856E6675E7E5039FFD9EFEA925897A2C6B8ED2E5A61AA4CE011CB755CE322B9A67419D2D04F9AE15B76AE7ABA51AD3901F9EF03FE3CBB4228B6B6F960ACAFAD53AA3C4091999CB5BBEC6B15A3D303970B2B220C917564E3B4AA6B6C0556CDC78B514DBEE9B8642406807962206FEC9423BC502E733BFFA16826F9F6BDA236344F8B85906727535B5996479117CD09ADA1290F3B8B1D5210E2B5E53D14BEBA4D12902F291D8EBD33F7DB4BC64CE2564E630DB477F048C57FB4A21E245A4B36A55C94736E1B6CBB55A0FF83509C07B300DA40884A6416E285FE4B95D9E35D327B2BE8CE00E3308EEC58198ED2CEC4CA4A7B02828DC7628E2B94569FAA58146F2FD2521467522F035DCD50ADF24276DC9DF5EEED528D05CD404F202FE68E5C3C050BD049AA62C03969550F9294A2DE4BC33C2D06951A7AFF1BFC76288B98586D60E44FD08D3A19CBFC8407CD8C20CAB777ACC83EFBBC2155DC5E83C32DBDBD71239CB35E5956F88C7B28C2B670575E9EBFA3E549097B091343A92686C694F3BF3A7725EBBF895B5DF6D2BA04D065FF03E44958207CF8E9488873E8B4B3EE5E362D921B6F5A43E818C46141F2C492872C5ED97424CB205156E7802EA8A21FBE38C57F9657915EDD596E2341CE4ED0C9B61B8BD4712623B5C4EAADCE389C563C052F90C38D48A3B7334B9B4781E43C03B6B8CAFFDE25EDC8880DDFFA499128F4B6A5250A518781811A69F95FEEACC3A3E5F75F61910CE12B3AE24A0FC9BE212CAB8AF3448822FA15195C0BBF5027AAD31DA9B96BBED47FA9E9AE2C4C9D9BDD26294A87997FE04C9E621D3510B6CAD9662EE8ABA7E54A7732237324D4C05C334F6CC28A2A8ED8BBC8509EB63506A21D0E82EDA8D1EA4AE9B37516723BA99C3C18533BB3D4D85C54D7B996F1CEFEEC4895AFCD71FD75878A1F966387E3B0745F416CB5224F38CCDBF4EB1E58756A8017FCF922B008DEA9CD758BEBA1B4513FF5110C5B4E16E842B85FD650A742FD160B3817D822A5866B9DBBCB0B91F12CB2459260558C76B82FD41CC836737C6498801DDDCD6696D2566798D10645BD5E819649CC0BDB7D33E8057E6EF4FCED036FC110C8F072C2FB129E3CD3C05EBDAD4311C42377EC26A9490D4F9062A870923A5830C4F3016F46B9C0B93284C7413895E116658E275CA08603C95FB87CBCCBD0C09A0197538F5A76534BD38DACAC136D080C1E734153D55AC818825BE599059346DE31DAAE41A2008AA6E2FCB6699E85254552815011AEF275B0D8F68FE41D364889F64A3238B25B8E6F85F0454A0AA10E114002CF4D1D3C296313609C316F0F962847C10AAC96654822CF6D4DD85588117427FEF4B35E904A00F7C89DFA7D5EDDD2C89BD31B15351034B62EDE683D212CB15B198F4CE25EC41ADD20E2A699FE50ADD68BF982396C8EB64BD61222AB2720DA6F37F9CE0CB35EC11E0D88A4EC5B0AC95089905DFB9CE855E89C004020E22865C4CF02A4C7A13766E8F41E22C177534B173304D38DE5A972DCC170431947B63C2F4A1C3FA722FC555C1D43A40EC51658DF1987D71F57B0E00FAAC6C4F793832C992DE7D8D032659E0A232B3EC6B81CA38567D79D73506A1723EC720CC00779875C0A5D2B689CC0B6B6FB27896FD3CD81B687CB701AE037F758507490E91C9932AD9A12943AD32A51D7F27DAB47C367977D5C285A3926216E9E98FE93ED97A934A66F4CD76B4ADEDFE105963C4ED68F57E36128925040A1F9717DDE18B30C566D2FCC81D71A4BF8A5EF799ADB1F93EB7DB1B19F4305D8002746672264F0CD597CE0B5D03A53400982A52E6B5167E86193E1CEE60C883623FF06D41724CD9ED35ACB01C38027CD4B97BE287A29D807FB5E8BF002C328257EA436F8079FD8C8AB1F5743596346EC84E3920F3107DB59F80E73EFEC79BD2A9E2465096DABB0DEA7F02F5582D0156F4E7869C0EEC649E3AEA4A4B87D7FB8DB75DA136ED39465EDA380D67BEB89FE9CC6F16FA5543304B193389ED399545F7D6C1ADE806CDB61BD1EBEF3F378DC1C4C773D0DDDFD25F6545A804A345284AB97744E5807D575DAD3CE6DCB4B875F32DD6DF05745EBD3CCC522B4F646AF302BE9097A53AABA893DCF82F9B0CAEA180851C7F9647D6DB511C7F9139012445DCC7F37B5638FB1F9D7D16DC5FAFD9BC6D8B2C73BA47BAF629F6C0A04A4915AAA947DF64B90C2CAD08C6B7513E00D221BCB9DA4EBBDD9DAC3CBC8782E5F3D644CE54DD21C1967647C9D84147E3F7A2B179B6A4108DE40F8679910B3F53F6855A0E9B48E0B24BD860DA6822BB54074D37EBDB797B4DE4E017459F7DA9F750AFFC83A55F212F9E9CF321F2057DFB4525E74AF28FF3E3190F5DCC787F5F3F0A52DFE62E0079FE883A6BDF6C844D42BC9FB4FEBCA44A20962A942F4DB969FA7C5FB64F482A9B0A14A3EF4CB08A1DAD2EAB75D279DB9EB0922800B90A9E9277771C697A317BEE22622ECA4B64EC5896D39EBDE020D116E5D9E7CB265D0D38DEFF54290920E14BEC8B96B380B178985D4E6DB6436D81CBA0159A6B7D6879C925BF7BB40D39A70499D22B71EC812C80355523A02622E84AB35162A0358B2E080D8334BD31ADFD80FE83E92BA8351D12B5DFE69B70775C6A6CBD61FACA9598730DC3B6F993E2502BE0A427728D54F8154C2D35CE0E2BDBB48CD8AF91D9EE3516067680A05A593FFB9DF4C75C3BD9330C4F4BD8FFBB9EF98E741152D3EDFE10A800535BC0514761152CE16CF7BA4FC5DFAC8D8FFA9635795236E1F7BB7E6CECFAEC71AC01B8EF99DF366F2524E120606BDCD130CAF90D29AC6504AFEB26978442164E282ABB92B0ED588907BFD1DE56D6DD1E5302BF034904AC57A469CCE2583E2F070348073D8A2FD3EFDE3211C5F4097E6CDD8ED5A35929962F6835C284DD26CB1985D5E7D543AAAD28B6082CDF34049D66FE9A092357A4DCFB1D4AE8275889F80B1155DA81706D06E6A22D582614A37A405D2B1EC521DC7F506758324A814F560E2E4182BE54EA920D5F3AFFC70534435F956976AE98164C94042F7C026A5611A1E45D5A67F31FB9D3D9A6EB7E70737FD36AACA092F14A6B88B975CE1ECE6BA43AA9703A7517BDFC360C67F903AEF619C23E3A7E1E90BB222ED27215FF45C63BC2AA8A649A45BE1DD8CB315E13694DFACF7513D4FA2E5EC51E0A80332586C7776A7B5241A9C59ED60334AC6D55C92CAF0597ACB6CD20B724FC243A292BC14285389727401853927C3BD105A1534AF94833ABF4780BF00E81CB7AA53C41CAB718D5FFB85F11605B0A1FB8A6DBB2729F91607BE3D2DA2874E0E638A0735DB234D2ACC823F2EC59C4277ECEA080D0F4CA7BEE02EE76AD53D109E294A8D597D9C8C04987C08CEE8D945EF29126AB3267859F1E484D26727E6A7D45028070B8B6B8A579D2F86693E8B43B2960F507C1160C7315619C407F329331EE646592B8CDBFE798F7C13EDA9AF0BA88BC6915B058D1BAA5394E78AE519D3B11C2F194A33CE78276A55092C0B1AC53DA4A921C7DB504EFF918DFA040369CF99A91F086FEDB052AC8D6CAB538CAC374E98EAF4B4B27DD0259F06FA867B069416A996D943695E28995DD344AC75ED058C14750B9880782F826271CD1549B080D218214191384CC4A382742CE1FF33966D1B4437FBD8AD37EA28128F2D02AB0E8AB544DF0C5A21D04B71E345B8625794F19ED0C0573A3516F82D9CB309973587C82D8F399425353DDC9C7131EFA56587DB1B26628A733B19EFD9044298FD6DBDA2D3EB1EE933B018015A33935424F0FC7035B17754D85AB34B796C453D37981030C656DFA2D5BC8C937B3BE42686925C1E4279300E9D83F9B38DF4A6C043943C3F5A19E6810F3FE965BF15D8D10D413F1F2D89D274D76B49ACD7EFE2BF214CA8530DF268C5B189A815ED0779E730D0A270B3C70CEBE84A31C2DF980AB754D76D39FC08A2B0B1F2E63A74BABE092D2945E1A636978F85A45BB0A219B898C31CD0AC11A71075B249A64B57929044FAD4DC9831CDD424847EE00D7D55F9583D3ECC05FEB8DD09C176AF7A5B1B0E65B2D9059C71F6D69022CE65EEB1D2EB62C4026665F8421DFF714D8F085DF6F3E96D91DF68B8BD5AA4A3C5481CB84F57507E0D714E047BF79242BE5ACB9B7A556AEB1D3E08236A7035506BE1EFD45FBECB192A82B360DE06AB9A03D328F3AB0F84B41C7B761B707A01C0D12D0B27919515E74E76AAFF0987669459799D6B31077E7608816A74A5198FD482BDE7459B0413A03E5AFA29868D3687EF1B35004F837DB972A62CA536534148A0318D400E55B08E79EDEEAFC0F11D3526A0C7E66230050FFDF59B4B938D8E2C09BB1AA4C25C27B702973055927BAF0DF2BF32C4804B04BBD5509D360DB326AA43812A70FE10F45965473167EBDB5F9A2CA8FEB937D1AE342C19B4B7B68DFF34FF1B30F215DBB5F1786A962E7F30D4890753C30CE725C67373404BB4016DC3FB76B198C06467EDEFB4E6DEFD45217477CEB624798875E698DC955903CA6AD85767DC4FF4A8A33F2CCD4B81CEBDA209CC43161FDAC42BD7C5A54163A493BA3B36B49CA04EEEB78EED90E9A4603A8BD94039EDBE05A08CF4072A3EAB3691D01571ACBC5997E242BA011CC066B93302035177F574A92CE7F20E348391A8B9AAAEF7A2D7623EDD5035AE96EAED939B288BBBE665E13FC7B8490FFB37E818F150EC095301E1BEBEEAB659343C6176F6ED451C9B82F8A5B401F98495212993AA6AEAF760E381E044263EDF0B9541C03CDF3024CA9283DC484DEDD4E226E4FDCAC1EE76FC9D55271210AE1E5E41F3A1D6DBAA7A1EF35598E0E795B60B93F1F3459D20FE36189CE7594E18202B64C3DE03F868D31A2A9AEBBF258E9985AF752A31D982221FF6993FAFC4A4B8DF15BE6F811B6580BE22CDC8BF40F4D0574CACFE07F736E9D344F9697926F6E7F25A2BB4F6E6E531AE7D2267C3566718601366A6AC97130BCAB555664C14FEE189901E275854E4BDF258961A02009E29AB457D7708807711818409DAA4D889449725676280135EDD8A6E2623A8948FD390FA3ED6589606F1F29F3AB7326F2C197B3EAF92D42E23EA1CD60D0F726AB0BC3B3C4AD0F1058347B83C90A4FD7AB4987D988E5851CB10DACA30DBDCDDBF2D83433731E607A9B10A97005DE408ED1AF8B2EACE9FEDF3F46D235279A20F1B4715209991177266834B387C4C4538332C43D3EBF725D44E1DD44FA44D8BF5EA86E44595173531EDE3A910A3EE0BC8431170DD6F8D95FF8DAB37CFC305561093EE2687148949A409B26081F6B28085EC9855FA5D1FE4110DF8CFDFBB3FE44E65A0C32373F760990BCEFC539EA3F75C8AF30EA853BBB056119A7F752255720606FF25EE0F0A78FA41A9B60D76F6AB8D6DF1342D45EB4D8A8ED22DECF2A242C2DC73494A30654EBF205493A0463E293F86721765174E794F4956535ECA994ED44AFD4C9F3532FF85574C7CBF3A96E0E231F78541768CBF28137F7C30EBA50B9D13CE3727215B370CB48EF1D6778CCEC5863F04D53662A281246DFB6D3EB3134822F44C095C672136CDBCA4190EE3960EECBBE3FEEE2E9160D7938E429105C958A700BA0E9BBB81693DF303C8C37A15B3B08D72080CBB48DD02E8C4DDD15F29D18568932397479B5FC3EFBA370B93489C715FA1BBD64EC03B235155371B4559F72A0F5C0C16871352484957CCF76C2F571FE0222A5754E0E174AAABAA99E4A91BBCB1A43AEB687C948AF80FB63034E5CFFCEE1BC46015A9CF494774921B9D4B58FF8701DD3B2B463AA4834000232929E83DC648E43CA8A3BD8EE06631A22017CAF933E0591D239544D3576D03D337AFB07916B33367448BE0E11E00D170199211861337D3DAA2FFF0F9B029C88984DC8EB1D74B34329EDD3007BAFB1C138FF5FC1FF688AFC66187C44BE6D14575939BDD3B14606516B2080FC2FD3561674BD6CBF59E5B246117A2123D61E63AADA02E3C1C6367EA5AEA9B7B1BE9C76873C42632217FE5A3D0B740A3FFBA50B12D23F88966A9258E7EF84ADB422CDBA2BAA1CC8D13145EA62994E642F1E6E3A4C5DDA7F78C810A40523A477F250F38B6F93189E25F168FD41A840B71EA78C8C57870EA7BE2D4D444842CA4A2E9792B3506D0BAB9AB5B15B0588ACB60C68E6DF6DC30F951453E87B3EB353D74C6E75FE6E5D200576EA5F671C12FB96988BF79C1A06B8A486010070627295EA2CCD6E012F3541F40500E61677959624D45AEDC4AD70A4BA7FA523B04125065D00C6FCB247DFE18650951CBEC12849B9B151A578DF96B1297FB5D110CB929921CFA74EB14F577679C3CD6B5EAA246050B5FF52EA46D6045F884C09BE49B553BBF3B6E321790FA9043BFC4ED3E6396589642AC61F5E9CE8A2D8C7B0F85BB26602A151880FADD47B8C1EA1772F88DD1739346570BFB7F50D8BC68105F48BB7B5B31BD7B0FD72A9EEE4DA8E146C18AF33DEBC4CB0117581EA624EFAB98CC9560A230D8FDEBCBBC385F476E631A2675C86701DCF4A85EAC342FA947CC0F89E65DB1C207BB89F2F41ADF6D29AD4B87C7EEF1FF347F294623AAEC62F0E0E69CA588F5BAEBE11467C79C80053ACC0899961F892D68B412DC189DA31B22508F75201A393147E2A7501B59B4465B41E3C7C50FB37F5606B6DEBA3D9D92322FC17BE3DC471E93CEA94A9EDF341F93CC19B630D64BE4CC72526838CC00F02D45305078471375F8139D11F37FF1A86EEFAABA2DCBD8627F3AC2F651403230DF9DCA8F88A20E3D8746810838CB1E8F69A4A86BFCDF8DF7D5B8F287859ABB791CD5DC110F5A4C175AA799BAC2AE1B72C147910DB94E05BCAED9EAD4BA68E4210143B6543EDFD7FAB161B9029B3CD0C08DADF06ABBBDBDD22A1BF1E654FE7914A935F7936EA91FB1B24CCB762130D7A0BF3FD2337D8E56F9D724FD5E9089467CD8DB3272DC90FF60E06DF812B694F72779816F9B7B52EFDBA8D3246D09001EAA5E820B195750222FDB4E856D69FECCFB92075EAF34A5FFE4F58AC3FEC0DAAE65DA621083908A2FD831A3417A36E5656BD2E448B865F90C6F059CA4862853D31CC8BB52CF699FE0DBC0C3A9411404819910EC5293F676212D317A227166EF9BDBE4567FB77E765724783F2F86263EE9280D0A76C42FB8724773D046C1C3581AEF4AD07FFE2D8FA4 diff --git a/src/libutil-tests/data/local-keys/mldsa87-signature.hex b/src/libutil-tests/data/local-keys/mldsa87-signature.hex new file mode 100644 index 000000000000..dae55effb425 --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa87-signature.hex @@ -0,0 +1 @@ +498BF0D1C00BD3E08E30F3C5C821D05A9EA314D15D7D3E884BF4EB919678D7D374ECBF941685894437B23AA18C6E4301082682DF82C9C9B8F78D53A22DAB782FBE141AF50382453D9F0DECA046CA5736E697BDCEB35EC881A61536E2D9682ED4BC7D265A9284A3CEA87EC7B9C4E5E2AD1ED8C4CCC32A7FC7FE47E449B348ABCAF204F590B8AC169FA50E8F7C91A8224EA5E0151234EFD010E0AC05B0133157B63F496BB9D54A6295E43F3826E12F4DCA1D4D1687A74CD2CBC7719282F595035954DF66FAA4E4D2E70BEDE9EE7856DA2AAACFA52E8723056C9D7EA1C0A38C19FACC17884796F0A04CBE1B3E3B5B1B6731EC8ED97474F8B08EFC3930D129CCA86ACF53033563DF7DC73DE741D7C17658D976168E02A56BCB47F3FB985FCF81CEB18E942D29A50A9E15C85EC5550432CA6A45FD25C50410B3CC0326F6DA67F002B90792876C2AF68FF552D6B863EE886B18800221C20F8CBF9A680795280F75F6E902C5E02662A59C8BCF16F129B45A35841D3032B73089736D6A36EE52E99EEC41179E9C8424526E868B1949DD225DF5DAC7994509CB61C0222624F7271D32317DECBFB5597894C082B5EA871F3E706B5BE56620A23D749F2E17060152A6703DAC4DF0D38B29C6704DFDA39773AA2A44D76A4FE662CDA0ACEAAD08F48C217AED4ACAEBD85E2B36D6CCB388AF7B534CED6F8D36340803763E9829FAD3702D8908BC321FA918F96448E5019CD264635E980D0997995CCA04AB302B3F93B25C5F28102D9DE2B285C20D1EF03ACFA7FE4447008A825980F6921969663F4F60285416D44F1BE49BBD64BEF4115AFF8CD4F1E5A2755ACF501CD7CA42F4916EEB6C048C781F12D8446AD13AC4E9955A4D1CB179893D0029F2DBC7131961ED1658ABCD743E0213FE9D45DE2BE92F324A7A797104E8F71C2DCBCD80ADE49C5CF298609F191D037B3883BBACF25CB0A11BCC29DB759DAE8B184B458F039AFF147397C843BB7B4774C7480E20DB4F5319D4C041C0CB618A9AE2E81A3EAA9DCE05F41698456068BFF39674445EAACDF1097F384E336207262A0F6B98879753D3FCCA7F580FB189D580B6A58A1E009CF4F47EB042E4387976C63079BB2A2A2B96F09895AF7227B3D2F3601467B7F70ACEAB6A0FFB04C103E0DEE7E1B59043503B42935D6A8433EAB5B05C03C7AED59A5BC50EC9BA81395D102C6C66B52C34A36301187404D84E809AFF4B8995B9D2129B06683E2E4D7C4591ED5050B465E894A4654F38C3CAEC3D9511BEF9341E14430DF8FEC166616E5D6E124CD6BF515CB280825F1682C0066743D71821DDD4FE579E20657A78E521CAA1012D15D819D3258F4CA24761E7F12EF47C364DF9CA35DE68FEF127AD7D9BD516CA65631AD36BB199CB0ECCE0EBEFADE1F7AF73B7DB3D505D5A27265846251C0642842C19002D28029EB9B226C8B1F4895B19E5B2DCF33E6D3C52F654DBF96D4448C43842DC6FB84C9616B7C6461D6761EE2B8F835A03328C31B42A562AABD28134FEF86541B45579E796A7BB9C4B859DA4693D613AB8B35CEB11E45DF87AC75F281E252B57C2983427F8E1EBBFE8BF38F9F45B1CEF693EF1101098565EC4A8AD55C6B3FEF7621E75A0EAAA2B3E85721213BC722ACBC3BEB34C6FAFCD2EDA4327EB7799C0F62CB308ED84C49913C57BC2A3FAF8AE4957E565370182323441150F1BFB0B87AEBF854BD37DE88CA56D3D0695474C3E4CC3E445C826893B2B5C25045F8B167B90C00A3E03329A8FBB78249BA5CA7AE2B3013D47AC7C109395CF587B3E4BAF8537721FBDF6CD646EFD72DDBC8201700FF85DEBA50EAB1F14C921A6202AD61CE745A5D0F61B542FB920872EFC2113A606BD466963AE97D9A2267860BDDE0F211025ACC6D5FEF6B5222C52662DD39BDB8B07B7EA773D8AE67E2B760C6BF8DCA4443AFC97650E7B27276213E1A347E2CA3AC65FF9BF066F94B644110D6694F79CF39C35A07C4A3AAA6C0DCFD437A01B3BB6D6AE5A78D727E3E73E8BFE8A75CDC394DB20B2787936964264029E471CEA7D27A72E6B68116620D0166B92B41F17417ADA6CD5A5B504DDA85171D233F77E0EC122012CA3A48B896151B14F379D83B87DDE3F9E0795EC5F11CB81E851868D24375E4E3961068C300ABCAC8F41C52024E0504AC773EC380CBFF6D15E8E85C0E49FC5925CDCF36765B2DE261E77C6845B7E0A4B3325C21B6FFF601EA96B25C09BCF4ADBE5E90928AC3343499018384A0ACA8879584A7B6D2206252F4FD0B6A93965B4609AD39553ED25C0CBE1CA120563B446F86D80865B9E086421595E05D9E341065654767A89C058F50E7E3685E1F6F42E4CC06E6AA987C695F077CEBDB8FC8694B116D38D992FD41E7A885DD9F3D0396007914761DAD88C5496F42001BD71E1BD2DC16E62375FB41AB58E8227FA950DD27742C30BF8B5C6D3BD7A45AD34F15C84271D5BB977EF5F65AACB899E840A8AA2139E8DAE9927A8E48CA797907377AE804B6123100802B2D4DE0A14B347D4782E1EAE1148899F56090541C8E5A82EB16F7284B60F73E33627E6C80936601C127C7414779BAB955A4D8B296D6AD9592DBCBC53DD2A22CBF3DB50269068068977CA89A11C33B36436D79D25D8184DC15EA778D417E4751346E57D05F509340733E36D8F93F9BC0DBA9B2268AD5131E2CC83D054F53661D79815001D29F07291B78816F9D632D8AB9306A38D2B972FE98D87DA541047FDA61B5D2B4317771CD92F418F53B50EEF4105639A1AF77204C3FD69B7DC6090F023D9A3810AACE73292BEFAB0A6C4D4B3C8A164C42D4C640290DF6CE262630E30DC31CF582338FDC1FECA6ACE5BAEE7994E00E8867D0B04A8854CBC4AD6D892FCC92F17ECB656AE303D0635DB7AC21CFA5A43B4012C7B7517A318E71E32B062369932FB42BE1A5B787CB78BFA7F00FDF08ED533758395DA85DB640DBE59375842E4072B76DC4736A6C059C3712A0760269F35461FB1341C4B9BD4C16E3F5D5D700601038BE8BBD76165C9CE5A4B0E7AF28224B6182E96B53432CBCE911920DB003D669BC6CEDB4F829E5FA4EA292D3EF16F6E876C8378953455969F45116D0D1EF4FCC986D8B0424BECCA52B09FFE4267C28148BD5F4462BCC70686BE01E159335026BC5FEDD3D8329C5E04D2FFECA97FB43DC88E9A68830CEEDC28E90B1E77ADBCC3C8408DCFF1A5C0CBC62418FAC212EF8C5A71054281F42F01070E03DD5456ECB652AD63AC161D4D1F139CB05DBB9FF18A2B2B3DE2B3C2CF4328D72D9BEDE401C6F3C8CC28816230B9D2CAB2DBAFE17639D180988859C2F6596FA0E766509FD3C6896B85F63FCC68E6096550B2AD180CC192F984BC626B08714627CC7E14FA206BA04C83AD39F0CD7B7F0CBA64E3A08219A5669256152BCABDA7CE13E684D1A79AC6F36668B5EDAF7D1BF16C325AD97893233925F2361C8C01EE280FE1EDD1D46E34ADE090E90A36C47E1CAE686C157C043090B90AE6943AFE03DB5257C1715EBBE2EEAADDC8F9EE827ECFD6E7FE3B5DE7DCBF14D817727DD15343F46C4B5861A30BB61F16F0D634E86371619C5072B01D0AD6693D2CB3AF5CF947346DB3BC9BE78FD945ACD95A67CDA9D3F2B534291028B47C5D0822A358D7D764C4F0479E72503AF9990CA52C61B478F6AD722BB3AE8BDC6BA8164A1F5AB53B2D91DB5512E61D2AF786EBD43DE2A6B66E0B7B2132853CB5C979BA9C1411A41CFBE06494DF2E9A2CC436B32C1F66E969EC597586E9CE2BD40FDFD663B28283C31776E2FB1F08664546DBEABED11B7F65CBCC66A952BC4780682DC0EF4A54E750D74098EB0CF0CD478D8B4EE87F2D4F7965605FA9A6DEF319F6310DC5183D01C755B08EA90E7F1065060BA0F2C978ED1358CD283E58B04B152A6ACEB32D9DB23EDDF635AFB394934353209A5AEC91D15E191FDC13CE670A85F90DC9F829F35E5C015C956AD8EA9DBFC2BE08A683F7970A5E4486835114836784761BBFB52BEE5E1A7EC5A264F8422714BC9EB5419644997456ECAC88C1FFD74712DCDFD7630CFF3129FED31F5D47E7CDBB96F340E836D76760D156CD470DF23C7925AB20B9EB3A91C25F138D281C5E07B9F5A6162F18A68DB9535A2B267523F3A33437EF707FB6A7F47E98CD72DEBB8960D6EF14C0E621C26120B83D0C809F4A5AB916BE6B602C298C119E09E20B7A85254FF871AA0ABDD91B08E0D61535F66DD5C3161205614105FDC784E4D43C5239C3F22B20922FBE4FF4A5EB483030D2BCA541B2D6E0BB8A7C6C253E7C3EC206B710BA5210C641174691455114A4AA212C27BF9E112F606880C9BEA27F9B1A2697943101DDCBE2E976A5F9148375B05378DEB1F84DFAEB82547F586B4AB0E5E019E706A3FC8B22A383D93EFCBA6AC8B974303BA8BCE73C760E61707859E330510FE4D63F6962F82BD3E7E45C86DC47DE8307491BE6066A0946C9B98818988F2DFB09558A1D3B446C3E1A0BE607D4595695419851DB07B1C22A227DC38453DA069AE706F5E9230E533EEC4DDF81E5D1A3C3E6843413774983CDBE9F3B739B8688156B1C01B5C9EC8E94AFDDE6A0EA73FE2D22C5707420A5BBE456CF6A009D72CA38A313A51FFF3A36E5C47DB402DF99BEFA103D7929DD62A0341EC0DF047520174DEF2B52F7C512135768424B6771621C9FC6075E3B6F0B5EAC5C2249E1AA539A132976D6FC6FEE7CDFBFA4FB895E4ACCFD73CD46C675E7A1937FCD3ADB71A6661BE852EEF1A7C7A0140D9877A7A8B50CC324DBA01970DADAF33A8A6D73BF6AD616D61D334695F2DE5CC906D0B680AABDE20AE71B40FF574B2E61EEB3912E630954FFA8B848D00209775FC2B75667A6BBCDD47527191D2C94B4DE2DC97AA830E0B9B52B8ABF4782B69D4061552532F81780947AC2AF25781E78913B044CFD99ABBC6E58F535372F71612CEAA4C51A354BDC40E628B9AD51056DC092CCF291711B0A5850501BB3F40B08E6209563EBA84426B31AF10CCD14E898E9CE2CF8E4BD136578DB7271B6D8442C8F984A76F2BB4BE488837802B2466A277CDC0FF7A24DBCD44D5D74C9EA3E6E20A46D4A4B1A5CD2A3B9975297B22855F4EA6F0B58495819F5708B336AF7CA7C7213887033289535FB15C55D72AC3AE733F0C81DB13E0196932E65CDDF28A5BFAD29BF07ABDC4E78746E79EA62A471B94E127C3CC65C19054A71B75ED7B4E747836FD2091A6A544814CD900D97EAD77DBAF2632E209969DFC8ABF87809A745A293F37C283A51A999A9ADD9A06B355A78C86696F193C4729FB27ABB82C6B4D93FC423FA6402E54F260F12A71EDB0A173D4F31A3F4BFD920AC4102C05BBFA8BCAEEF1325AE16E892C88DFE282193FD506716EE250AB3D9C1A73FBBEE0580436666CAF38D49654D5594182F3B6FF32DDFB0C422CC15A213DE17096AE31A7E8D90F37E89518DC81BFF8E51EA45F46F6CA305909BCB01E7E8171928E427F29B874BD875E74C20B3BC2C2813B0891B7AB403CD1951EC46E23431766D4103C8E3BD643C01694D31C3295AA7133816CD90F77894ECC0D5B901F09EB317722FF17F340AA499A29DB5950545E952317F6051EFEE982DBBCC64F95A207C1A99BF0D2F55F5C5CB58A37B0B31ACBE68D5874AA7CD561FBF66654690A5C0C6FC8AC84B9C0DA8BF6549F2579045E344EA44FF328BBEA1DB2E5F415D3541EFA8E525AD3C8E9C30314065AFB82BFA769FE257CB1CD369500D646C891A6BFB03B6D69833AB72A8F6961F6FDF3EA5D9B98558DFE833554D8D41C0E79236C8F0E352EEAE6A99EA0BAB4F52DA7A92B4698C107DAB1521CFF4FFFCB307E4BE89F56028B349FEA9D36B0995BA1A8B495D03DF7BD9D20B5DACB4D674B46A9BB9461FEEE556E2940C61C709F4EABE8A0206D728FE96C76B1F4EDD5F94625CA104F11A01C87B8ED83DB443D17103925BFC3F77C609C92C441222AC717E19BF1065A159D87328437BA007AB4FA262145610917D4481CA5BAA94F49965C67E08A62EE454FAB3F7F1067EC27D644C19AB16ABF4FA68DA102D185DE15E474C4A004BC52CC7E485CA9BE16B384AD41B31550155718D586AA112B4E2B6FCC1FB9A6765A411AFBFADFACD46055B4B2D1614267157F86A0CC0FC1561FE52DBDD2716C7D394AEE756053075E89A6E2CDBE5BAC1620C53EF1060710F20AFBFB1BDA04DEDC016DF8282D35AE42B06DBB7B618BB13D7401504F2F964DF8DF55919EA5C35710808CDA952F6A9DDD9FE392433EB672BC2506C8F2AAFC88D3DEDCC103C1815CEF8B36EA06CB38B9DBAB6417A7729555117A9CC6D0803814A7AAC5C48D8204053EC837F71AFB68E355B5AF17D57CE929931FD098FB473440BCAAFD22681238C603A3C063ACAEB2542BE9C8A0608EB280762A6D930D354892ED0E9370683EB3177DE3CC8360B5671D86098D652FCF6641B13B551EDE758CC8306083A6B94596C6F83A2BECF2079BCBDC3D4ECFA8DC3E154AFC1C92236979FBE0E1B29304A62828B92EAF2F3F5002FB6E00000000000000000000000000000000000000000000000000000050C14171B202D31 diff --git a/src/libutil-tests/data/local-keys/mldsa87-sk.hex b/src/libutil-tests/data/local-keys/mldsa87-sk.hex new file mode 100644 index 000000000000..025cf4d1626c --- /dev/null +++ b/src/libutil-tests/data/local-keys/mldsa87-sk.hex @@ -0,0 +1 @@ +2AD180C0AD68E081C265C682EE82AD88A5D0F5EB9F5B9DFDF387B175B214F297965468E54AB2B99C74A344B633B1102E5BA80B6372BD5430A208EAC14C5F822A91809D572C4415D402BF56BFFE22FB9FD0A2D59079D0DB408DCABE82ED2FEE0D12E26A27F4B784E56BA8AD02474DD75DB5CB35F79E1862DB95F2602B5C827E2358102E9A0444020592039685DC2812E03442202901A29424E210905B044013C4818C400098A82588320214882104492901264064246C4CB22493A68D02280D98268A80482413228D1C330200C50D5B048210B849C83421510641128561900408A09850D20428C002258A4441D812224842091CA190A1348D114861DC4600838261C1A28813244818116C8A020508B0101009698C06201C044AC4284E10808582A08D613209E2322221346060C41062242E1191218CC26C14C31009212940A2501C134259902459C48C9BA26882A6890BB50023408DE442860A982D04878150428658486449A68901405013B1690221819A0872D4A0495BC249183061C3A009D2360E13004813152424926159964983146412C68D1034308C80498B926D9482801CB36854082A514466618831DBA80481404ADC1412108841C2428A4AA009038071C846204A484D43C625C11885DB808411C49121206E194285C216901B090CD04442DBB091E0360A4BB408D43262584831C2C200188810C186915B2229A3142C0929028B3892149561032468E4006900263050A68CC904840C01660916424BA4311CA28009040861B28904406A0905292143250CB548138501E100228B924058864558068682128681304ED1C224DB2644218705620660E390884A00294232291C4012C2800951B8098B200D88428454424252228C4C38201291295038454A3452D13090E2A64DA20285511880A11604A2968858B28CDB946D04A8710A34614A222158420941442AA036611A00525238611C42841215480BB60150364D02C005CC124E841869211729E4C860A2A6850A278A20154A8B38459B2802409801588631E126620B386A1CB08C24C98504164CA496681A46898336014A489001B32464020CCA828050C62DC008911AA41021214D03410C214582A3364EA12672E2C24D1C130E23A8615408490BB09190266D92866C1034460B9584CA0421D224709CC83192064E82047148440193124963368C53206ACCB28811A3051140261A428E83144C503442842250438401430600DA94441826411922620CA86D98C8285C820011C151814032D22430D88488C2322EC92472DA2471DCA64CC3128500824861A01094162DDCA46D9C8825C34242C446082049200088084330488B9288C9922804966900B39014126022B871C8A82023B2294A880DE31029C9A21051820103806054866DD9926C8A2852E0382A83402514A15001080119B48522924C21C4712448250193001BB18008A04421084C4B0869A4A04549A64089225210118D08228DC828825384084A16844326910991040A820C43325214C670182121583849E192610A452A54284018140E8B4451A4A29149204D9A00928C06319B1080C81812608644583442C01452E1328C0C9561D3442A1AC844504422CB14628316421C184201C82551206A4C420612370900158189C4252294684C848D52042689A66944482924A468840471224071A4B20C52329208882541B01124A20DC9042E50B444534662141722E1888D43860883224112836881104588A64C4C962C5C1825040290131642008828E2A8204B1244124428C9A451D812459B18601411114B1082E2467081124A51148824A76C8A066A93468013A6454448880CC00DD1088A52842054C444C1886599001222428910868C10A84D89B410D32262411010C18644214325C9342013122D94C244C2B82548A00064104C981682DC928D50182D01426CA21090048800A294888AC444108069C3148A1B410A0A0548A4B2480C1721A294700B8040841045D9B2100B425011A360400002633424603224C036228B808D5B182E0B134610B069219345203982D23860C44080143285533068E22882A2C621D9C4250246901A470420C2680AB450D4268611425222A46C434624C4102624938411218662268100246E1A2806184820193151D02885E1946CE4C20519C4711B097158464DA32652DB205012246923A161CC18021A0451E11408C9042514933150006EE9D68E6DF390D82306189DF75CCA2FF9A73B51414FE2658B006D3276473B8441F4F0D545B017BB0F51517801048D8ADEDAEA6BF0EC994F1D1F168F739BB0039AD8ADDA327812A1766E400A870DFE6AE610F994520C2A92336E0EB53ADF88644A81F7BF76FBE33072542FF20C31D771D24AD0591C622DC98C3E407243EC3FD9DD453455719A174C9E682638D69555B4A4B907AE087A7A5C414D6ED6472E6AAAE648F973C41BD28D76B3464413D52C83B1111C67564D38669A925A085D322D6DF6F4153497CBABF5DE5E11082974940012071399CEE5176695EC6774A0D37253724ECAB2B1D26B6A620CCD4ACF66C5C5C18FC7F92DCA1E707655CDC6A89AF423AFE8B39C6B8AED86B1501E1BFBE6ACA628938453AD1E97C4FD567E74DB3842EB5D57D3C2FCF462FC9DBC1CD7E52BA8D87CE7648DADF669389C2D9481E3658BE8F6B41FFB290C89FF9F105F945428F15F5962B83A33BDE918C3469F868D9CF19A3E76178C7A670333A248B42B99AB01CDC231EC6C3AFDC4CD971CBD5AB98756CFC6D11D6C5B766A07381D7305A396D075A0593E89C2353FCA87F86C25E1C48AFD08D0218A4F72C4A075B5E0097CF88ED15D40F25C3C421B3D92C902CA6C92323A97257CB0F9ED3FFF0898DCFAE4D14A17ECE76560540251486EC22F9A00821B7E956ABA4CF7820B9C7F488359CA55752E30EB4590FCB080A22F7CD0E4DB92FD2283398D13B796C5B55EBF3CA0660E1D04C2F93932D258885579FACE2358416EDB0DEE92E7AB59BDFE1F0D12191AC9D1A6A7CF7EFE2FF7B2B23864C802B4A5D0C696779C79D89D058CC9FAF9F9473363DD044B176C22C5EC719A692CBC6A97C13E270CDB5004F20ABBBE75809531B13A581BEDFF6E3BAFB588FF361DAF136B68B440C7B536AE965462F7C0CD0B26C4BD623C36D3BC247E1D49A58769DCB670716F657DA75986BCB1F630311478E54C9AD70C963FDBAFECD1419A15DD4D938A7AAE6E0365B89214316BD81BF28EB646B52F1998C93AC601EEDA721805B57B52790DAAF4DB77351CF4AC2014BD692AF13295B18E307C113F3845BA8EEE88B1A52ED5F6E6E6376807951879D5023E1C41038D023FA8BACAF3704C67A037F768E9755DEDDC61E66DD7A9500B924832E5B5732B40B4CAEB2C34EDFABC3E3EDC9B59A201EAA5441FBE3D8BEF3D94DEDAB0069BBF2D4E769CEB551D1A0A99B13E06D2F2761CC735A4F787E2655C704261D7167D349C60F006979F2BA2E1F5FB65F5F08B2708D94FE3F6871824EBFF2F44D2228381BB7F3ECA69514D1D491C05919A246459E70E9FC94645A05A287234EBC4DF76B6352978A53CE0A0A6B63289A19D6A25069B3A87E578423A033F4906A44B3BEC4202CBD3D528DA02737A897D71E9AD9823D7CC28AA1DB9CA645357F1B07D66C7934C7CF9B64F0B85EECB0C7D3FCABA571868EE83C9B53D7A3277029AFEF9899E09B9515BDEF4BC0FBFB976BEEFC2CE629EA713529ED924EBFD106495062972EAE40E2610FBEA65BA118125C05186CFDAB0EC01C384669323EE4A4BE2CF005438FAA7EDF4EB22CFDA6E14B9F7E03282E3520CD1B5F0A15E47DEB218A747B15DC034B1CAA665DFA619788D2D07E6C58AD120451F67D6E3F310FE44854BD5B035E2A101D4164EEC6EA42AECC9D9A50EC472BDBA4634E2E96C51380037FB2E58731D1B237486C132E15813A5C04525EA29B71F849D8F910FC332BF7839FF602C100CA2CDCD96163B31E3528444C82713FBAD64F990FE33EACA8B8DCADA5B1990BEDED44661FA75543D7121671BCD069B43252398F897D39E2A04B9FEA4926AD773F38EEA1E9C5B23E2656D936453F6ED418375D52EA7B01D56654DC84237D63DA2FB941AE06DA734A9BE27FAC9892C33F284B39BB987F9C41F4394ED236BB930F0973CEBD732C441617C8EB95FBAF7CCF0D894D9A3194579EE485573498BD80B649F50241F80A33119214F0DDF2089A56DC42FE1A90A5D82AC13ACF5418305C1DC6D76A2AFB7903F1E1278EAD84C11652B2BD28B5DBD48E7A081170A3918C2F8DCFA038B67BC99A8B396CBAD4855A9916BA52487CE1995F77F2755A70E398DC65E752BF5D0F888F54A255413824AF9EA976B5CCF4102964C2E0BD0ABC69B834E6BB4BBE32040BA829CEFA2557357E2019BB87AE7A31C42CBC8982BCDB23F2C37D695E52CE1B4728729C216A5A348EBDD01D2CB07D4B30F16303C7AEC30D16AE99C7F9611CF2CC209106D5B4788CDC08A5C98374E56FF3C52A30D7D24C67E2402519CAC5514498372CD81D0D3D6A9B859E58CA3C0DFF22A2CBAE5E321FFA103207400C9C31F6C8E2D9888602EAD5AAD25600A32B9A15761EA5325D10273972430B829785E24754BA2684FFD15028C6F1CCD6F19A3B2F9C32F85F8AEEF72F11E79658CEF99A6A4F091732384D3BAB63EA1202D9D3A7DEA2B2616E9DA4F1660EA80EB50A24D9B07BC060639562C561D070E803211CD93AB9E7D5A07357E3E539CA273FE994B55C869389A84BBC56E8EB708DFF5CAE5F07FA84F5073FD9B777E1A193849F8009B83ACA1C6C97998E6C78D297C708980590BF7C3EDA267C98C0795443E3BEF8BE2308AF6D11FADDE82A1E1B403043A268548673485B2414D8B762D278E75080DD09F4969724DE3FDD869A2F1E2B9A37197C0DFCE2144705E9FD91CD1BF5FF282A454836F35DAEEE2E3D1ED3B0953310A2DBB5FE108AA7E7E1F28A1A3FAC39E042A0FF48C5109628FD968B05A9B20813ADD8AA75585438F2183CAA29F0DC91D4D040669602D0FE19DFB2B9E353E940BD0C74C63BED2467B8630AC1C301E71837544ED17944673CBBCD68E584C60F326B059FAF64C7FAB1AC2DF7B2766FCDD9186755D018B5C19B39673B0293264B877ACE5C123374A680858ACB45AE9475B1B8D95D94A6534B86CBB74813C50E8C30B8B779A5F5225F823FD02368F767AB95B5986F39289E033F45B6742784F39131D96E5D8CDBF225FF6C03684086485B96C839CCBB285BFC1D631CEB87840AE9245440DF46D21CD77E7CFB0124012C1C4875ACE1C4290101074FD7B2CAA25AB4AF68C28C5D48797931CFFE46DDCCDD11C776A4AA0C20B27B7A24107B27184DD3D26F7300B5078572C6F2C724CD0B504C186AE19023D825A59E968D4D4F66E340F2894D603DE58E3A5C5293D6DAB9AD182FB5BC14888CCD698113AF3A5D7039FA7E48FEFFD6942129BCB436026E486EE9AC994AD28CE8D885469A5F7B627A2E62AF68C402518396D9D17A738D0DBFA2F2DB6FD48534B8516F4D01C3A21ED023775E6FB962B0E5322A224E5D86275188D1A59F43749BD3793294F9643A0C08EA08E26351FDD474F5C8B036621D512AF88B169EAA6BB87949E50854E05B78363852E1172776FD88B32832988985564983E120B2DFD06E98541F26E51837C821628645F2AABCB3CBE9DE9AE585434DA2947CD077A243DC43BD4DA2F940B89818FE193D1754EBFDB454702FC9235F46BE9DBE0103A4BD0981AF64EB4A695EDBC4204C1FD2C2C3530C994280A2DD6B9011DA7CB68BABC5C0DBF1222BDE403770CEA1283E7B87764555A9841E86202A6657E5E6948F0A473D8AD902BCE510D5B15086BD34A1BBCB5C3EDB7E0045F1D6D377A6060358917C641DCA7921C761F359A97AB86CD00E6077B4519CC802600A8D17FCD32227D043D78DCD766A4F068F9CF2F58AE5FF58F96721F72FE917366C7B08E98081A7F4C87A669E17E9E0AD0C2C8E9FD6D07496D7FBCD47760EEEEA5F2685A2C98BB211212411CB5D4318CA1B741C8DFA0062E5375C9F199507748C6A76C945718D460710C80FD16847C35373E034D09DFE39ED579AA31F72CC4583D98E37E5D35394848C8BE777CCA9C0B68F452A916FA68A23DFE78A20D4E16EF31EA633468F58CB1280C619721F94C34F5241F15A04AB105F9764F117E71CCFA265387EA47B537150692FCADB6DF1CB0C3F7CB725BE932F0891B343FCB2EDDB7C24F77F296C69541B070E58BCEEE9C08D0EED5FAEDFADF39061C4CB9559E2686D846EF43E19EE920579D70944003BBA729DBCC0197A46ABD9C1B86AF9344B6B5800D573E7FA3CF0C4C20D4E69BE26C902E008CF068C34DC855AFFEAE85F41DD70D003930DECC1064BA8D6459B1CC17BBD1942E733B4B293AA6B3B081BC97B735BF213BB838CE199690E4E876990C0335D05E41D7DE02E6EC54E99E80523B3DC2E3D4AE904D74FAB55D6CA0E31E62BC54885BB6CD9BD81CDCF263F48BA7648427F8A954BD3144E670B0618AEAD6F81E093B35435021F07161926ED9E664D7805344A042BF07DE6DBC837A41D27A4C81C36EB16AB31BB16EA0919DEF73091FF7BD8A6C89250E2C980A5F4B9AF2DFDD66EC23D60F1BCEA538801451C3AAAEC208526AF893A286C55A1648866D0A166709CAD4CAC3E9ADC5D8C6058BE13FA1F11CA65F01AC7FA5E5A99425340B4ADC350EA483AF19E637AD364EA62911680428FC830928EC86B77E82CE39312E8A63FDDA30524452EFCDC6FF0294CF582B00CC2BC2032A742EC2C79E56E698BA9AC6B0D9301AC505242E8FFEED7C335A66A761CC80F07F832B146233C3A567CB5795A472471960043AFD78706B5ACF62782A0CB547595B040682EF11603DC5CD86E2315E4EEF07C49854B069BE248005D00CE0EAD4CC4EFDB7231F5BCDCB3387504D16CD50276918E90303F4A3 diff --git a/src/libutil-tests/local-keys.cc b/src/libutil-tests/local-keys.cc new file mode 100644 index 000000000000..fc83ca8da825 --- /dev/null +++ b/src/libutil-tests/local-keys.cc @@ -0,0 +1,253 @@ +#include "nix/util/signature/local-keys.hh" +#include "nix/util/base-n.hh" +#include "nix/util/configuration.hh" +#include "nix/util/file-system.hh" +#include "nix/util/util.hh" +#include "nix/util/tests/test-data.hh" + +#include + +namespace nix { + +TEST(local_keys, signAndVerify) +{ + experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::CNSA); + + for (auto type : {KeyType::Ed25519, KeyType::MLDSA44, KeyType::MLDSA65, KeyType::MLDSA87, KeyType::ECDSAP384}) { + auto sk = SecretKey::generate("test-key-1", type); + auto pk = sk->toPublicKey(); + + auto sig = sk->signDetached("hello world"); + auto sig2 = sk->signDetached("hello world"); + ASSERT_EQ(sig, sig2); // checks idempotence of signing + + ASSERT_EQ(sig.keyName, "test-key-1"); + ASSERT_TRUE(pk->verifyDetached("hello world", sig)); + + auto sk2 = SecretKey::parse(sk->to_string()); + ASSERT_EQ(sk2->name, sk->name); + ASSERT_EQ(sk2->key, sk->key); + + auto pk2 = PublicKey::parse(pk->to_string()); + ASSERT_EQ(pk2->name, pk->name); + ASSERT_EQ(pk2->key, pk->key); + } +} + +TEST(local_keys, rfc8032TestVector) +{ + // Test vector from RFC-8032, section 7.1. + auto seed = base16::decode( + "833fe62409237b9d62ec77587520911e" + "9a759cec1d19755b7da901b96dca3d42"); + auto pubKeyBytes = base16::decode( + "ec172b93ad5e563bf4932c70e1245034" + "c35467ef2efd4d64ebf819683467e2bf"); + auto message = base16::decode( + "ddaf35a193617abacc417349ae204131" + "12e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd" + "454d4423643ce80e2a9ac94fa54ca49f"); + auto expectedSig = base16::decode( + "dc2a4459e7369633a52b1bf277839a00" + "201009a3efbf3ecb69bea2186c26b589" + "09351fc9ac90b3ecfdfbc7c66431e030" + "3dca179c138ac17ad9bef1177331a704"); + + // libsodium's 64-byte secret key format is: seed (32) || public key (32). + auto skBytes = seed + pubKeyBytes; + auto skString = "test:" + base64::encode(std::as_bytes(std::span{skBytes.data(), skBytes.size()})); + + auto sk = SecretKey::parse(skString); + auto sig = sk->signDetached(message); + + ASSERT_EQ(sig.keyName, "test"); + ASSERT_EQ(sig.sig, expectedSig); + + auto pk = sk->toPublicKey(); + ASSERT_EQ(pk->key, pubKeyBytes); + ASSERT_TRUE(pk->verifyDetached(message, sig)); +} + +TEST(local_keys, ecdsaP384TestVector) +{ + experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::CNSA); + + // ECDSA P-384 / SHA-384 test vector from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/P384_SHA384.pdf. + // The signature was produced with an explicit (non-RFC-6979) nonce K, so we can only verify it here, not reproduce + // it via signDetached (which uses deterministic nonces). + // + // Q_x = 3BF701BC9E9D36B4D5F1455343F09126F2564390F2B487365071243C61E6471FB9D2AB74657B82F9086489D9EF0F5CB5 + // Q_y = D1A358EAFBF952E68D533855CCBDAA6FF75B137A5101443199325583552A6295FFE5382D00CFCDA30344A9B5B68DB855 + // R = 30EA514FC0D38D8208756F068113C7CADA9F66A3B40EA3B313D040D9B57DD41A332795D02CC7D507FCEF9FAF01A27088 + // S = CC808E504BE414F46C9027BCBF78ADF067A43922D6FCAA66C4476875FBB7B94EFD1F7D5DBE620BFB821C46D549683AD8 + + // DER-encoded SubjectPublicKeyInfo: ecPublicKey + secp384r1, then 0x04 || Q_x || Q_y. + auto pkDer = base16::decode( + "3076" // SEQUENCE (118) + "3010" // SEQUENCE AlgorithmIdentifier (16) + "06072a8648ce3d0201" // OID 1.2.840.10045.2.1 ecPublicKey + "06052b81040022" // OID 1.3.132.0.34 secp384r1 + "036200" // BIT STRING (98 bytes, 0 unused) + "04" // uncompressed point + "3bf701bc9e9d36b4d5f1455343f09126f2564390f2b487365071243c61e6471fb9d2ab74657b82f9086489d9ef0f5cb5" // Q_x + "d1a358eafbf952e68d533855ccbdaa6ff75b137a5101443199325583552a6295ffe5382d00cfcda30344a9b5b68db855"); // Q_y + + // DER-encoded ECDSA-Sig-Value: SEQUENCE { INTEGER r, INTEGER s }. + // S's top bit is set, so it gets a leading 0x00 to keep the INTEGER positive. + auto sigDer = base16::decode( + "3065" // SEQUENCE (101) + "0230" // INTEGER r (48 bytes) + "30ea514fc0d38d8208756f068113c7cada9f66a3b40ea3b313d040d9b57dd41a332795d02cc7d507fcef9faf01a27088" + "023100" // INTEGER s (49 bytes, leading 0x00) + "cc808e504be414f46c9027bcbf78adf067a43922d6fcaa66c4476875fbb7b94efd1f7d5dbe620bfb821c46d549683ad8"); + + auto pkString = "ecdsa-test:" + base64::encode(std::as_bytes(std::span{pkDer.data(), pkDer.size()})); + auto pk = PublicKey::parse(pkString); + + Signature sig{.keyName = "ecdsa-test", .sig = sigDer}; + ASSERT_TRUE(pk->verifyDetached("Example of ECDSA with P-384", sig)); + + // Tampering with the message must cause verification to fail. + ASSERT_FALSE(pk->verifyDetached("Example of ECDSA with P-385", sig)); +} + +TEST(local_keys, rfc6979EcdsaP384TestVector) +{ + experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::CNSA); + + // Test vector A.2.6 from RFC-6979: ECDSA P-384 / SHA-384, message "sample". + // Our signDetached uses RFC-6979 deterministic nonces, so we can reproduce + // the expected signature exactly. + // + // x = 6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8 + // 96D5724E4C70A825F872C9EA60D2EDF5 + // Ux = EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64 + // DEF8F0EA9055866064A254515480BC13 + // Uy = 8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1 + // 288B231C3AE0D4FE7344FD2533264720 + // r = 94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C + // 81A648152E44ACF96E36DD1E80FABE46 + // s = 99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94F + // A329C145786E679E7B82C71A38628AC8 + + // DER-encoded SEC1 ECPrivateKey (RFC 5915) with named curve secp384r1 + // and the matching public key embedded. + auto skDer = base16::decode( + "3081a4" // SEQUENCE (164) + "020101" // INTEGER version=1 + "0430" // OCTET STRING (48 bytes) -- private scalar x + "6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5" + "a007" // [0] parameters (7 bytes) + "06052b81040022" // OID 1.3.132.0.34 secp384r1 + "a164" // [1] publicKey (100 bytes) + "036200" // BIT STRING (98 bytes, 0 unused) + "04" // uncompressed point + "ec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13" // Ux + "8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720"); // Uy + + // Expected DER-encoded ECDSA-Sig-Value. Both r and s have their top bit set, + // so each gets a leading 0x00 to keep the INTEGER positive. + auto expectedSig = base16::decode( + "3066" // SEQUENCE (102) + "023100" // INTEGER r (49 bytes) + "94edbb92a5ecb8aad4736e56c691916b3f88140666ce9fa73d64c4ea95ad133c81a648152e44acf96e36dd1e80fabe46" + "023100" // INTEGER s (49 bytes) + "99ef4aeb15f178cea1fe40db2603138f130e740a19624526203b6351d0a3a94fa329c145786e679e7b82c71a38628ac8"); + + auto skString = "rfc6979-test:" + base64::encode(std::as_bytes(std::span{skDer.data(), skDer.size()})); + auto sk = SecretKey::parse(skString); + + auto sig = sk->signDetached("sample"); + ASSERT_EQ(sig.keyName, "rfc6979-test"); + ASSERT_EQ(sig.sig, expectedSig); + + auto pk = sk->toPublicKey(); + ASSERT_TRUE(pk->verifyDetached("sample", sig)); +} + +/** + * Run an ACVP ML-DSA-sigGen-FIPS204 test vector (external/pure interface, + * deterministic, empty context). For each variant we load the ACVP `sk`, + * `message` and expected `signature` from data files, wrap the expanded-key + * `sk` in a PKCS#8 PrivateKeyInfo DER (per draft-ietf-lamps-dilithium- + * certificates), feed it to SecretKey::parse, sign the message, and assert + * the signature bytes match the ACVP output exactly. + * + * `derPrefixHex` is the PKCS#8 prefix to prepend to the raw expanded sk; it + * encodes the outer SEQUENCE, version, AlgorithmIdentifier (with the + * variant's OID), and the two OCTET STRING headers. + * + * Source: + * https://github.com/usnistgov/ACVP-Server/blob/15c0f3deeefbfa8cb6cd32a99e1ca3b738c66bf0/gen-val/json-files/ML-DSA-sigGen-FIPS204/internalProjection.json + */ +static void +runMlDsaAcvpTest(std::string_view variant, std::string_view derPrefixHex, size_t expectedSkSize, size_t expectedSigSize) +{ + experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::CNSA); + + auto dataDir = getUnitTestData() / "local-keys"; + auto sk = base16::decode(chomp(readFile(dataDir / (std::string(variant) + "-sk.hex")))); + auto message = base16::decode(chomp(readFile(dataDir / (std::string(variant) + "-message.hex")))); + auto expSig = base16::decode(chomp(readFile(dataDir / (std::string(variant) + "-signature.hex")))); + + ASSERT_EQ(sk.size(), expectedSkSize); + ASSERT_EQ(expSig.size(), expectedSigSize); + + auto der = base16::decode(derPrefixHex) + sk; + auto skString = + std::string(variant) + ":" + base64::encode(std::as_bytes(std::span{der.data(), der.size()})); + auto parsed = SecretKey::parse(skString); + + auto sig = parsed->signDetached(message); + ASSERT_EQ(sig.keyName, std::string(variant)); + ASSERT_EQ(sig.sig, expSig); + + auto pk = parsed->toPublicKey(); + ASSERT_TRUE(pk->verifyDetached(message, sig)); +} + +TEST(local_keys, mlDsa44AcvpTestVector) +{ + // ACVP tgId 1 / tcId 4. id-ml-dsa-44 OID = 2.16.840.1.101.3.4.3.17. + runMlDsaAcvpTest( + "mldsa44", + "30820A18" // SEQUENCE (2584) + "020100" // INTEGER version=0 + "300B0609608648016503040311" // AlgorithmIdentifier: id-ml-dsa-44 + "04820A04" // OCTET STRING privateKey (2564) + "04820A00", // OCTET STRING expandedKey (2560) + 2560, + 2420); +} + +TEST(local_keys, mlDsa65AcvpTestVector) +{ + // ACVP tgId 3 / tcId 40. id-ml-dsa-65 OID = 2.16.840.1.101.3.4.3.18. + runMlDsaAcvpTest( + "mldsa65", + "30820FD8" // SEQUENCE (4056) + "020100" // INTEGER version=0 + "300B0609608648016503040312" // AlgorithmIdentifier: id-ml-dsa-65 + "04820FC4" // OCTET STRING privateKey (4036) + "04820FC0", // OCTET STRING expandedKey (4032) + 4032, + 3309); +} + +TEST(local_keys, mlDsa87AcvpTestVector) +{ + // ACVP tgId 5 / tcId 73. id-ml-dsa-87 OID = 2.16.840.1.101.3.4.3.19. + runMlDsaAcvpTest( + "mldsa87", + "30821338" // SEQUENCE (4920) + "020100" // INTEGER version=0 + "300B0609608648016503040313" // AlgorithmIdentifier: id-ml-dsa-87 + "04821324" // OCTET STRING privateKey (4900) + "04821320", // OCTET STRING expandedKey (4896) + 4896, + 4627); +} + +} // namespace nix diff --git a/src/libutil-tests/meson.build b/src/libutil-tests/meson.build index 5938aad02f0b..3c08899de331 100644 --- a/src/libutil-tests/meson.build +++ b/src/libutil-tests/meson.build @@ -68,6 +68,7 @@ sources = files( 'hash.cc', 'hilite.cc', 'json-utils.cc', + 'local-keys.cc', 'logging.cc', 'lru-cache.cc', 'memory-source-accessor.cc', diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc index 334a410bb863..bcd4cf54624a 100644 --- a/src/libutil/experimental-features.cc +++ b/src/libutil/experimental-features.cc @@ -25,7 +25,7 @@ struct ExperimentalFeatureDetails * feature, we either have no issue at all if few features are not added * at the end of the list, or a proper merge conflict if they are. */ -constexpr size_t numXpFeatures = 1 + static_cast(Xp::Provenance); +constexpr size_t numXpFeatures = 1 + static_cast(Xp::CNSA); constexpr std::array xpFeatureDetails = {{ { @@ -305,6 +305,16 @@ constexpr std::array xpFeatureDetails )", .trackingUrl = "", }, + { + .tag = Xp::CNSA, + .name = "cnsa", + .description = R"( + Enable support for keys and signatures using algorithms from the + Commercial National Security Algorithm (CNSA) Suite: ECDSA P-384 + and ML-DSA-44, ML-DSA-65, and ML-DSA-87. + )", + .trackingUrl = "", + }, }}; static_assert( diff --git a/src/libutil/include/nix/util/experimental-features.hh b/src/libutil/include/nix/util/experimental-features.hh index 85ca58e23da1..f2bdecee5e54 100644 --- a/src/libutil/include/nix/util/experimental-features.hh +++ b/src/libutil/include/nix/util/experimental-features.hh @@ -41,6 +41,7 @@ enum struct ExperimentalFeature { WasmBuiltin, WasmDerivations, Provenance, + CNSA, }; extern std::set stabilizedFeatures; diff --git a/src/libutil/include/nix/util/signature/local-keys.hh b/src/libutil/include/nix/util/signature/local-keys.hh index 789fb831f0f3..6d7620335174 100644 --- a/src/libutil/include/nix/util/signature/local-keys.hh +++ b/src/libutil/include/nix/util/signature/local-keys.hh @@ -41,24 +41,28 @@ struct Signature auto operator<=>(const Signature &) const = default; }; +enum KeyType { + Ed25519, + MLDSA44, + MLDSA65, + MLDSA87, + ECDSAP384, +}; + +KeyType parseKeyType(std::string_view s); + +const StringSet & getKeyTypes(); + +// FIXME: remove this class. struct Key { - std::string name; - std::string key; + const std::string name; + const std::string key; std::string to_string() const; protected: - /** - * Construct Key from a string in the format - * ‘:’. - * - * @param sensitiveValue Avoid displaying the raw Base64 in error - * messages to avoid leaking private keys. - */ - Key(std::string_view s, bool sensitiveValue); - Key(std::string_view name, std::string && key) : name(name) , key(std::move(key)) @@ -70,27 +74,35 @@ struct PublicKey; struct SecretKey : Key { - SecretKey(std::string_view s); + using Key::Key; + + virtual ~SecretKey() {}; + + static std::unique_ptr parse(std::string_view s); /** * Return a detached signature of the given string. */ - Signature signDetached(std::string_view s) const; + virtual Signature signDetached(std::string_view s) const; - PublicKey toPublicKey() const; + virtual std::unique_ptr toPublicKey() const; - static SecretKey generate(std::string_view name); + /** + * Return a PEM PKCS#8 encoding of this secret key. The Nix-specific + * key name is not included. Only OpenSSL-backed keys (ML-DSA and ECDSA P-384) are supported. + */ + virtual std::string toPEM() const; -private: - SecretKey(std::string_view name, std::string && key) - : Key(name, std::move(key)) - { - } + static std::unique_ptr generate(std::string_view name, KeyType type); }; struct PublicKey : Key { - PublicKey(std::string_view data); + using Key::Key; + + virtual ~PublicKey() {}; + + static std::unique_ptr parse(std::string_view s); /** * @return true iff `sig` and this key's names match, and `sig` is a @@ -104,20 +116,20 @@ struct PublicKey : Key * * @param sig the raw signature bytes (not Base64 encoded). */ - bool verifyDetachedAnon(std::string_view data, const Signature & sig) const; + virtual bool verifyDetachedAnon(std::string_view data, const Signature & sig) const; -private: - PublicKey(std::string_view name, std::string && key) - : Key(name, std::move(key)) - { - } - friend struct SecretKey; + /** + * Return a PEM SubjectPublicKeyInfo encoding of this public key. + * The Nix-specific key name is not included. Only OpenSSL-backed keys (ML-DSA and ECDSA P-384) are + * supported. + */ + virtual std::string toPEM() const; }; /** * Map from key names to public keys */ -typedef std::map PublicKeys; +typedef std::map> PublicKeys; /** * @return true iff ‘sig’ is a correct signature over ‘data’ using one diff --git a/src/libutil/include/nix/util/signature/signer.hh b/src/libutil/include/nix/util/signature/signer.hh index d03dbe975466..92765360a829 100644 --- a/src/libutil/include/nix/util/signature/signer.hh +++ b/src/libutil/include/nix/util/signature/signer.hh @@ -46,7 +46,7 @@ using Signers = std::map; */ struct LocalSigner : Signer { - LocalSigner(SecretKey && privateKey); + LocalSigner(std::unique_ptr && privateKey); Signature signDetached(std::string_view s) const override; @@ -54,8 +54,8 @@ struct LocalSigner : Signer private: - SecretKey privateKey; - PublicKey publicKey; + const std::unique_ptr privateKey; + const std::unique_ptr publicKey; }; } // namespace nix diff --git a/src/libutil/signature/local-keys.cc b/src/libutil/signature/local-keys.cc index 51f94cee006a..49c8407dda09 100644 --- a/src/libutil/signature/local-keys.cc +++ b/src/libutil/signature/local-keys.cc @@ -1,16 +1,31 @@ #include #include #include +#include +#include +#include #include "nix/util/base-n.hh" #include "nix/util/signature/local-keys.hh" #include "nix/util/json-utils.hh" #include "nix/util/util.hh" +#include "nix/util/deleter.hh" namespace nix { namespace { +using AutoEVP_PKEY = std::unique_ptr>; +using AutoEVP_PKEY_CTX = std::unique_ptr>; +using AutoEVP_MD_CTX = std::unique_ptr>; +using AutoBIO = std::unique_ptr>; + +std::string_view keyNamePart(std::string_view s) +{ + auto colon = s.find(':'); + return colon == std::string_view::npos ? std::string_view{} : s.substr(0, colon); +} + /** * Parse a colon-separated string where the second part is Base64-encoded. * @@ -45,6 +60,99 @@ std::string serializeColonBase64(std::string_view name, std::string_view data) return std::string(name) + ":" + base64::encode(std::as_bytes(std::span{data.data(), data.size()})); } +const char * toOpenSSLKeyType(KeyType type) +{ + switch (type) { + case KeyType::MLDSA44: + return "ML-DSA-44"; + case KeyType::MLDSA65: + return "ML-DSA-65"; + case KeyType::MLDSA87: + return "ML-DSA-87"; + case KeyType::ECDSAP384: + return "EC"; + case KeyType::Ed25519: + default: + throw Error("key type is not supported by OpenSSL"); + } +} + +/** + * Return the digest algorithm to use with `EVP_DigestSign` / `EVP_DigestVerify` + * for a given key type, or `nullptr` if the algorithm performs hashing + * internally (as ML-DSA does). + */ +const char * digestForKeyType(KeyType type) +{ + switch (type) { + case KeyType::MLDSA44: + case KeyType::MLDSA65: + case KeyType::MLDSA87: + return nullptr; + case KeyType::ECDSAP384: + return "SHA384"; + case KeyType::Ed25519: + default: + unreachable(); + } +} + +/** + * Determine the `KeyType` of a parsed OpenSSL key, or return `std::nullopt` if + * we don't support it. + */ +std::optional detectOpenSSLKeyType(EVP_PKEY * pkey) +{ + if (EVP_PKEY_is_a(pkey, "ML-DSA-44") == 1) + return KeyType::MLDSA44; + if (EVP_PKEY_is_a(pkey, "ML-DSA-65") == 1) + return KeyType::MLDSA65; + if (EVP_PKEY_is_a(pkey, "ML-DSA-87") == 1) + return KeyType::MLDSA87; + if (EVP_PKEY_is_a(pkey, "EC") == 1) { + char curve[64] = {0}; + size_t curveLen = 0; + if (EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, curve, sizeof(curve), &curveLen) == 1 + && std::string_view(curve, curveLen) == "secp384r1") + return KeyType::ECDSAP384; + } + return std::nullopt; +} + +/** + * Parse a DER-encoded PKCS#8 `PrivateKeyInfo`. + */ +AutoEVP_PKEY parsePrivateKey(std::string_view der) +{ + auto p = (const unsigned char *) der.data(); + AutoEVP_PKEY pkey(d2i_AutoPrivateKey(nullptr, &p, der.size())); + return pkey; +} + +/** + * Parse a DER-encoded `SubjectPublicKeyInfo`. + */ +AutoEVP_PKEY parsePublicKey(std::string_view der) +{ + auto p = (const unsigned char *) der.data(); + AutoEVP_PKEY pkey(d2i_PUBKEY(nullptr, &p, der.size())); + return pkey; +} + +AutoEVP_PKEY parsePublicKey(std::string_view der, KeyType type) +{ + auto pkey = parsePublicKey(der); + + auto detected = pkey ? detectOpenSSLKeyType(pkey.get()) : std::nullopt; + if (!detected || *detected != type) + throw Error( + "public key is not '%s' (got '%s')", + toOpenSSLKeyType(type), + pkey ? EVP_PKEY_get0_type_name(pkey.get()) : ""); + + return pkey; +} + } // anonymous namespace Signature Signature::parse(std::string_view s) @@ -81,19 +189,32 @@ Strings Signature::toStrings(const std::set & sigs) return res; } -Key::Key(std::string_view s, bool sensitiveValue) +static std::unordered_map keyTypeMap{ + {"ed25519", KeyType::Ed25519}, + {"ml-dsa-44", KeyType::MLDSA44}, + {"ml-dsa-65", KeyType::MLDSA65}, + {"ml-dsa-87", KeyType::MLDSA87}, + {"ecdsa-p384", KeyType::ECDSAP384}, +}; + +const StringSet & getKeyTypes() { - try { - auto [parsedName, parsedKey] = parseColonBase64(s, "key"); - name = std::move(parsedName); - key = std::move(parsedKey); - } catch (Error & e) { - std::string extra; - if (!sensitiveValue) - extra = fmt(" with raw value '%s'", s); - e.addTrace({}, "while decoding key named '%s'%s", name, extra); - throw; - } + static StringSet validKeyTypes = [] { + StringSet s; + for (const auto & [k, _] : keyTypeMap) { + s.insert(std::string(k)); + } + return s; + }(); + return validKeyTypes; +} + +KeyType parseKeyType(std::string_view s) +{ + auto i = keyTypeMap.find(s); + if (i != keyTypeMap.end()) + return i->second; + throw UsageError("unknown key type '%s'; valid key types are %s", s, concatStringsSep(", ", getKeyTypes())); } std::string Key::to_string() const @@ -101,46 +222,318 @@ std::string Key::to_string() const return serializeColonBase64(name, key); } -SecretKey::SecretKey(std::string_view s) - : Key{s, true} +Signature SecretKey::signDetached(std::string_view s) const { - if (key.size() != crypto_sign_SECRETKEYBYTES) - throw Error("secret key is not valid"); + throw Error("signing is not implemented for this key type"); } -Signature SecretKey::signDetached(std::string_view data) const +std::unique_ptr SecretKey::toPublicKey() const { - unsigned char sig[crypto_sign_BYTES]; - unsigned long long sigLen; - crypto_sign_detached(sig, &sigLen, (unsigned char *) data.data(), data.size(), (unsigned char *) key.data()); - return Signature{ - .keyName = name, - .sig = std::string((char *) sig, sigLen), - }; + throw Error("conversion to public key is not implemented for this key type"); } -PublicKey SecretKey::toPublicKey() const +std::string SecretKey::toPEM() const +{ + throw Error("conversion to PEM is not implemented for this key type"); +} + +struct Ed25519PublicKey : PublicKey +{ + Ed25519PublicKey(std::string_view name, std::string && _key) + : PublicKey(name, std::move(_key)) + { + assert(key.size() == crypto_sign_PUBLICKEYBYTES); + } + + bool verifyDetachedAnon(std::string_view data, const Signature & sig) const override + { + if (sig.sig.size() != crypto_sign_BYTES) + return false; + + return crypto_sign_verify_detached( + (unsigned char *) sig.sig.data(), + (unsigned char *) data.data(), + data.size(), + (unsigned char *) key.data()) + == 0; + } +}; + +struct Ed25519SecretKey : SecretKey +{ + Ed25519SecretKey(std::string_view name, std::string && _key) + : SecretKey(name, std::move(_key)) + { + assert(key.size() == crypto_sign_SECRETKEYBYTES); + } + + static std::unique_ptr generate(std::string_view name) + { + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + unsigned char sk[crypto_sign_SECRETKEYBYTES]; + if (crypto_sign_keypair(pk, sk) != 0) + throw Error("key generation failed"); + + return std::make_unique(name, std::string((char *) sk, crypto_sign_SECRETKEYBYTES)); + } + + Signature signDetached(std::string_view data) const override + { + unsigned char sig[crypto_sign_BYTES]; + unsigned long long sigLen; + crypto_sign_detached(sig, &sigLen, (unsigned char *) data.data(), data.size(), (unsigned char *) key.data()); + return Signature{ + .keyName = name, + .sig = std::string((char *) sig, sigLen), + }; + } + + std::unique_ptr toPublicKey() const override + { + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + crypto_sign_ed25519_sk_to_pk(pk, (unsigned char *) key.data()); + return std::make_unique(name, std::string((char *) pk, crypto_sign_PUBLICKEYBYTES)); + } +}; + +struct OpenSSLPublicKey : PublicKey +{ + KeyType type; + AutoEVP_PKEY pkey; + + OpenSSLPublicKey(KeyType type, std::string_view name, std::string && key, AutoEVP_PKEY && pkey) + : PublicKey(name, std::move(key)) + , type(type) + , pkey(std::move(pkey)) + { + assert( + type == KeyType::MLDSA44 || type == KeyType::MLDSA65 || type == KeyType::MLDSA87 + || type == KeyType::ECDSAP384); + } + + bool verifyDetachedAnon(std::string_view data, const Signature & sig) const override + { + if (!experimentalFeatureSettings.isEnabled(Xp::CNSA)) + return false; + + AutoEVP_MD_CTX ctx(EVP_MD_CTX_new()); + if (!ctx) + throw Error("EVP_MD_CTX_new failed"); + + if (EVP_DigestVerifyInit_ex(ctx.get(), nullptr, digestForKeyType(type), nullptr, nullptr, pkey.get(), nullptr) + <= 0) + throw Error("EVP_DigestVerifyInit_ex failed"); + + return EVP_DigestVerify( + ctx.get(), + (const unsigned char *) sig.sig.data(), + sig.sig.size(), + (const unsigned char *) data.data(), + data.size()) + == 1; + } + + std::string toPEM() const override + { + AutoBIO bio(BIO_new(BIO_s_mem())); + if (!bio) + throw Error("BIO_new failed"); + + if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) + throw Error("PEM_write_bio_PUBKEY failed"); + + char * data = nullptr; + long len = BIO_get_mem_data(bio.get(), &data); + return std::string(data, len); + } +}; + +struct OpenSSLSecretKey : SecretKey { - unsigned char pk[crypto_sign_PUBLICKEYBYTES]; - crypto_sign_ed25519_sk_to_pk(pk, (unsigned char *) key.data()); - return PublicKey(name, std::string((char *) pk, crypto_sign_PUBLICKEYBYTES)); + KeyType type; + AutoEVP_PKEY pkey; + + OpenSSLSecretKey(KeyType type, std::string_view name, std::string && key, AutoEVP_PKEY && pkey) + : SecretKey(name, std::move(key)) + , type(type) + , pkey(std::move(pkey)) + { + assert( + type == KeyType::MLDSA44 || type == KeyType::MLDSA65 || type == KeyType::MLDSA87 + || type == KeyType::ECDSAP384); + } + + static std::unique_ptr generate(std::string_view name, KeyType type) + { + experimentalFeatureSettings.require(Xp::CNSA); + + auto typeS = toOpenSSLKeyType(type); + AutoEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new_from_name(nullptr, typeS, nullptr)); + if (!ctx) + throw Error("EVP_PKEY_CTX_new_from_name failed for '%s'", typeS); + + if (EVP_PKEY_keygen_init(ctx.get()) <= 0) + throw Error("EVP_PKEY_keygen_init failed"); + + if (type == KeyType::ECDSAP384) { + char curve[] = "secp384r1"; + OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, curve, 0), + OSSL_PARAM_construct_end(), + }; + if (EVP_PKEY_CTX_set_params(ctx.get(), params) <= 0) + throw Error("EVP_PKEY_CTX_set_params failed"); + } + + EVP_PKEY * rawPkey = nullptr; + if (EVP_PKEY_generate(ctx.get(), &rawPkey) <= 0) + throw Error("EVP_PKEY_generate failed"); + AutoEVP_PKEY pkey(rawPkey); + + unsigned char * derBuf = nullptr; + int derLen = i2d_PrivateKey(pkey.get(), &derBuf); + if (derLen < 0) + throw Error("i2d_PrivateKey failed"); + std::string der((const char *) derBuf, derLen); + OPENSSL_free(derBuf); + + return std::make_unique(type, name, std::move(der), std::move(pkey)); + } + + Signature signDetached(std::string_view data) const override + { + experimentalFeatureSettings.require(Xp::CNSA); + + AutoEVP_MD_CTX ctx(EVP_MD_CTX_new()); + if (!ctx) + throw Error("EVP_MD_CTX_new failed"); + + /* Generate a deterministic signature (i.e. only depending on the key and the data) since Ed25519 is also + deterministic. For ML-DSA we set OSSL_SIGNATURE_PARAM_DETERMINISTIC; for ECDSA we request RFC-6979 + deterministic nonces via OSSL_SIGNATURE_PARAM_NONCE_TYPE. Note from RFC-9882: "The signer SHOULD NOT + use the deterministic variant of ML-DSA on platforms where side-channel attacks or fault attacks are a + concern." */ + int deterministic = 1; + unsigned int nonceType = 1; + OSSL_PARAM mlDsaParams[] = { + OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_DETERMINISTIC, &deterministic), + OSSL_PARAM_construct_end(), + }; + OSSL_PARAM ecdsaParams[] = { + OSSL_PARAM_construct_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, &nonceType), + OSSL_PARAM_construct_end(), + }; + OSSL_PARAM * params = type == KeyType::ECDSAP384 ? ecdsaParams : mlDsaParams; + + if (EVP_DigestSignInit_ex(ctx.get(), nullptr, digestForKeyType(type), nullptr, nullptr, pkey.get(), params) + <= 0) + throw Error("EVP_DigestSignInit_ex failed"); + + size_t sigLen = 0; + if (EVP_DigestSign(ctx.get(), nullptr, &sigLen, (const unsigned char *) data.data(), data.size()) <= 0) + throw Error("EVP_DigestSign (get length) failed"); + + std::string sig(sigLen, '\0'); + if (EVP_DigestSign( + ctx.get(), (unsigned char *) sig.data(), &sigLen, (const unsigned char *) data.data(), data.size()) + <= 0) + throw Error("EVP_DigestSign failed"); + sig.resize(sigLen); + + return Signature{ + .keyName = name, + .sig = std::move(sig), + }; + } + + std::unique_ptr toPublicKey() const override + { + experimentalFeatureSettings.require(Xp::CNSA); + + unsigned char * derBuf = nullptr; + int derLen = i2d_PUBKEY(pkey.get(), &derBuf); + if (derLen < 0) + throw Error("i2d_PUBKEY failed"); + std::string der((const char *) derBuf, derLen); + OPENSSL_free(derBuf); + + auto pubKey = parsePublicKey(der, type); + + return std::make_unique(type, name, std::move(der), std::move(pubKey)); + } + + std::string toPEM() const override + { + AutoBIO bio(BIO_new(BIO_s_mem())); + if (!bio) + throw Error("BIO_new failed"); + + if (PEM_write_bio_PrivateKey(bio.get(), pkey.get(), nullptr, nullptr, 0, nullptr, nullptr) <= 0) + throw Error("PEM_write_bio_PrivateKey failed"); + + char * data = nullptr; + long len = BIO_get_mem_data(bio.get(), &data); + return std::string(data, len); + } +}; + +std::unique_ptr SecretKey::parse(std::string_view s) +{ + try { + auto [name, key] = parseColonBase64(s, "key"); + + if (key.size() == crypto_sign_SECRETKEYBYTES) + return std::make_unique(name, std::move(key)); + else if (auto pkey = parsePrivateKey(key); experimentalFeatureSettings.isEnabled(Xp::CNSA) && pkey) { + auto type = detectOpenSSLKeyType(pkey.get()); + if (!type) + throw Error("secret key has unsupported type '%s'", EVP_PKEY_get0_type_name(pkey.get())); + return std::make_unique(*type, name, std::move(key), std::move(pkey)); + } else + throw Error("secret key is not valid"); + + } catch (Error & e) { + e.addTrace({}, "while decoding key '%s'", keyNamePart(s)); + throw; + } } -SecretKey SecretKey::generate(std::string_view name) +std::unique_ptr SecretKey::generate(std::string_view name, KeyType type) { - unsigned char pk[crypto_sign_PUBLICKEYBYTES]; - unsigned char sk[crypto_sign_SECRETKEYBYTES]; - if (crypto_sign_keypair(pk, sk) != 0) - throw Error("key generation failed"); + switch (type) { - return SecretKey(name, std::string((char *) sk, crypto_sign_SECRETKEYBYTES)); + case KeyType::Ed25519: + return Ed25519SecretKey::generate(name); + + case KeyType::MLDSA44: + case KeyType::MLDSA65: + case KeyType::MLDSA87: + case KeyType::ECDSAP384: + return OpenSSLSecretKey::generate(name, type); + + default: + unreachable(); + } } -PublicKey::PublicKey(std::string_view s) - : Key{s, false} +std::unique_ptr PublicKey::parse(std::string_view s) { - if (key.size() != crypto_sign_PUBLICKEYBYTES) - throw Error("public key is not valid"); + try { + auto [name, key] = parseColonBase64(s, "key"); + + if (key.size() == crypto_sign_PUBLICKEYBYTES) + return std::make_unique(name, std::move(key)); + else if (auto pkey = parsePublicKey(key); experimentalFeatureSettings.isEnabled(Xp::CNSA) && pkey) { + auto type = detectOpenSSLKeyType(pkey.get()); + if (!type) + throw Error("public key has unsupported type '%s'", EVP_PKEY_get0_type_name(pkey.get())); + return std::make_unique(*type, name, std::move(key), std::move(pkey)); + } else + throw Error("public key is not valid"); + } catch (Error & e) { + e.addTrace({}, "while decoding key '%s'", keyNamePart(s)); + throw; + } } bool PublicKey::verifyDetached(std::string_view data, const Signature & sig) const @@ -153,15 +546,13 @@ bool PublicKey::verifyDetached(std::string_view data, const Signature & sig) con bool PublicKey::verifyDetachedAnon(std::string_view data, const Signature & sig) const { - if (sig.sig.size() != crypto_sign_BYTES) - throw Error("signature is not valid"); + // Unsupported key type, can't verify. + return false; +} - return crypto_sign_verify_detached( - (unsigned char *) sig.sig.data(), - (unsigned char *) data.data(), - data.size(), - (unsigned char *) key.data()) - == 0; +std::string PublicKey::toPEM() const +{ + throw Error("conversion to PEM is not implemented for this key type"); } bool verifyDetached(std::string_view data, const Signature & sig, const PublicKeys & publicKeys) @@ -170,7 +561,7 @@ bool verifyDetached(std::string_view data, const Signature & sig, const PublicKe if (key == publicKeys.end()) return false; - return key->second.verifyDetachedAnon(data, sig); + return key->second->verifyDetachedAnon(data, sig); } } // namespace nix diff --git a/src/libutil/signature/signer.cc b/src/libutil/signature/signer.cc index fff03fc30db1..493754c4e371 100644 --- a/src/libutil/signature/signer.cc +++ b/src/libutil/signature/signer.cc @@ -5,20 +5,20 @@ namespace nix { -LocalSigner::LocalSigner(SecretKey && privateKey) - : privateKey(privateKey) - , publicKey(privateKey.toPublicKey()) +LocalSigner::LocalSigner(std::unique_ptr && _privateKey) + : privateKey(std::move(_privateKey)) + , publicKey(privateKey->toPublicKey()) { } Signature LocalSigner::signDetached(std::string_view s) const { - return privateKey.signDetached(s); + return privateKey->signDetached(s); } const PublicKey & LocalSigner::getPublicKey() { - return publicKey; + return *publicKey; } } // namespace nix diff --git a/src/nix/key-convert-public-to-pem.md b/src/nix/key-convert-public-to-pem.md new file mode 100644 index 000000000000..010886341aba --- /dev/null +++ b/src/nix/key-convert-public-to-pem.md @@ -0,0 +1,29 @@ +R""( + +# Examples + +* Convert a Nix public key to PEM: + + ```console + # nix key convert-secret-to-public < secret-key \ + | nix key convert-public-to-pem + -----BEGIN PUBLIC KEY----- + … + -----END PUBLIC KEY----- + ``` + +* Convert a public key to PEM and decode it using OpenSSL: + + ```console + # nix key convert-public-to-pem < public-key \ + | openssl pkey -pubin -text -noout + ML-DSA-87 Public-Key: + pub: + … + ``` + +# Description + +This command reads a Nix public verification key (as produced by `nix key convert-secret-to-public`) from standard input and writes the corresponding PEM `SubjectPublicKeyInfo` to standard output. The key name is not included in the PEM output. + +)"" diff --git a/src/nix/key-convert-secret-to-pem.md b/src/nix/key-convert-secret-to-pem.md new file mode 100644 index 000000000000..f1ec2ca32491 --- /dev/null +++ b/src/nix/key-convert-secret-to-pem.md @@ -0,0 +1,29 @@ +R""( + +# Examples + +* Convert an ML-DSA-65 secret key to PEM: + + ```console + # nix key generate-secret --key-name cache.example.org-1 --key-type ml-dsa-65 \ + | nix key convert-secret-to-pem + -----BEGIN PRIVATE KEY----- + … + -----END PRIVATE KEY----- + ``` + +* Convert a secret key to PEM and decode it using OpenSSL: + + ```console + # nix key convert-secret-to-pem < secret-key \ + | openssl pkey -text -noout + ML-DSA-87 Private-Key: + seed: + … + ``` + +# Description + +This command reads a Nix signing key generated by `nix key generate-secret` from standard input and writes the corresponding PEM PKCS#8 private key to standard output. The key name is not included in the PEM output. + +)"" diff --git a/src/nix/key-generate-secret.md b/src/nix/key-generate-secret.md index 609b1abccb90..1e9e33f8d67d 100644 --- a/src/nix/key-generate-secret.md +++ b/src/nix/key-generate-secret.md @@ -24,7 +24,7 @@ R""( # Description -This command generates a new Ed25519 secret key for signing store +This command generates a new secret key for signing store paths and prints it on standard output. Use `nix key convert-secret-to-public` to get the corresponding public key for verifying signed store paths. @@ -36,10 +36,16 @@ the host name of your cache (e.g. `cache.example.org`) with a suffix denoting the number of the key (to be incremented every time you need to revoke a key). +Nix supports keys in the following formats (specified using the `--key-type` option): + +* `ed25519` (libsodium). This is the default key type. It produces compact keys and signatures, but may not be resistant to attacks using quantum computers. +* `ml-dsa-44`, `ml-dsa-65`, `ml-dsa-87` (OpenSSL). These generate much larger keys and signatures, but are believed to be resistant to quantum attacks. +* `ecdsa-p384` (OpenSSL). ECDSA over the NIST P-384 curve using SHA-384. This is a CNSA-approved classical algorithm but is not believed to be resistant to quantum attacks. + # Format Both secret and public keys are represented as the key name followed -by a base-64 encoding of the Ed25519 key data, e.g. +by a base-64 encoding of the key data, e.g. ``` cache.example.org-0:E7lAO+MsPwTFfPXsdPtW8GKui/5ho4KQHVcAGnX+Tti1V4dUxoVoqLyWJ4YESuZJwQ67GVIksDt47og+tPVUZw== diff --git a/src/nix/nix-store/nix-store.cc b/src/nix/nix-store/nix-store.cc index d6649d3e96dd..1cc4d7aa9c07 100644 --- a/src/nix/nix-store/nix-store.cc +++ b/src/nix/nix-store/nix-store.cc @@ -1101,10 +1101,10 @@ static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs) std::string secretKeyFile = *i++; std::string publicKeyFile = *i++; - auto secretKey = SecretKey::generate(keyName); + auto secretKey = SecretKey::generate(keyName, KeyType::Ed25519); - writeFile(publicKeyFile, secretKey.toPublicKey().to_string(), 0666, FsSync::Yes); - writeFile(secretKeyFile, secretKey.to_string(), 0600, FsSync::Yes); + writeFile(publicKeyFile, secretKey->toPublicKey()->to_string(), 0666, FsSync::Yes); + writeFile(secretKeyFile, secretKey->to_string(), 0600, FsSync::Yes); } static void opVersion(Strings opFlags, Strings opArgs) diff --git a/src/nix/sigs.cc b/src/nix/sigs.cc index c72204cea3d4..600c7b42903e 100644 --- a/src/nix/sigs.cc +++ b/src/nix/sigs.cc @@ -121,8 +121,7 @@ struct CmdSign : StorePathsCommand void run(ref store, StorePaths && storePaths) override { - SecretKey secretKey(readFile(secretKeyFile)); - LocalSigner signer(std::move(secretKey)); + LocalSigner signer(SecretKey::parse(readFile(secretKeyFile))); size_t added{0}; @@ -149,6 +148,7 @@ static auto rCmdSign = registerCommand2({"store", "sign"}); struct CmdKeyGenerateSecret : Command { std::string keyName; + std::string keyType = "ed25519"; CmdKeyGenerateSecret() { @@ -159,6 +159,13 @@ struct CmdKeyGenerateSecret : Command .handler = {&keyName}, .required = true, }); + + addFlag({ + .longName = "key-type", + .description = fmt("Type of key: one of %s.", concatStringsSep(", ", getKeyTypes())), + .labels = {"type"}, + .handler = {&keyType}, + }); } std::string description() override @@ -176,7 +183,7 @@ struct CmdKeyGenerateSecret : Command void run() override { logger->stop(); - writeFull(getStandardOutput(), SecretKey::generate(keyName).to_string()); + writeFull(getStandardOutput(), SecretKey::generate(keyName, parseKeyType(keyType))->to_string()); } }; @@ -196,9 +203,50 @@ struct CmdKeyConvertSecretToPublic : Command void run() override { - SecretKey secretKey(drainFD(STDIN_FILENO)); logger->stop(); - writeFull(getStandardOutput(), secretKey.toPublicKey().to_string()); + writeFull(getStandardOutput(), SecretKey::parse(drainFD(STDIN_FILENO))->toPublicKey()->to_string()); + } +}; + +struct CmdKeyConvertSecretToPem : Command +{ + std::string description() override + { + return "convert a secret key read from standard input to PEM PKCS#8 format"; + } + + std::string doc() override + { + return +#include "key-convert-secret-to-pem.md" + ; + } + + void run() override + { + logger->stop(); + writeFull(getStandardOutput(), SecretKey::parse(drainFD(STDIN_FILENO))->toPEM()); + } +}; + +struct CmdKeyConvertPublicToPem : Command +{ + std::string description() override + { + return "convert a public key read from standard input to PEM SubjectPublicKeyInfo format"; + } + + std::string doc() override + { + return +#include "key-convert-public-to-pem.md" + ; + } + + void run() override + { + logger->stop(); + writeFull(getStandardOutput(), PublicKey::parse(drainFD(STDIN_FILENO))->toPEM()); } }; @@ -210,6 +258,8 @@ struct CmdKey : NixMultiCommand { {"generate-secret", []() { return make_ref(); }}, {"convert-secret-to-public", []() { return make_ref(); }}, + {"convert-secret-to-pem", []() { return make_ref(); }}, + {"convert-public-to-pem", []() { return make_ref(); }}, }) { } diff --git a/src/perl/lib/Nix/Store.xs b/src/perl/lib/Nix/Store.xs index 505faf0279cb..d7493ceeff70 100644 --- a/src/perl/lib/Nix/Store.xs +++ b/src/perl/lib/Nix/Store.xs @@ -301,7 +301,7 @@ SV * convertHash(char * algo, char * s, int toBase32) SV * signString(char * secretKey_, char * msg) PPCODE: try { - auto sig = SecretKey(secretKey_).signDetached(msg).to_string(); + auto sig = SecretKey::parse(secretKey_)->signDetached(msg).to_string(); XPUSHs(sv_2mortal(newSVpv(sig.c_str(), sig.size()))); } catch (Error & e) { croak("%s", e.what()); diff --git a/tests/functional/signing.sh b/tests/functional/signing.sh index bfa21fcff76b..642f13049ef9 100755 --- a/tests/functional/signing.sh +++ b/tests/functional/signing.sh @@ -1,15 +1,49 @@ #!/usr/bin/env bash +experimental_features="cnsa" + source common.sh +runTests() { + clearStoreIfPossible clearCache -nix-store --generate-binary-cache-key cache1.example.org "$TEST_ROOT"/sk1 "$TEST_ROOT"/pk1 +keyType="$1" + +nix key generate-secret --key-name cache1.example.org --key-type "$keyType" > "$TEST_ROOT"/sk1 +nix key convert-secret-to-public < "$TEST_ROOT"/sk1 > "$TEST_ROOT"/pk1 pk1=$(cat "$TEST_ROOT"/pk1) -nix-store --generate-binary-cache-key cache2.example.org "$TEST_ROOT"/sk2 "$TEST_ROOT"/pk2 +nix key generate-secret --key-name cache2.example.org --key-type "$keyType" > "$TEST_ROOT"/sk2 +nix key convert-secret-to-public < "$TEST_ROOT"/sk2 > "$TEST_ROOT"/pk2 pk2=$(cat "$TEST_ROOT"/pk2) +# Test PEM conversion. +if [[ "$keyType" == "ed25519" ]]; then + # Ed25519 keys cannot be converted to PEM. + expectStderr 1 nix key convert-secret-to-pem < "$TEST_ROOT"/sk1 | grepQuiet "conversion to PEM is not implemented for this key type" + expectStderr 1 nix key convert-public-to-pem < "$TEST_ROOT"/pk1 | grepQuiet "conversion to PEM is not implemented for this key type" +else + # ML-DSA-* and ECDSA-P-384 keys can be converted to PEM. + nix key convert-secret-to-pem < "$TEST_ROOT"/sk1 > "$TEST_ROOT"/sk1.pem + grepQuiet "^-----BEGIN PRIVATE KEY-----$" "$TEST_ROOT"/sk1.pem + grepQuiet "^-----END PRIVATE KEY-----$" "$TEST_ROOT"/sk1.pem + + nix key convert-public-to-pem < "$TEST_ROOT"/pk1 > "$TEST_ROOT"/pk1.pem + grepQuiet "^-----BEGIN PUBLIC KEY-----$" "$TEST_ROOT"/pk1.pem + grepQuiet "^-----END PUBLIC KEY-----$" "$TEST_ROOT"/pk1.pem + + # If openssl is available, verify that it can parse the PEM keys. + if type -p openssl > /dev/null; then + openssl pkey -text -noout < "$TEST_ROOT"/sk1.pem + openssl pkey -pubin -text -noout < "$TEST_ROOT"/pk1.pem + fi + + # Feeding a secret key to convert-public-to-pem (or vice versa) should fail. + expect 1 nix key convert-public-to-pem < "$TEST_ROOT"/sk1 + expect 1 nix key convert-secret-to-pem < "$TEST_ROOT"/pk1 +fi + # Build a path. outPath=$(nix-build dependencies.nix --no-out-link --secret-key-files "$TEST_ROOT/sk1 $TEST_ROOT/sk2") @@ -120,3 +154,11 @@ for file in "$TEST_ROOT/storemultisig/"*.narinfo; do exit 1 fi done + +} + +runTests ed25519 +runTests ml-dsa-44 +runTests ml-dsa-65 +runTests ml-dsa-87 +runTests ecdsa-p384