| 966 | } |
| 967 | |
| 968 | bool CLI::handleSign(const std::vector<std::string> &args) { |
| 969 | if (args.size() != 3) { |
| 970 | std::cerr |
| 971 | << "Usage: sign <quantum_secret> <vault_id> <public_seed> <message>" |
| 972 | << std::endl; |
| 973 | std::cerr << " quantum_secret: 32-byte hex string (0x...)" << std::endl; |
| 974 | std::cerr << " vault_id: 32-byte hex string (0x...)" << std::endl; |
| 975 | std::cerr << " public_seed: 32-byte hex string (0x...)" << std::endl; |
| 976 | std::cerr << " message: 32-byte hex string (0x...)" << std::endl; |
| 977 | return false; |
| 978 | } |
| 979 | try { |
| 980 | std::vector<uint8_t> quantum_secret_vec = fromHex(args[0]); |
| 981 | std::vector<uint8_t> vault_id_vec = fromHex(args[1]); |
| 982 | std::vector<uint8_t> public_seed_vec = fromHex(args[2]); |
| 983 | std::vector<uint8_t> message_vec = fromHex(args[3]); |
| 984 | if (quantum_secret_vec.size() != 32 || vault_id_vec.size() != 32 || |
| 985 | public_seed_vec.size() != 32 || message_vec.size() != 32) { |
| 986 | throw std::runtime_error("All arguments must be 32 bytes"); |
| 987 | } |
| 988 | std::array<uint8_t, 32> quantum_secret; |
| 989 | std::copy(quantum_secret_vec.begin(), quantum_secret_vec.end(), |
| 990 | quantum_secret.begin()); |
| 991 | std::array<uint8_t, 32> vault_id; |
| 992 | std::copy(vault_id_vec.begin(), vault_id_vec.end(), vault_id.begin()); |
| 993 | std::array<uint8_t, 32> public_seed; |
| 994 | std::copy(public_seed_vec.begin(), public_seed_vec.end(), |
| 995 | public_seed.begin()); |
| 996 | std::array<uint8_t, 32> message; |
| 997 | std::copy(message_vec.begin(), message_vec.end(), message.begin()); |
| 998 | QuipSigner signer(quantum_secret); |
| 999 | auto [pqAddress, private_key] = |
| 1000 | signer.recoverKeyPair(vault_id, public_seed); |
| 1001 | auto signature = signer.sign(message, private_key, public_seed); |
| 1002 | // Print as a single hex string |
| 1003 | std::vector<uint8_t> sig_bytes; |
| 1004 | for (const auto &seg : signature) { |
| 1005 | sig_bytes.insert(sig_bytes.end(), seg.begin(), seg.end()); |
| 1006 | } |
| 1007 | std::cout << "Signature: " << toHex(sig_bytes) << std::endl; |
| 1008 | return true; |
| 1009 | } catch (const std::exception &e) { |
| 1010 | std::cerr << "Error: " << e.what() << std::endl; |
| 1011 | return false; |
| 1012 | } |
| 1013 | } |
| 1014 | |
| 1015 | void CLI::printUsage() const { |
| 1016 | std::cout << "Usage: quip-cli <command> [options]" << std::endl; |
nothing calls this directly
no test coverage detected