| 915 | } |
| 916 | |
| 917 | bool CLI::handleRecoverKeypair(const std::vector<std::string> &args) { |
| 918 | if (args.size() != 3) { |
| 919 | std::cerr << "Usage: recover-keypair <quantum_secret_hex> <vault_id_hex> " |
| 920 | "<public_seed_hex>" |
| 921 | << std::endl; |
| 922 | return false; |
| 923 | } |
| 924 | |
| 925 | try { |
| 926 | std::string quantum_secret_hex = args[0]; |
| 927 | if (quantum_secret_hex.front() == '"' && quantum_secret_hex.back() == '"') { |
| 928 | quantum_secret_hex = |
| 929 | quantum_secret_hex.substr(1, quantum_secret_hex.size() - 2); |
| 930 | } |
| 931 | std::array<uint8_t, 32> quantum_secret = fromHex32(quantum_secret_hex); |
| 932 | |
| 933 | std::string vault_id_hex = args[1]; |
| 934 | if (vault_id_hex.front() == '"' && vault_id_hex.back() == '"') { |
| 935 | vault_id_hex = vault_id_hex.substr(1, vault_id_hex.size() - 2); |
| 936 | } |
| 937 | std::array<uint8_t, 32> vault_id = fromHex32(vault_id_hex); |
| 938 | |
| 939 | std::string public_seed_hex = args[2]; |
| 940 | if (public_seed_hex.front() == '"' && public_seed_hex.back() == '"') { |
| 941 | public_seed_hex = public_seed_hex.substr(1, public_seed_hex.size() - 2); |
| 942 | } |
| 943 | std::array<uint8_t, 32> public_seed = fromHex32(public_seed_hex); |
| 944 | |
| 945 | QuipSigner signer(quantum_secret); |
| 946 | auto [pq_address, pq_private_key] = |
| 947 | signer.recoverKeyPair(vault_id, public_seed); |
| 948 | |
| 949 | std::cout << "Winternitz Public Seed: " << toHex(pq_address.publicSeed) |
| 950 | << std::endl; |
| 951 | std::cout << "Winternitz Public Key Hash: " |
| 952 | << toHex(pq_address.publicKeyHash) << std::endl; |
| 953 | // Flatten the private key vector to hex for output |
| 954 | std::vector<uint8_t> privkey_bytes; |
| 955 | for (const auto &seg : pq_private_key) { |
| 956 | privkey_bytes.insert(privkey_bytes.end(), seg.begin(), seg.end()); |
| 957 | } |
| 958 | std::cout << "Winternitz Private Key: " << toHex(privkey_bytes) |
| 959 | << std::endl; |
| 960 | |
| 961 | return true; |
| 962 | } catch (const std::exception &e) { |
| 963 | std::cerr << "Error: " << e.what() << std::endl; |
| 964 | return false; |
| 965 | } |
| 966 | } |
| 967 | |
| 968 | bool CLI::handleSign(const std::vector<std::string> &args) { |
| 969 | if (args.size() != 3) { |
nothing calls this directly
no test coverage detected