#include <iostream>
#include <assert.h>
#include <optional>
#include <vector>
#include <cstdint>
#include <string>
#include <tuple>
#include <string>
#include <cstdio>
#include <cstdarg>
#include <alloca.h>
#include "api.h"
std::string stringff(const char *format, ...)
{
va_list arg_list;
va_start(arg_list, format);
// SUSv2 version doesn't work for buf NULL/size 0, so try printing
// into a small buffer that avoids the double-rendering and alloca path too...
char short_buf[256];
const size_t needed = vsnprintf(short_buf, sizeof short_buf,
format, arg_list) +
1;
if (needed <= sizeof short_buf)
return short_buf;
// need more space...
// OPTION 1
std::string result(needed, ' ');
vsnprintf(result.data(), needed, format, arg_list);
return result; // RVO ensures this is cheap
}
std::string string_hex(std::vector<std::uint8_t> const &input)
{
std::string s;
for (auto it = input.cbegin(); it != input.cend(); it++)
{
auto const byte = *it;
s += stringff("%x", byte >> 4);
s += stringff("%x", byte & 0xf);
}
return s;
}
void api_test(std::vector<std::uint8_t> const &input, std::optional<std::vector<std::uint8_t>> const &output, std::string const &name)
{
auto const result = run(input);
if (auto answer = std::get_if<0>(&result))
{
if (output)
{
if (output.value() == *answer)
{
std::cout << "Ok: " << name << std::endl;
}
else
{
std::cout << "Err: Returned value differs: " << name << std::endl;
std::cout << "Expected: " << string_hex(output.value()) << std::endl;
std::cout << "Got : " << string_hex(*answer) << std::endl;
}
}
else
{
std::cout << "Err: Run returned value: " << name << std::endl;
}
}
else
{
if (output)
{
std::cout << "Err: Run errored (" << std::get<1>(result) << "): " << name << std::endl;
}
else
{
std::cout << "Ok: " << name << std::endl;
}
}
}
std::uint8_t parse_hex_char(char c)
{
std::uint8_t byte = 0;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
byte = c - '0';
break;
}
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
{
byte = 10 + c - 'a';
break;
}
default:
std::cout << "Not a hex char: " << c << std::endl;
break;
}
return byte;
}
// Parses data in hexadecimal caracters
std::vector<std::uint8_t> parse_hex(std::string const &input)
{
std::vector<std::uint8_t> data;
for (auto it = input.cbegin(); it != input.cend();)
{
auto const high = parse_hex_char(*it);
it++;
auto const low = parse_hex_char(*it);
it++;
data.push_back((high << 4) | low);
}
return data;
}
void tests()
{
{
auto const input = parse_hex("0268259362ffe4eeeab4198826f2a6123c684cb9e1cb9776a641521a8e584ad990b3a95a828a22b542cf9c2e9e5fb1f800bc266b1bc34b4485c4cad7d5dcb588ead513c35d1110f39ed3e6f6701f1344c197b9e2d148ce4ffc5d00c209f75a4e68ff10a2c9d2cf7c567f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024603acd52f0a8a647b7d70f565298a1b3e4a5349641b7c7c35db0fb47fbe2e757138c5c08dd21d76b9954307b68e400bb3f912c3b60c0b7856ba09d6e396a39852de12492760f11bbd8b79002c5eea2c3757d43fb6bd5dbe7eb38c857a8fadad489188185712e77792c2fca45adb1a75c95f19c7556ede577fb6483c59af5b01f83d3abe6795f3ab19980e1aca89f70025ae6eaa1e276afcf5a852cf3106be6a0614c27f812f83c173d45c04de620711b07220f30996f3652eb0e61b07df94b8e9b0717f5858564efe837d6164f6ca77e0babbbe1f44c780e0caedea5839cc114034f7f20c5f937edca1b026d7c29542222de53f9c794dc976b983bbfdbe18868a2ea1a77705688748469e13331203dcaf10ce79816d7b017c26dbec741af0a354ebfba7f9a82ab4c41ddcf0ebfd751fb0ab731aa6ffd42e1f38f35fd682bd1bdf6a47678818bd8a823cbf323c31040d5a2ceca884850229534825f324");
auto const output = parse_hex("0fccd33a00d85ba0ee3ce8571406aa2e2a8da22d682b855c0bd647513723ecc1e8595e9146d382e9ea3b9e8287a9e5776fa3ac3ac7a97c0595cc1bda5d3ef1efe4a9152d9bf3998b435d8a8d698e1186f5c856a9c418b97404d6f33c080ef7925fde8f63f7e4ef241d2c5778c7ba25b4a368c53649da84f8d25d1cde12ecdaf28c9756571355f9ac88ea7c1ed3f1baf902c6bd7b3e9cbfde4d1f72d74dba5caf003a729f7d9de60b1bcfb8acd51ccd2b663b81d2273ef8301c952e065fc90aadb06a625b1947687fa6514a700882f4d1");
api_test(input, output, "G1 multiplication: 0");
}
{
auto const input = parse_hex("0703580458a3a3a3a3a3a3a3a33888a3a3a4a3a3a3a3a3a3a3a3a300a3a3a3a3a3a3a3a3a3a3a3a3a3a2a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3b3a3a3a3a3a335c8a3a3a37c46aa25e315000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b000000000000000000000000000000000000000000000000000000002948f3e91fc070298a9adfa89a9f4f95940d662c0716b81984b21fdcde3d457089784b1c2e32fb436bfac448a57931333438313334313838343933373033323931000000000000de0000000000000000000000000000009b00000000000000000000000000000000000000000000000000008000290ef2e91fc070298a9adfa89a9f4f95940d662c0716b81984b21fdcde3d457089784b1c2e32fb436bfac448a5790d61cd9308e4a87277fa9917e00e629bae26fc24c664702c38a739a0022957efcbed27201e03232362fcb320fed286f64f56ef708edfa58f420281a27463a37a0000000000000001020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000009767375890a7959bb77376a0f15a15aea37fcf1d5df1399e6a65172ca0e64869e2eba6f2c6f384cdcc74a29c79406b1aab0bc89b3655339b6084fff30ef5bc3db3a60cd6347218e09f2c59e73f4ff7dedd59eb8b6f0ce963e6a3e68685fd4cc9f7bfd4a22055c2e22e5c2aeb07fdbc3198c5a1b8a157470d10a21086b8b403d401ff7d9acd69ad359538953e9ad86bb33f7de55725c0f05b07c9f325260a36c45944234f1db5139692a3e07bdc77fac2c77be99a4d5c74a097fe7b8b3a8c21d4626dfb3b808e374c9eedbf35548788dd370d503051c113aa7cf8b49a97d1620c7d6a49ab9b806802cabc93c953c5c7b70fbd7546f1114b10267d97d417d0ad5ae48c3e28644a292a924e40fd26de3c59da896f923daa2c43c7589445f9f1a68d1b2b654b06612de56e726f397341fbac90f6ed680e7d648797aa38389162186467015a117ef3dcf323e35ee401924418a65f7573940191dea99d312f5ae8cf858054322a2657392e7ffd3f105487c4854bd98324abedabc216409448b80258036e9a2a69c32da0ce0ae39104d8eef30bc88505b8d484d9ce11f72189ac048a26b6c1fbef7e7a04a056ec26718b75e89cd11776118b19b734a532aa7e3746f06dad671f38db19ebe8ca8b0b974899ee177a40cf766d564418341f09eaca7f1432da0a32c60c8cf5271c805024a5b9e9fc6e3eb445fb7950202b2ea25ae81b3721f7ab270fe51baa0135b60f56f44359d68d2bc7529c25dbbf824199d71ecf63857ddbef380210ec043e70d37dd569e5fce53ad2cbe458b02ce5c7f60774b6e875788fdfff0742e239cf184b45ddb6272e8e7a3178edd2376476aaa8257160b2e7aff44cae872127c1df7b2d998cc2628dca2dd6e1d02fd18c3abde2251fe8ba8b700c094535694ec6fd598defa539ce514c1c7b02b30bf39832cf14cb466e3a0da3854fdfdd38054b3d3e1df3327b5a8b7f7021654e911f709089285057c63ddf301bc9811a41037da56c39207928669d9e1116d831dd513e541d0ee7da74f6a1a1819e3baeb46ee061f0e67b78a511ad6dfdfaad75b542e4d6685dd112ffd9e876546711e458bf82d05155f83f54fcb9a4a2897f67b949f8ae7e5256f990ca1369e31b4f3d7464e74b832eaf4e3bd9579c1e7b367630960f679752b533c794f1720cc4692b635c1686a32f5cad41e180a3d294fcc2c8124888e9e895c9c63dcb5230bdfd0badaba67bc3fe16ee7190dc2dac1e673ad399bdb3423a56e04c0aac7394fbdcc24f83ef1fefecb1f31f617764da05f45bdfd70811a9109a90f21339b157a002593b1a9101ac7ab890a2514813a5fda8d762750655f9002afcdbdf5d77c2a52522cf1b2efd001eb072f6035ea1db228190ec8ab7cd750e1b8ea6ee8372393bb0ddb26db7c862843b3aa4e97f06ea069c5bda0fccbc9e937ba4c66b5c68883edd9edcee1c9e410dafec204eb4ae0d2fafc29d894c6511e7948385577f7e54c7b55adf11fb0a485619913f9860777e837e003f64abb40f1a58e8aee097320e25250bed7af11bee74fc381eaa5419165de58b53d79ea58c0a126ec5cda28a82174ee42947cda433f8ff2d584ab85846307f8c2d3b1d475db2c4a9ecbda746f6c2460e28fd96e5cd18d84f268e17c02565558a44359773a0e03688fa03c9f658745b5ca90de910876eea0cbba6200b9e70036e28a16af2b5665ec64de2d886467901e5fbfbedc057dc9d0e506733bbda4f2026c520fd5515873ce1c218c4edb11b248714078f5cc06231856b561cfa35de6a4996eeaab4e81d039bfc7416576fd15ed4c472adf74909eff4fe713f5d9952dcdbc7d83215a8fdf1f11169e5d490e4b71ad7788b42591a05c2d2bd5c91901d58379caf4579e9c353a53fa207984f0462a28fed4d6b5dbc74e5676a23ff47599c8b868a5889238bc67869b42f38de673d1801710e7636f2a9913416ec5dfd5d1dde2e397f48f749857dbcb5a4bec015302dcd830d3e5c4cd64e2eb3bc53548cf060dcc0051e2543762072a463e415b50861bc43fe3e3229c8ee1dcdf8b2c633a54c1ba3c7d8333590dfb7432ae916a7d67b4e06595be0f0104964e232cc0839223611536ab457b0315ea9bd21fa1455a862da236d2330bf63c497c15353d9c5e189bd87bf67542d79d059e36cc5fd53c1ab54a9f5b6787e5aa7016bb14372cc94340b0f1fb1000fbd49a40cc356817c5c2a2b5c75e84996d0f60c06bc774c9dc5ca349559508a338132f62c8a966c2ace2192bc6f530e9624f9154f14e476faccc3213d611baa3d341753e726d5ed03f37b2381f3a3b330aa7757fd79ed69007e1111ba4a3df050b1b09d1212f157d146aea9704ec348c18429a7a567b86f26f4b77831cad0de10f721859851decd72940eb8ac6f81671bc06787f6e97e6dbfe69739b8f079a33ce3b72c0492ea192001ee58263ec123e55f20c46df19de67f181681579830b8b82050fab536a8f67a4ece3022be97c6c23963e0954aa7a36d9a9c76b1dc348ab4fbc3391f9a78bece729b9608873b40f23f0d16ced34c18e786c84e0d430cd067ec650799e3e28a4c8c60d2dadda52e1cf640a207c98f8a7e6ce093d9458a44c71db74c2b71c248d54e4f6202c352c3562f3e0a99a4301d78de3cfe6336dc02721f10c6e7f4d4cedfee69df22590ec881a9547ad28dda9b8c5770d747955ca30c022e364ccb65eb8a6675050ec30508272ee9aa6131dd9fafb5f87b5a2ce21e6a05e7cb1477831b707a8ef6aa699ac3d41f77fa66bb5d9d72cdf3a4881e231069988b7f108bb5603bf77a8f676f833fbcb38b502f0c262089015af58809a640123d2c07c9be7df3d0d4740f16b473bbff2bc9e3175dec56bdc4482fdc8e51667f2b2b81bdc509bede72bec0a4dd22ff300ffed03a2337cd163057284ed87020758a8d870669ecca91d1097d273c8e50755c270593a5438ff4e53b917f4315c5469834da5197329d588d633994786eeb1fe74625704727714299e6798c846f33765549a4c7ca1f0f92b42ad31ca60d383cb1f4e556416a7c84262c27e62e42a6405d5f0141121065000b4e8764f14038ea63ae4d536f9672c5ee6bf4e1d468400964665595df637458424d645833647800c9dcddf86474e5864723f0e99e8522ae9729e50a53ab614ee955c46377b6277dae62ae2c423c8b7c9f387453a2d8850cb158c868340559beffffd53f3a2c159a7dfecc6501cf79f7274be785c1674d3ce30713ce9c34ce7283766893d5f1ae48616fd1d9de5e19407b61a88d4a08339dff88466f70f7ef1eac70173361c5b3ccddf047112f5449e75a89c210e41b917175c8bcb746603b9e66c3699e297023b45caffe5a36248dbd4d984024a1196a21ebee08be0009b9bd72b10bb8596107bba10ec466b57c650e54516bc9b7aecdc7c1d338f05a4954ec7d6f016619a7fbd9f9bf1ff0708c337ddd1edde3d312ccd91eb7c110365db57a58f60a2059c91d672f366f222c3be44e120b7f62620e17aa205fb8dbf8298f93278a4d8f5a2fcad9f483e9e236540ba35da6e21c948aff1c32529f887d570e70f174ce4882e2bcf22272bc82de2bec24303f183f57596bb6dc6223eb74d421f0900a5bf4e1619e05b9382ebfe65d8a87078408ff2fb23e7bd1e4dbdaac1b925809290a25aa42ed60f30ce72aba1452626d025d1686f2b4a822c0567bac5ae8dce7aca3b7c2397132241a735b168ca9c2f501be889432a752da0fd01a6626eefa02e527b125686b5c7b5b3115183ef7d9712ea28e9c59f041cd59acdde3ca99e056f42b9e0a5815e98426c540618149f3c48d6ea6f0ebc944bfb5188e944f868b798ed6b361446706f9f12e555a8361137634d6c589754e27224157d09cd43c95d58b685e2ba4c6963060f4832b9ed51e77ba63931d1346d013107acf7e4fafd6c85c11805340e76526deec85835661432366f32ac7d870598dab3900660ae646f1ff7c465a64f9acf5045f4080c503c115662878fafcc32820d7e7be77b33657cc4fad251231439fdfab010a3ec1d5fe2b080c51f85b07bcd7095b5d8f5517e5254cd286fb8ed3fd34dc3fb0b2823d442d7df85d77ffed8ebd8be5138153ffc7d026827c3bc5696e5a61a6f63f7c042be7e402f7ef89d895c37282901ba80dd6a40bef27d601eb90bd87eeab46c066e04f6aa3cbeea2b4046ba08bebdf242f8de9227eb2a654a1b038ab8b970062d3f8ac9c9509148014a7f1d5e234687504a70a22aae9878b1d8d656eeb1d57cf083758732b1efe7613b1b2dfa3b4959f22574de5cf5fa399");
auto const output = parse_hex("264b5c0da7075851dd74b2a727d0ccf95f21d55f946453caf6b701dab9d1e7ce0d664cc12991cfc0765b66367b12aa3032087dd7329756d305fc5f6a0bc81645126356a11508b70a268ddfa6fd0736cad1722c646c43b430b915fb6d6df3b8c20197e879c06be063bab5fc52440a33c295ff6c8fc46c41726c2790fa0b294fbc");
api_test(input, output, "G2 multiplication: 0");
}
// {
// auto const input = parse_hex("0568259362ffe4eeeab4198826f2a6123c684cb9e1cb9776a641521a8e584ad990b3a95a828a22b542cf9c2e9e5fb1f800bc266b1bc34b4485c4cad7d5dcb588ead513c35d1110f39ed3e6f6701f1344c197b9e2d148ce4ffc5d00c209f75a4e68ff10a2c9d2cf7c567f02259362ffe4eeeab4198826f2a6123c684cb9e1cb9776a641521a8e584ad990b3a95a828a22b542cf9c2e9e5fb1f800bc266b1bc34b4485c4cad7d5dcb588ead513c35d1110f39ed3e6f6701f1344c197b9e2d148ce4ffc5d00c209f75a4e68ff10a2c9d2cf7c567e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004603acd52f0a8a647b7d70f565298a1b3e4a5349641b7c7c35db0fb47fbe2e757138c5c08dd21d76b9954307b68e400bb3f912c3b60c0b7856ba09d6e396a39852de12492760f1036f88a4149393b994f6d0c31c8a6d50198a1d60060aa4161b7b242f020e3d0d8a916ae1a565e7872c91e04408dcbdba757cffc81d41b0cbd4fe1406e01eecdd560e49d3fcd392fb75f280d1336d0be250578168df0190c448c3db4c65ba92a06fb81588a28f7b050f7e1c5d17bbc074408fa7880851b1cb6724bcaefaab8da3a5062a90c8c73bf946e309dab187b06b2a52042747efafea134b60889cab1fa6c368da83e313098c9ca2251bf55f1269b55dcffd2409a7c4e65f6149f20611ae0a5399cd2eee0f2ac93e9408d5b991dd1701124102f19bac5dde49eb976306060e1049c2eb5ab73d5e1bba8cca8c66b557773b308b45a843b5daf1a2b7a968fafe8ff96053e1bc3198c304b3f7d86ea7eae2592caec9d79ed97645c175226b8962d9d27e78943b0f29dfe7117231ddf2c05f6ed2a2cc49620aa5bf3a99e736dccf546a844ed447b066870d36a337430af91102f379a90b80c3cacbf850c809942d6a0410425e0c98766103a25d8ee911934e7d0ea50c94ec50f811e48e3a37934703bb714135dee961bd88aeca048659390c8a7dd497e31774a9978dc51b3607027aca1e946ef4dbd5f2a2df6a3a5fe9c1283d446900eef91a185ad09d63ba518ffb1f0ebf3ae3abbaf17dbb7c0d06b45bf700126c2a5a31ab268b33961354a6732f199a35b6");
// auto const output = parse_hex("04d464743c373711b8b34a74853a935594bdf40f2b8312d0e2aacad7ed0dfcdee58c8f06d4c3704946f7987fbe7f4fc4554ae790815fdbe5c97c6e1ae1886f5bfef331d973b1f258ceee5724a2ff0498ef4beee8f969b0cf7b65f1c9d6c86f07d42ea107e0758dce006ff974b07be4b048215d88ac1064e8d33e031eeb6e3b4afbe812b1d764d57025b92826275babf3700688e83680fbcf994e167a4e2840724f91028810680435a49041f5d10090eba0da199925932a2acb397395b2c9a77053979ae3c46da96660d6cd49482f76441ca5f0cce32be561fb2b354495fd0e5de3f460ca61435e828f0368213fb0bddec1b0552e5be8833e8b809521cc73f06476aede3d7853a82d8683d0f027d5765270e1fa3fb19cef4a0cff3d8aa37bd6107b8b82d2aa800d2fcbdea93585e15541b897b136791457280582ed337b826fe3cd42c391fa2dec9dd9a5684e34a342a9c0110f40e3545b8b20cd01b73865102880646a146f4380add11ed004c379369a7ffe36ebf5f48ec068fd99abd31ad8ef281b10249cda61dd694564e28ec2b51d91837f1d9e307fed0765a46fd87a0782");
// api_test(input, output, "G2 multiplication: 1");
// }
// {
// auto const input = parse_hex("0531026d331f7ce9cdc5e48d73aeedf0a1d7f7870b788046ec2aff712eda78d3fe42dfb8fe05c47ae860b05717583ae170045d02026d331f7ce9cdc5e48d73aeedf0a1d7f7870b788046ec2aff712eda78d3fe42dfb8fe05c47ae860b05717583ae170045b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002103c192577dfb697d258e5f48f4c3f36bb518d0ea9b498ca3559dfb03a2c685a5290101ffde193f98185f975ffb1372580fd7a93194e7a50a5cf7852f292455e0a34451c82bd7901a3de0c2a3479e716cbbdc00ac30a79956814c1a0e970fb255184f367d122abb6f3f9627ac2c2c97a68379d16883dfaf2549e3a3dce33f3bea1247df01460c7673ee5b7a2db0e9452d1b7fbb502e3f999f1b1dcd31e7062346408863c7f973b94e34c8b55c32bf5e829c664688005aa657b27ade7a8f4b1cabea24ce403f3ce23f7274e2569c90bcb97a4c04434c78438560cec76719bde389aedc17011301d82faa3935ba82cc72fca999eaa64a3e13f4b70e08eae12074e1841ea7e78c19");
// auto const output = parse_hex("004b6e56e5c05c0326653db28ee57c4155a8257dfe50695f14e5bb6c15113429f154aa5cd0a75a9b7db8b7d9c878a11515024e5f4800afc640288d68e5c9c2209795f8789465e0b0f49d1c047341cc61b52068eff7186db42de70eae178e6a08e75b0096d93f4253ae722fd5833f508110b4154a4ed440401174ddeaec89ac236a9b8bb325ac07253e64b18e8cce66ecac4c1f01c2721afe0cb38260be4cf450e317e4c60e191b3c98348aae52d7b906bb9eacbb99ea7064ccac70b63a6926794ff538ce");
// api_test(input, output, "G2 multiplication: 2");
// }
// {
// auto const input = parse_hex("052885fc1f752ac6f59f216571afe4d8db11c41bd3cc740f6270bb7cc3ac835a00e7d7ab6e9c5e72a30b0285fc1f752ac6f59f216571afe4d8db11c41bd3cc740f6270bb7cc3ac835a00e7d7ab6e9c5e72a30a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b36770e180fecfb20096cf26d0dff3151536877d570787a3b64bc414970e14721ec542f65f4e068855530505e32a40f57a2148c619e7e02f50e2e1debfff50870db8de684d6937638d8694890d9ceec508e14719211a22093040ac5e6300ffc8cb6ebf0c4eaafd21a6665a802bb174ef38349339ff9730404019a83c2d6d9776ec43f04e7c07285cf797111a6acbf22578e674d578e3b4204772e6f73a6e3ad6209cc7a020cd9351d85da0036c7af0fbf8154ba7be8aef2ee26632a2510336cd8552dba1855019ac0a6ab2ef0e6a5c5345884e3086826");
// auto const output = parse_hex("7ccf8ead202f00683db10087c511a2d6d43aa1fe8efa5de19e86368b13d77969e370abf3a4a8cd876410835eb0def110a0aabfc237af1fee6bbce8ea171e31ce154e1b0554471189638918c98eec3b645f52092aeea6aa97da5dc5e06a04c9daff33e3622a8de62d55c1bafa3ba165899fc1455fba91c34e3440f44dbacd555e2860e3cf07138bbf63ab5c9796de21913e36f2aac71e38d19e82978f43420dc4");
// api_test(input, output, "G2 multiplication: 3");
// }
}
int main()
{
// // Api
// std::vector<std::uint8_t> input = {0, 1, 2, 3, 4};
// auto result = run(input);
// if (auto err = std::get_if<1>(&result))
// {
// std::cout
// << "Err: " << *err << std::endl;
// }
// else
// {
// std::cout
// << "Ok" << std::endl;
// }
std::cout << "Starting tests" << std::endl;
tests();
std::cout << "Done testing" << std::endl;
}