-
Notifications
You must be signed in to change notification settings - Fork 31
Description
I tried using libcrux-ml-dsa v0.0.3 to generate accumulated test vectors for ML-DSA. Since I wanted to generate a 60M iteration test vector, I cross-compiled the code to run on an Alpine Linux server with an Ampere Altra processor.
Surprisingly, the output of the binary on Linux was different from the one generated on my M2 laptop. Comparing with my implementation, it looks like the local macOS build is correct, while the Alpine Linux cross-compiled build is producing incorrect results.
I built a minimal reproducer and built it directly on the Alpine Linux machine with a rustup toolchain, no cargo.toml, and Alpine's gcc to rule out cross-compilation issues. It gave the same incorrect output.
Note that I am a complete Rust noob, and I had Claude write most of the code, but from eyeballing it I can't imagine how it should produce different results on different targets.
Environment
System 1 (macOS - CORRECT OUTPUT)
- OS: macOS 15.6.1 (24G90)
- Kernel: Darwin 24.6.0 ARM64
- CPU: Apple Silicon M2
- Rust: rustc 1.86.0 (05f9846f8 2025-03-31)
- Cargo: 1.86.0 (adf9b6ad1 2025-02-28)
System 2 (Alpine Linux - INCORRECT OUTPUT)
- OS: Alpine Linux edge (3.23.0_alpha20250612)
- Kernel: Linux 6.12.40-1-lts aarch64
- CPU: Ampere Altra Q64-22 (ARM64)
- Target: aarch64-unknown-linux-musl
- Rust: rustc 1.91.0 (f8297e351 2025-10-28)
- Cargo: 1.91.0 (ea2d97820 2025-10-10)
Minimal Reproducer
Cargo.toml
[package]
name = "libcrux-ml-dsa-repro"
version = "0.1.0"
edition = "2021"
[dependencies]
libcrux-ml-dsa = "0.0.3"
hex = "0.4"src/main.rs
use libcrux_ml_dsa::ml_dsa_44;
fn main() {
println!("libcrux-ml-dsa v0.0.3 - Platform Determinism Test\n");
// Test with a zero seed
let seed = [0u8; 32];
let kp = ml_dsa_44::generate_key_pair(seed);
// Sign an empty message with deterministic (zero) randomness
let empty_message = &[];
let context = &[];
let randomness = [0u8; 32];
let signature = ml_dsa_44::sign(&kp.signing_key, empty_message, context, randomness).unwrap();
println!("Seed: {}", hex::encode(seed));
println!("\nPublic key ({} bytes):", kp.verification_key.as_ref().len());
println!("{}", hex::encode(kp.verification_key.as_ref()));
println!("\nSignature ({} bytes):", signature.as_ref().len());
println!("{}", hex::encode(signature.as_ref()));
}Reproduction Steps
cargo run --releaseI get the same output with and without --release.
Actual Output
macOS Output (appears correct)
libcrux-ml-dsa v0.0.3 - Platform Determinism Test
Seed: 0000000000000000000000000000000000000000000000000000000000000000
Public key (1312 bytes):
ba71f9f64e11baeb58fa9c6fbb6e14e61f18643dab495b47539a9166ca0198131c44f826bbd56e34e55db5e5e2d733485e39ea260fc6000c5ea4ba80d3455cde53b46f34482aedfd5450fc2e1ba4f25d15f9c144242fb39bb52287189030c50498e1717b7c758b190a6748ea9aa3f7acaaf2c7cb526ed717c9f79aeb84214fa5cd8ded92a0c3fa1558810f12c7050a367708d196cd24e5af974904aed8e4ce8872e8696b0b7bca50e452cd7d30ea9a4adac0311d672c6bde8496240b07431463708895cd9bafc31632d7397649388fdafcbf7d305a3de9a495eca7433a8f83ba0f0b25c413c6e39c96eb7d691b34d37ce37f1eead1cf217e25ef34eecf3f7c60f84b8edfdde8405d4f832576c61ef98e0a2f28da187700953924f686b94614705bcf53d33fedd4348edddbdf28b5065e1f20775043e85cf931f829179363a1a7e7404a838ec00086b0976386fe637c98244757e3f769ddd4467471bfad670f9a05f8246ee50a7b1eaf87fc4069c3ae2aa2033258117792f0bcd49e083fd1bc7496abff29cc94e4868b21214ed316525399a610fbdd4a80e7c80715f29578e2a84bb40bdddbd9f47a11b6e7da118a1b658d359e8aef55eb46b5376b5b655979984a922beebfc59bcd600d5309dccd72dbf0787db8ba757b537c1eafd5c0f50ea4bc9583549e2829a42c28cac248c96d78124c47159b18aedd754aba17b19d430fb78f633ea9d26f54a9bd50f8d8f6b73594f828976e7ea09c53bbb9f11a56c9507fb89b9a5ebc037a37267a95f85b8d64ca97192b10a66f417b3f61fe9ca57130a48fd925eae2ab5502d571c8a51903c1d398f4c1f76a7e11743976afdbc697f23094a3cd761ff9685de32e09fb3c28add453490300bc7c89dc01780096071722945775f264e1b0623bcf4619c712c838761205d87691b75ef360196cbb9e9b92a0d4c4ed62326e5024d77510b8ee2c7426cc22eae209dc9f13bde6bf08f5e7181bd3b459450b451a51539a715c21d67dd330eb5970db00d9edbfb2822b036fa13bafeb86d8dc78866e3f8d43e53d78cca5595a6faf886b5dc112f1cf4adcfa875800d90b48883af97316fe1506873fc157e570eacbfd222868d14234101966afb6bf9940829253a953ada89fc756b6a849f70acb9838e69faa50bba75e3e89c2adb57e86d088ab9b04a28e670709172243ec5e0008a5ceaf3f8722f487302596ffd755ad1b82a49c34b3469515b46aa290cd86ee38ea7a9be3f103610335b531cca333ddfe32b14510f4b07ef95fc6684e8c454a92c10dbb5d59c7a7c63fb305fe881967d99e669eb632840582560bb403431d40f75a4954908482278292821f4ea91e42e78fa48caee3c836146dcfd738d117e92e9a15137d28e8e6a4b4622650cb413504cb3a335d44beec5746c1c294b1e8cb99cb608d928f8ce3563632c521f23d13c61a8f61c01df8c96c7360db4f3c68aa5d2fdd342a62ff3459c116389421ab43e8584c45882b50e6e4e96db6f0b8fde890d5dbfadcd88690b449e64240ddb2023747f308363e301aa77757169fc6150628d5920b5aa1ab1c8cbf44cb00e025d7879d72b479e3af5311c785725590da9c89b9fc3b8450769554eb44d203eba2bbaef9cad2237011c2ea44eff00f299a48ffe28ca93ddf85f76608242ef8d6cc24610a1e2078fcac4f9385c314905ecaa82e553916d94d1a7c1ec652aa08897083daa2ebb1775fbc471ae27777d7904ea9f1b92bcac3d8a3158426087b645b1108f0d65fec93789c053743ca14fd63d05e98b652df2b9c2ff9ce05f1940703ffb273f80e0e2732eca9960d981b4cfd3b7bb8045b3c3830546b9dd8db0d
Signature (2420 bytes):
3ad97aca43b38096316df981b81a35d279d381faa3abb87de968cf008259c6498c16dae4c86dcb0b2f19e0181c30a9553b73b01772c3d26608ecd825dfa6726f14c47e94ecb29b3b5d49f662eb7ae8ad2d7c780a41c327fba72b84feba71e55fc6691354966ae74e42689c6666243922f0aba733d77a568ea6aca77572cfd4053f9ea7094c05474a3fd8c5c7b17b000f4291982be22ebd05625f060b4fd7f1e417d73bad8adfc71de0309e9cb12e80ad0164768d1412b9c2a71397c83cd3a82af7aa28ee36a0edffa1711d099670e157b8cbbd9702092e3952a3b46f9e95966d8d7c98416c75a4d4a6d3f82b213464a2a105ae41c589f752a4c716a439bc7bfae4f883cc048567b4391adbacc08cab9993048e36e4d2a92f5f4106c5c6799a6507cbff78fa692f271be5c94232e3ad1c0ef16a7535a59b268c59e148133071445d0d01f3acc0b52fc0dd93a956844a1b85bbfbbdd516bb8587722eec7a9b03a3e8979b7c1aa9303cf5a3288d00fac1dc9a80947ebd6274f3786a0c4f1168a1d9aaeb5aa0290082c84dfb7982092b69374324dd042aba7fe14cc1cdc7ea5afa2952c73e5cc9ccb58354bd30cf5e8de1df8521b69429f68c627822cdf9a7f64c8274ad569f90ec5bfdc64cbcbeefd13f2479560b760f5cd2988298b9d39216aa948fbd5596003ad11c8ca41893317ee8f51e48d526b93489a57f7f8742a60f9bf84c6a8c90a28b005ddeef35439cf0fed10c5b3ee4a11131cd5fce8e580dcb71adcbe66478bab5a65d492a361bbe0b985dbe4b0f07bdd93417a8674ddd902da12ec8ef4eaf8495392a323f7f8a45839186e3c037f9d454ee94f77ec7bfbf559e1c34b4b74456eae23265bf35a0e240ea8ee12d88d1fe43053e9a243b49854aa5d03ae1ec42b7b2cd7fd3012fc3ddf05389c1596aa86e67561a0190dbfc8526b82e942c7cb9808a26d7243c017421fcc1301e84d3640b806836c776587e87e529cea9d6ee74000a780121a15fdb30efcec14e4c43a7a8d22b61666d3e8ac05704c89bd9642d1e9027a49436eea1d0a12cc0f404defff125aec1dde0ab7db69b1fc2f76d9b2dbac1b9104483177183eedb95ecee3b2b69f2682a878dd78298a2fa56e7e89ad7518a96b1200f35e636bd4fc2c3ae283adfe80ac9c9416c146ca58f4da7c3d188bdaf1da2c39644b373d65592c712e0322efa378015cba97f2c4238a935c6f9fab5009cb6753ce7596c8ec548745213c3aa91c106b29426194af21e407ae523e70450b6df882432c3f82add843b02e163f0525ff4782b56bb51143a5f54524200c10df686a2d48b71ba4f78d0391392310b3543a0c9e898297e4b13e87f898f49c7da4736471f1756d3e24e103fc1bfc3b9c399b28c9775840b07127fe8c35e1c4ede2a5790b9c4affe6d9bb95ae0c4368bafd6eddfb791fdfe1faa656f322ddb06918e75286425fb04a90f4cce900b5debb0936a2592102ba46f89636cad8d179c489e740a757111513d1c8da193e58acd9187a541f149cfa2d067977b230db007c42ce21996f67508f7625bfaf0f4b74b2e74d862dbd004609469ccf2ae2e16a1345d241493c75b22af4ab8155563c010e4768621045277b44590d70f51b14788c091b17df691e05b17926f3ba627101d98ac18d903d284f6a29c2da1b2e71d8a73e440c2196b1f09a7b64587a3770866b1ed9baccadcc22ba65fa80221a89516e8f4f54befbe29bf8815b6f5975617401cabea4db3842dd43bc629b011d423ca7b28892ad806217b7005dff454a6dbe218c6031b92b41d460c44e37ac29131d10f02e6e4212ba2d50e4f8a59dd6195ca796f464563babec24b255dc610391aa045e3063ee22fa984f0cbd4387ad4b171989ada4e1c1258f37feefb45e0659e86c38b19a7946dc683454e0b81ccaee4b4fcd0f8d6c6ca2f231196c6f9dbfba02b7ab80d61cece2d68f5ef49f8ad7e19df1ba4d4c495cb19a90a863e894bc68baad9f384621c1620de5038e270a096e28f725741152f28db852a84e530a06b075f68aa819e856622988b974fb92d56d6867625886a59c98cefa52d162d68a83410478f97477912a11723333e38e29967d1772b98088542cac91c28b8d6f732f937c03857212ffe9676004ae28d2bd4286d81cfefa00fc9bc315f5cf5d8f6e509e1b5b836b54787c33e6e06e91c13dd508e2f4919c3e18b6ee64e71120e2a199a9ffbfd571f5f49a05eeec45e3250a4cf1e8fc449097cbb7d55c309d5346c31221c3cf23d5eab124e30b5b04f3eb1eaa89ff824430313bedf45652d8b9cffee9f502f088a05922ecbfef297f1556f38faafe40f3ab9302b28f1d5218e34184e0fd35326bf3177e3035084f91e2b644b5b02db45069440f3b6a4aa27c3942341bde5f08ef450de375938fc538d796281ef28283ab5dd4eafc6474c7cbd5a2e8064b80bf3d188fc3acd1c173cf2113988169daaf1f3172dca7e7ebb971fe2cdf62ecfaf742e43c10f15737df46cfeab5832d24a76d5bdffdf0d77f3bca39dd6c6382085d7020679ff75ec439b7ee4fe9f972be8a37fd89eb11a69c1dd709280f1135a3dfd5d317df65efaddefd794a3dfa9a46c3c4643e626cf3481627fd6e886677f5715f6200fbf425b439ff01286aa4837384a2d51067ef115a215bcb11f8de19d0ac9f8b9172a5a8ed1664d1e0f2a55b7b00351b557cb888e5d99ec97fe708cda9bb31874af6ca0e4d530ca1c77f6b4ccdde3e94f928a7e6f15a5b5998a6e94227d20ca971840840ceccf3c4d17bb5f749b2d906056e03d5b52c32e9bc52f7188fb7783fa7390790d69c9c2b772c3e96a5850e7760a1ad90b4faadefd7abfcce276e6d03d0b62724379a1ae83da6d5bb63dd33f5ae5063a3ee998852b755fe883cfa2bbf8c8612a762e90a212f45700f383a3e252fa75baf4b5f19c9d02f064885b8855c2ed4237823bb266d4c699b1c514fc8d78aefb84a6f224b6659c1c693ad0e2d022d34489f18f0307cb572b32e6b2f021f55f33938075e8ee357110db875b621d54764d645d0b4da5f6f91f440eacef6bb6899c8461433df6d3ab4746c4c0e0bff183bb58d6adda436713596f054a65b6470ca3bb8b30fc506042f6a3048a5d9a17d8b9b21f90e0e4670d1bbbe199edeca23f66442441172f823ac3b243fb1d160bb58d68c94c4d591ae72ea9fd67ad003fc3e6228f0a6d1639e52f6a6e8386e8aa00c3c94a09ee9e59cbcc00a8ab8d4f2a04cd78653c58344879fb6bcdd7c9a4dfcd29a3673f63e74f3264ba54252bcfbbcf29d15875622f08102c2f34435b6263696d737d8586919da3b7bcc0d1092932618796c4dcdeebf6122029304f8695c1c6c8d2ecfc0a0e11244c5d7e88a0bfdfe2e5eff9fb00000000000000000000000000000000000016212e3e
Alpine Linux Output (incorrect)
libcrux-ml-dsa v0.0.3 - Platform Determinism Test
Seed: 0000000000000000000000000000000000000000000000000000000000000000
Public key (1312 bytes):
ba71f9f64e11baeb58fa9c6fbb6e14e61f18643dab495b47539a9166ca019813faaabac2d79a26f818330cf16db17ce3e693851b666bfc2a9dd5f5ecfd14d0888d801ffe29628ef9642fbcf56d3ea9f3b3139136a46349f9ef81ba1886e1c4c042682b64f5ccadd6db9b67bce3fa0d9309afcf7d6c50ba2066f25313d3a8a998f729a17120a2564b2f06a87f10452d6d34004eed727d28b45a4aa2260c23dcedbc5a417adb8b9a430952158c61e114ca2b6ac791e6b5c3e8429c08f26040be6ef007be1d1b8d402c25e452f32e7c127d868636a7b59257e1f0a9b0cf0c0dae2f0d444bd6004052228f332da7de861adaa00779e4dc5dcdd168fbd3f97cca4e9d81870da6701bbe8b9f4b6d063b74398e49dd48318facaa94e5435fe74ca67688f83266d3dd6349d22633072a0f6ec435fd4097da79b12f61385ef681d15887b195575bff49f788a3e91b3499c036d5240ebc84b0f82dccd1114e366f2c501e0fa65e2b7c96f5f03069f09c9ebae958ace0be77654ba0f2e31118e30b7e4768b50b71b94a0287577f143730d65950f7d2a8e71bfdbac9d19d7d76094cab1d015fb2ada1a3954a47381eb8dcdc8e4a40a9f27921d6147abecdc154c402738a9109bc629dc30ecc2d52624082b43f7451beaf9220b51c0ac404a0807cbd44344457fda3a62f665724b4124e936b647c4469c798ef5b81ff832f95cdf1653db17a3d709148303cd607af3ddd244dd000b7f58a7790e32421177c4006fdd454de280033a50682b4e9d296ad4fec4e45dc9d29a498c9795129c84d79c4bdd81d8908df022ef03cbb3efc370eb058b028e430982637f1ec46786b55153f464a492187d3ebf3d46c11338ce950808f7c20f7b7896235af0e2f7b3446214ccb04a998f184d48c8bd111099769ad107f85a5035b3a805732ffbb038ad9380d1585f3f7f622ddf388e74633fd253c0a2965117aaa9935be84ab736e0e0c4fffdcd8e40f23770fa781440893b5a4fc299fd8daa20e350f08476962b8deab152778788d5a2e7059e7233db9bfbf8fd658a19359e095e6679050f036d2e5cdd5417dfc347f6de2d5575c2a91d42aa209bd89f7915b9914cf911a62a7554c8c41b016a5dd2927dce6d2b58c2d1a8cd742593e88b879aa1e786b53ee05377f9ce1a3cec48c35a39b7f4f017b93b753be1a5102da6bbf8fa28390252e2102ab754b45e57fc69d0a7f2906d617e9056156c7562f2fd749b53e193c279dd503498e6a4a35407a3078525ca9274bfe07e5809a973405e2e39b7cb612753b8a802881f9c7996cc0c2b887eb09d12fb0ec5a2a13bd16c0959bce3fcfef157d65f7c4c9e780c0364426044bf2868f37d70b7d8484d383f768799ad58bd6236225c481ed624a15e68196763881fccb704bb4af2599d6cd4fb2ff2c7a8fd3880eb4548f303491cc10783e8e100c42b8b394d3f24bccf775b59a62387163a32a5aa47e9bee87bd6ac515903b9742d69406b9a8c755ef7f2decbb8f9c65bb674ad800cd308b6898f63d433256ea7343e55003d2845a1f10d613434f94ae4a6f1c7a457b5f7fafc98e7fc81128b1587bb9710ae1a1ce953271e559e86df11f588bfc944d6018bc5b97cfcd930daae96e36212d89352e0d0f0025d6acb308ca5827e0136535e9114f45611be00222a5c6800741d6c58a20e4e5bdcc79d79cc96e8dba192e20430f95c4052694071862b5b5ddd533033762dd0447b600d5b281914ff59883a051773b0efb9310d4e0b315f6fa231f530f770716ac942ac02c3614d0deb9458f3bd9538464b80143f91526838998a8d033f6f7189a41ca60862c2bc666e913c6eace5f4613393fc58c
Signature (2420 bytes):
b1323584f92ff3e0417194a93b1baaf662b16cab65e6cadc5cfb386140def2e76072fe181df8bf2e96d08129f974198c329d289dd236d48492938e593eccc74e221f3448d868f76b859aeb8e88cdb745e360ed411326fe8c72ec05d669abdc2bf685797aaa7c778aee5c27adcdefadf37f942d39b4939d8b9dab175581c23b5afe966e26b4edf9740059054c266ff448d9a187ce01df5d32cb373a6ca549807e210f06e3ec2317e3e53ed58752f9a8ddc67a70088ec3dc4a6f138caea0b5ce35f7aad0866fc8b051259913e5a706d093d6d085f0c0ef7fd8a5fe5012ada5e05913559b7cbf5b87b9d4d77dbad3a5fb153193fa5c47c3bd69e38bbc33203a7393acfa057b86e42a40cc625d7c985d5ce77032d8a5522de52f3f469ccaf119ccceba84ac7dc107d29e38b374b5f7132b688b2ee2f1cfd87bf5fa7359a7f84f86465c04aa5677bd5a20a0874d3b80a5295c7752249f11111c80041b62b9bf98efb0c971ff1c2640f82a7f555db682f370e5490a27cb4e133b8141ee5d94ceb7ed901009c941230086efff61b2bcc764b56564495b702d8dc626e5dd443549b04699965eff392a91318c75cd13fa37e6a58a72bdb5e5871b7262a59c330c25e379adea4204804b9821d477f646e33d10228c03a4569c365e5a6d8b6a8ece1530526aefa667d4302b9bdc7c609f1c3c3b1a2ed0026321cdbb146c831a84d326b5f270a80ba071f137fadb6f09e5ff6162be0fd549083d1ed327ddb2c30a1ab5d4f71a6fdfae57e3b1c022d525865da312bf6ce674135341771a58497209ec28ffda801c36c4c40db3a792ddfc444d05ff690b62c605af0e48f029c7327461755ef0426c6d7b86b90941e2ab42a76df8d9fd3513c945e117ccaa421f63ea3f82f7313a425f84456e8d3ba81501775cccf0f531296d767209c39834f8eecc848f2807c2af4e44543427d168c4d1e3155de3a76dc39b0f3a58dadc9ec5d6df4223c5aaf6e07d2d24c2c2389a2102717981e43442264b2ce0f0c860e0c25dd573112bbf93ab02adf1720add5a8175159d65de6c97063729f3e83311f1fe020d07dc87035369b7ec57bf2b412bdd4b4cac3b6b771016cedaf7928c0d3f8fc7f9037b7f9c055cd7590624d6f0d387a05f58fc2343d0a5c4d6375b45c78cd9654ba5b88dfca22f0f1ed273443b7688c37b7f01bc52de75374c57b25f8da861f70b199a70cf3d4266ed8cfdea5a6aa088857e916eee043b5d303665f40f0ce028b07c6f9cd22d19de6cc98c5ef7df4634f4af9e0c870fb67006084d751bc84ec3235de7c68741667754656e50cb8c684b3b8aca03f25881102f0aea6c051f58b46bacada308299346b1ec2af90afc518a529822961165f7fa3480bd6852284ebf1f94d9ac802bc932e45f658ef4fa28303ba7ac25286fa8317f77b724d269de61d801d1527132913c17ac0981405898c8d2b4e064255d9bfda3b06a25748f89c072f62b1a44cb73e20bc22aa1b05bb9ebf3e2456c4594c00991882ce5cf391046de090b43da8371eae24139019d74a818642c17637619045e32eadb101d9154de5e4dcad00e3c902f6146ee261b2287b938d4d50cc2e7907bad4caf904dfe5e9e58f319402520eaabb14c82cd6e52645f78922a972bce3d83934fb03970eae32247c96d87d7c8849118712f68c896aba65148e63d087a9b1c77f1beccb3d04d8981db8715530ff639d487a203cb570b82ba616cf2c0bcb8f029592ec879ee66540ed6d037beeec5dd61c96d9ed7ea6e5e1adbfcb03a5130abdf3fa36216b969dc97fba891b486490929a50df63a112e63fa52aed4851b3f022a8c1646686d7d970a5b7e5191573b5e99b363980ac35efd9c0fab20a928dc3c9a297375e23f23491fe2630f06653cc952b9abc5df03b8ccfc3c32cb76da849205bf9ebc622fa88c8eccdae27bed318c0058bc29c49039d92a9b57eda36ccbe6901e5fdc36256a88abcec9fc598f7acac36debd9b2a0531b6e07aff9482a54fac852c0b928b0332e5b76aaaf327cd5d04df2c3661295981def4006190afc64fa640c03a3adfe96f65b0dfc9963b276755a840fc6f76028b85f2bbfc3ac3952c03d9068f578873a509cac300dc0a7523b3d5f36688beee725aa1a77bee96f9dd5a6f11a37d9059dd5e8511c78e09d4ae904c863f6a0058a4a601136629568d6a6c2a1bce2901f19b6154e9b8e5e6fd3b9f2147d1e00addd8016933db4a215b66f7df00b81f7b838140938dab40586f07fc992224efd580a0a637f9008ce9b71bcb0fc4c640a1215c616dfb4abb2ce5e48435c0c79a3ae02989de2aed9f8a7e8eb003ae77a6a28edf3e307a27fce32c98956dce6124c7007507924910c703af86dadb04fb479b533e6900f9f55a4715634419ddcc67c96b73296c15c0140cf44885e30490f4f2e078b1f9cf2c7ab4373950a73175c072f7796ae8d2a56bca16653f13ad17096f821db4ad726b99c1ccfc55ae3007e4fe109244626dbdd8d210cba953c7f49a06f929b9d55ea88ab498afddaf5463414fdd1a31c4be703766a8cd3902c2042288548a1c3b59ead8e21ec3d6c1367fb44e3af1c84f7c56839ae776fbccea77ee6685f4afda23051c0c527245f05ac094f6290edd505d54068e5e4fa80d4d0c9f300100d5017db1b9f0661074ec6065041479662d89a1c01090f242f232da0c7a6185c5558d3da4ad98134b4399f96a946b5941bc8c2f02763802599082f96b7426340de0c133e89bde8e05f63d0b1a69562a7badef0db47d562853caf075265c8321acc0dba0b458eb86cea2fc860e1293c0898d4f195561da4b060e3518febc700567cfd43ab737743f9862c090cd564eac4df57b44717ab6f524b9576dae96bb37f1220f699fca34fbecfd0dbda3c7e1b2910a164b409f9844550e2bdff12ced203239a582854fe659fc6c7fcdd3d158fe5e6889f9c6f932fe93748da506bc557f7a138fda55c6e789a662d63f0fe61ce4d2866241ef7587a4717de33e7ec8ada5fc9e8c28238bc64ef67abd2360e0367e047e2a4f477ba032b728eb5a5b5439c2a68e5b22d271d20c4cc1f566855f0b015ac06a033fba6ae00d0969cff104e15c54d9191f05eeace5b710a6a66888085b8045b1610ab53394e7d33810db81c0bc57dda4924427053e868df7ff0323e839a7fc422adc48f174fb85eb97ac5f76226d400f418159baaec30766b1d5d90b69decb9577a939af9aec1edbd59e84798f7a377641bfe708c551474cd69a3a7c5d08d96640d7e415d90f8b34782a4a00b5942453554c22f9910222a5b628aa0a3c9ddf934394863656e77b3c1cbcccee7ea091a2e3235444a4d526f767b87a2a7cde3fd00061528314b5561676f72dde2effc000000000000000000000000000000000000000000000b192b3a